extension-develop 4.0.7 → 4.0.8-canary.1783951222.f8433602

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/0~dev-server.mjs +4 -1
  2. package/dist/0~rspack-config.mjs +297 -76
  3. package/dist/101.mjs +16 -2
  4. package/dist/839.mjs +45 -6
  5. package/dist/845.mjs +18 -1
  6. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  7. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  8. package/dist/extension-js-devtools/chrome/pages/centralized-logger.js +4 -4
  9. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  10. package/dist/extension-js-devtools/chrome/pages/welcome.js +1 -1
  11. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  12. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  13. package/dist/extension-js-devtools/chromium/pages/centralized-logger.js +4 -4
  14. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  15. package/dist/extension-js-devtools/chromium/pages/welcome.js +1 -1
  16. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  17. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  18. package/dist/extension-js-devtools/edge/pages/centralized-logger.js +4 -4
  19. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  20. package/dist/extension-js-devtools/edge/pages/welcome.js +1 -1
  21. package/dist/extension-js-devtools/extension-js/chrome/events.ndjson +114 -6
  22. package/dist/extension-js-devtools/extension-js/chrome/ready.json +7 -7
  23. package/dist/extension-js-devtools/extension-js/chromium/events.ndjson +116 -6
  24. package/dist/extension-js-devtools/extension-js/chromium/ready.json +7 -7
  25. package/dist/extension-js-devtools/extension-js/edge/events.ndjson +114 -6
  26. package/dist/extension-js-devtools/extension-js/edge/ready.json +7 -7
  27. package/dist/extension-js-devtools/extension-js/firefox/events.ndjson +114 -6
  28. package/dist/extension-js-devtools/extension-js/firefox/ready.json +7 -7
  29. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  30. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  31. package/dist/extension-js-devtools/firefox/pages/centralized-logger.js +4 -4
  32. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  33. package/dist/extension-js-devtools/firefox/pages/welcome.js +1 -1
  34. package/dist/extension-js-theme/extension-js/chrome/events.ndjson +114 -6
  35. package/dist/extension-js-theme/extension-js/chrome/ready.json +7 -7
  36. package/dist/extension-js-theme/extension-js/chromium/events.ndjson +114 -6
  37. package/dist/extension-js-theme/extension-js/chromium/ready.json +7 -7
  38. package/dist/extension-js-theme/extension-js/edge/events.ndjson +114 -6
  39. package/dist/extension-js-theme/extension-js/edge/ready.json +7 -7
  40. package/dist/extension-js-theme/extension-js/firefox/events.ndjson +200 -8
  41. package/dist/extension-js-theme/extension-js/firefox/ready.json +7 -7
  42. package/dist/feature-scripts-classic-concat-loader.js +15 -2
  43. package/dist/feature-scripts-classic-concat-loader.mjs +15 -2
  44. package/dist/preprocessor-passthrough-loader.mjs +10 -0
  45. package/package.json +1 -1
@@ -491,6 +491,9 @@ class BridgeBroker {
491
491
  case 'result':
492
492
  if ('producer' === this.roles.get(conn)) this.onResult(frame);
493
493
  return;
494
+ case 'reload-ack':
495
+ if ('producer' === this.roles.get(conn) && this.pendingReload?.reloadType === frame.reloadType) this.pendingReload = void 0;
496
+ return;
494
497
  default:
495
498
  return;
496
499
  }
@@ -516,7 +519,7 @@ class BridgeBroker {
516
519
  conn.send(frame);
517
520
  notified++;
518
521
  } catch {}
519
- this.pendingReload = 0 === notified ? frame : void 0;
522
+ this.pendingReload = 0 === notified || "content-scripts" === frame.reloadType ? frame : void 0;
520
523
  return notified;
521
524
  }
522
525
  pingProducers() {
@@ -17,7 +17,7 @@ import { isResourceUnderDirs, canonicalizeDir, toResourceKey } from "./93.mjs";
17
17
  import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, EXTENSIONJS_CONTENT_SCRIPT_LAYER, isCanonicalContentScriptAsset, getCanonicalContentScriptJsAssetName, getCanonicalContentScriptCssAssetName } from "./291.mjs";
18
18
  import { stripBom, parseJsonSafe } from "./23.mjs";
19
19
  import { scrubBrand, makeSanitizedConsole } from "./0~branding.mjs";
20
- import { cssIntegrationsEnabled, cssConfigsDetected, missingSassDependency, isUsingIntegration, postCssPluginNotResolved } from "./845.mjs";
20
+ import { cssIntegrationsEnabled, cssConfigsDetected, deadCssUrlRef, missingSassDependency, isUsingIntegration, postCssPluginNotResolved } from "./845.mjs";
21
21
  import { isUsingTypeScript, jsFrameworksIntegrationsEnabled, ensureTypeScriptConfig, ensureOptionalContractModuleLoaded, resolveDevelopInstallRoot, getUserTypeScriptConfigFile, isUsingCustomLoader, isUsingIntegration as messages_isUsingIntegration, loadOptionalContractModuleWithoutInstall, resolveOptionalContractPackageWithoutInstall, jsFrameworksHmrSummary, jsFrameworksConfigsDetected, hasDependency, resolveDevelopDistFile, optional_deps_resolver_ensureOptionalContractPackageResolved } from "./839.mjs";
22
22
  import { PROJECT_MANIFEST_FILENAMES, findNearestProjectManifestSync, readProjectDependencies } from "./80.mjs";
23
23
  import { injectedFileDependencyMissing, getURLDependencyMissing, staticImportDependencyMissing, backgroundIsRequiredMessageOnly, fetchedFileDependencyMissing, importScriptsDependencyMissing } from "./266.mjs";
@@ -293,6 +293,89 @@ function checkManifestInPublic(compilation, publicDir) {
293
293
  }
294
294
  } catch {}
295
295
  }
296
+ function isFromFilepathList(filePath, filepathList) {
297
+ return Object.values(filepathList || {}).some((value)=>value === filePath);
298
+ }
299
+ function getFilename(feature, filePath) {
300
+ const entryExt = __rspack_external_path.extname(filePath);
301
+ let fileOutputpath = feature;
302
+ if ([
303
+ '.js',
304
+ '.jsx',
305
+ '.tsx',
306
+ '.ts',
307
+ '.vue',
308
+ '.svelte'
309
+ ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.js');
310
+ if ([
311
+ '.html',
312
+ '.njk',
313
+ '.nunjucks'
314
+ ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.html');
315
+ if ([
316
+ '.css',
317
+ '.scss',
318
+ '.sass',
319
+ '.less'
320
+ ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.css');
321
+ return unixify(fileOutputpath || '');
322
+ }
323
+ function unixify(filePath) {
324
+ return filePath.replace(/\\/g, '/');
325
+ }
326
+ function resolveRootAbsoluteRef(ref, projectRoot, publicRoot) {
327
+ if (!ref || !ref.startsWith('/')) return;
328
+ if (projectRoot && ref.startsWith(projectRoot)) return;
329
+ if (ref.startsWith('//')) return;
330
+ const trimmed = ref.replace(/^\/+/, '');
331
+ if (!trimmed) return;
332
+ if (publicRoot && __rspack_external_fs.existsSync(__rspack_external_path.join(publicRoot, trimmed))) return;
333
+ const candidate = __rspack_external_path.resolve(projectRoot, trimmed);
334
+ const rel = __rspack_external_path.relative(projectRoot, candidate);
335
+ if (rel.startsWith('..') || __rspack_external_path.isAbsolute(rel)) return;
336
+ if (!__rspack_external_fs.existsSync(candidate) || !__rspack_external_fs.statSync(candidate).isFile()) return;
337
+ return candidate;
338
+ }
339
+ function collectRootAbsoluteRefs(source) {
340
+ const refs = new Set();
341
+ const attrRe = /(?:src|href)\s*=\s*["'](\/[^"'#?]*)["']/gi;
342
+ const urlRe = /url\(\s*["']?(\/[^"')#?]+)["']?\s*\)/gi;
343
+ let m;
344
+ while(m = attrRe.exec(source))refs.add(m[1]);
345
+ while(m = urlRe.exec(source))refs.add(m[1]);
346
+ return refs;
347
+ }
348
+ function emitRootAbsoluteRefs(compilation, context, publicDir) {
349
+ const scanned = new Set();
350
+ for(let pass = 0; pass < 10; pass++){
351
+ const refs = new Set();
352
+ for (const asset of compilation.getAssets()){
353
+ if (!/\.(html|css)$/i.test(asset.name)) continue;
354
+ if (scanned.has(asset.name)) continue;
355
+ scanned.add(asset.name);
356
+ let source;
357
+ try {
358
+ source = String(asset.source.source());
359
+ } catch {
360
+ continue;
361
+ }
362
+ for (const ref of collectRootAbsoluteRefs(source))refs.add(ref);
363
+ }
364
+ if (0 === refs.size) return;
365
+ let emitted = 0;
366
+ for (const ref of refs){
367
+ const outputName = ref.replace(/^\/+/, '');
368
+ if (compilation.getAsset(outputName)) continue;
369
+ const sourcePath = resolveRootAbsoluteRef(ref, context, publicDir);
370
+ if (sourcePath) try {
371
+ compilation.emitAsset(outputName, new rspack.sources.RawSource(__rspack_external_fs.readFileSync(sourcePath)));
372
+ compilation.fileDependencies.add(sourcePath);
373
+ emitted++;
374
+ } catch {}
375
+ }
376
+ if (0 === emitted) return;
377
+ }
378
+ }
296
379
  class SpecialFoldersPlugin {
297
380
  static name = 'plugin-special-folders';
298
381
  options;
@@ -303,6 +386,14 @@ class SpecialFoldersPlugin {
303
386
  const { manifestPath } = this.options;
304
387
  const context = compiler.options.context || __rspack_external_path.dirname(manifestPath);
305
388
  const publicDir = __rspack_external_path.join(context, 'public');
389
+ compiler.hooks.thisCompilation.tap(SpecialFoldersPlugin.name, (compilation)=>{
390
+ compilation.hooks.processAssets.tap({
391
+ name: `${SpecialFoldersPlugin.name}:root-absolute-refs`,
392
+ stage: compilation.constructor.PROCESS_ASSETS_STAGE_SUMMARIZE
393
+ }, ()=>{
394
+ emitRootAbsoluteRefs(compilation, __rspack_external_path.dirname(manifestPath), publicDir);
395
+ });
396
+ });
306
397
  if (__rspack_external_fs.existsSync(publicDir) && __rspack_external_fs.statSync(publicDir).isDirectory()) {
307
398
  compiler.hooks.thisCompilation.tap(SpecialFoldersPlugin.name, (compilation)=>{
308
399
  compilation.hooks.processAssets.tap({
@@ -380,36 +471,6 @@ function envInjectedPublicVars(count) {
380
471
  function envNoMatchingFile(browser, mode, presentFiles, expectedCandidates) {
381
472
  return `Found ${presentFiles.map((file)=>pintor.yellow(file)).join(', ')} but none match browser ${pintor.yellow(browser)} (mode ${pintor.yellow(mode)}), so EXTENSION_PUBLIC_* variables read from code will be ${pintor.yellow('undefined')} in this build.\nMatching names, in priority order: ${expectedCandidates.map((file)=>pintor.gray(file)).join(', ')}.\nFamily names apply to every family member — e.g. ${pintor.yellow('.env.chrome')} also matches ${pintor.yellow('chromium')} and ${pintor.yellow('edge')} targets.`;
382
473
  }
383
- function isFromFilepathList(filePath, filepathList) {
384
- return Object.values(filepathList || {}).some((value)=>value === filePath);
385
- }
386
- function getFilename(feature, filePath) {
387
- const entryExt = __rspack_external_path.extname(filePath);
388
- let fileOutputpath = feature;
389
- if ([
390
- '.js',
391
- '.jsx',
392
- '.tsx',
393
- '.ts',
394
- '.vue',
395
- '.svelte'
396
- ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.js');
397
- if ([
398
- '.html',
399
- '.njk',
400
- '.nunjucks'
401
- ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.html');
402
- if ([
403
- '.css',
404
- '.scss',
405
- '.sass',
406
- '.less'
407
- ].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.css');
408
- return unixify(fileOutputpath || '');
409
- }
410
- function unixify(filePath) {
411
- return filePath.replace(/\\/g, '/');
412
- }
413
474
  function background_background(manifest) {
414
475
  return manifest.background && manifest.background.scripts && {
415
476
  background: {
@@ -2159,12 +2220,14 @@ async function buildCssRules(projectPath, mode, usage, opts) {
2159
2220
  test: /\.(sass|scss)$/,
2160
2221
  exclude: /\.module\.(sass|scss)$/,
2161
2222
  type: nonModuleType,
2162
- loader: null
2223
+ loader: null,
2224
+ missingTool: 'sass'
2163
2225
  },
2164
2226
  {
2165
2227
  test: /\.module\.(sass|scss)$/,
2166
2228
  type: 'css/module',
2167
- loader: null
2229
+ loader: null,
2230
+ missingTool: 'sass'
2168
2231
  }
2169
2232
  ],
2170
2233
  ...useLess ? [
@@ -2184,16 +2247,18 @@ async function buildCssRules(projectPath, mode, usage, opts) {
2184
2247
  test: /\.less$/,
2185
2248
  exclude: /\.module\.less$/,
2186
2249
  type: nonModuleType,
2187
- loader: null
2250
+ loader: null,
2251
+ missingTool: 'less'
2188
2252
  },
2189
2253
  {
2190
2254
  test: /\.module\.less$/,
2191
2255
  type: 'css/module',
2192
- loader: null
2256
+ loader: null,
2257
+ missingTool: 'less'
2193
2258
  }
2194
2259
  ]
2195
2260
  ];
2196
- return Promise.all(fileTypes.map(async ({ test, exclude, type, loader })=>{
2261
+ return Promise.all(fileTypes.map(async ({ test, exclude, type, loader, missingTool })=>{
2197
2262
  const use = loader ? await commonStyleLoaders(projectPath, {
2198
2263
  mode: mode,
2199
2264
  loader,
@@ -2203,6 +2268,9 @@ async function buildCssRules(projectPath, mode, usage, opts) {
2203
2268
  }) : await commonStyleLoaders(projectPath, {
2204
2269
  mode: mode
2205
2270
  });
2271
+ if (missingTool) use.push({
2272
+ loader: resolveDevelopDistFile('preprocessor-passthrough-loader')
2273
+ });
2206
2274
  return {
2207
2275
  test,
2208
2276
  exclude,
@@ -2302,7 +2370,53 @@ class CssPlugin {
2302
2370
  console.log(cssConfigsDetected(postcssConfig, tailwindConfig, browserslistSource));
2303
2371
  }
2304
2372
  }
2373
+ tolerateDeadUrlRefs(compiler) {
2374
+ const manifestDir = __rspack_external_path.dirname(this.manifestPath);
2375
+ const projectPath = compiler.options.context || process.cwd();
2376
+ const roots = [
2377
+ __rspack_external_path.join(projectPath, 'public'),
2378
+ manifestDir
2379
+ ];
2380
+ const assetExt = /\.(png|jpe?g|gif|webp|svg|avif|ico|bmp|cur|woff2?|ttf|otf|eot|mp3|mp4|webm|ogg|wav)$/i;
2381
+ let compilation = null;
2382
+ const warned = new Set();
2383
+ if (!compiler.hooks?.thisCompilation?.tap || !compiler.hooks?.normalModuleFactory?.tap) return;
2384
+ compiler.hooks.thisCompilation.tap(`${CssPlugin.name}:dead-url`, (c)=>{
2385
+ compilation = c;
2386
+ warned.clear();
2387
+ });
2388
+ compiler.hooks.normalModuleFactory.tap(`${CssPlugin.name}:dead-url`, (nmf)=>{
2389
+ nmf.hooks.beforeResolve.tap(`${CssPlugin.name}:dead-url`, (data)=>{
2390
+ const issuer = String(data?.contextInfo?.issuer || '').split('?')[0];
2391
+ if (!/\.(css|scss|sass|less)$/i.test(issuer)) return;
2392
+ const raw = String(data?.request || '');
2393
+ const req = raw.split('?')[0].split('#')[0];
2394
+ if (!req || req.startsWith('//') || /^[a-z][a-z0-9+.-]*:/i.test(req)) return;
2395
+ if (req.startsWith('~') || req.startsWith('@')) return;
2396
+ const isRootRef = req.startsWith('/');
2397
+ const isRelativeRef = req.startsWith('./') || req.startsWith('../');
2398
+ const isBareAssetRef = !isRootRef && !isRelativeRef && assetExt.test(req);
2399
+ if (!isRootRef && !isRelativeRef && !isBareAssetRef) return;
2400
+ const issuerDir = data?.context || __rspack_external_path.dirname(issuer);
2401
+ const candidates = isRootRef ? roots.map((root)=>__rspack_external_path.join(root, req.slice(1))) : [
2402
+ __rspack_external_path.resolve(issuerDir, req),
2403
+ ...isBareAssetRef ? roots.map((root)=>__rspack_external_path.join(root, req)) : []
2404
+ ];
2405
+ if (candidates.some((candidate)=>__rspack_external_fs.existsSync(candidate))) return;
2406
+ if ('true' === process.env.EXTENSION_STRICT_REFS) return;
2407
+ const key = `${issuer}|${req}`;
2408
+ if (!warned.has(key) && compilation?.warnings) {
2409
+ warned.add(key);
2410
+ const warning = new core_WebpackError(deadCssUrlRef(__rspack_external_path.relative(manifestDir, issuer) || issuer, raw));
2411
+ warning.file = __rspack_external_path.relative(manifestDir, issuer);
2412
+ compilation.warnings.push(warning);
2413
+ }
2414
+ return false;
2415
+ });
2416
+ });
2417
+ }
2305
2418
  async apply(compiler) {
2419
+ this.tolerateDeadUrlRefs(compiler);
2306
2420
  const mode = compiler.options.mode || 'development';
2307
2421
  if ('production' === mode) return void compiler.hooks.beforeRun.tapPromise(CssPlugin.name, ()=>this.configureOptions(compiler));
2308
2422
  const configuring = this.configureOptions(compiler);
@@ -2353,7 +2467,7 @@ class StaticAssetsPlugin {
2353
2467
  rules: []
2354
2468
  };
2355
2469
  compiler.options.module.rules = compiler.options.module.rules || [];
2356
- const filenamePattern = 'production' === this.mode ? 'assets/[name].[contenthash:8][ext]' : 'assets/[name][ext]';
2470
+ const filenamePattern = 'assets/[name].[contenthash:8][ext]';
2357
2471
  const defaultSvgRule = {
2358
2472
  test: /\.svg$/i,
2359
2473
  type: 'asset',
@@ -3872,8 +3986,7 @@ function emitDirectoryAsAssets(compilation, absDir, baseDir) {
3872
3986
  walk(absDir);
3873
3987
  }
3874
3988
  function emitFileAsAsset(compilation, absPath) {
3875
- const mode = compilation.options?.mode || 'development';
3876
- const filenamePattern = 'production' === mode ? 'assets/[name].[contenthash:8][ext]' : 'assets/[name][ext]';
3989
+ const filenamePattern = 'assets/[name].[contenthash:8][ext]';
3877
3990
  const ext = __rspack_external_path.extname(absPath);
3878
3991
  const name = __rspack_external_path.basename(absPath, ext);
3879
3992
  const content = __rspack_external_fs.readFileSync(absPath);
@@ -4306,15 +4419,32 @@ const DEV_CONNECT_SOURCES = [
4306
4419
  'http://127.0.0.1:*',
4307
4420
  'http://localhost:*'
4308
4421
  ];
4422
+ const LOOPBACK_HOSTS = new Set([
4423
+ '127.0.0.1',
4424
+ 'localhost',
4425
+ '[::1]',
4426
+ '::1'
4427
+ ]);
4428
+ function devConnectSources() {
4429
+ const sources = [
4430
+ ...DEV_CONNECT_SOURCES
4431
+ ];
4432
+ const raw = String(process.env.EXTENSION_DEV_SERVER_CONNECTABLE_HOST || '').trim();
4433
+ if (!raw || LOOPBACK_HOSTS.has(raw)) return sources;
4434
+ const host = raw.includes(':') && !raw.startsWith('[') ? `[${raw}]` : raw;
4435
+ sources.push(`ws://${host}:*`, `http://${host}:*`);
4436
+ return sources;
4437
+ }
4309
4438
  function loosenConnectSrcForDev(csp) {
4439
+ const devSources = devConnectSources();
4310
4440
  const connectSrc = csp.get('connect-src');
4311
4441
  const defaultSrc = csp.get('default-src');
4312
4442
  if (connectSrc) {
4313
- for (const source of DEV_CONNECT_SOURCES)if (!connectSrc.includes(source)) connectSrc.push(source);
4443
+ for (const source of devSources)if (!connectSrc.includes(source)) connectSrc.push(source);
4314
4444
  csp.set('connect-src', connectSrc);
4315
4445
  } else if (defaultSrc) csp.set('connect-src', [
4316
4446
  ...defaultSrc,
4317
- ...DEV_CONNECT_SOURCES
4447
+ ...devSources
4318
4448
  ]);
4319
4449
  }
4320
4450
  function patchV2CSP(manifest) {
@@ -4779,6 +4909,7 @@ function javaScriptError(errorSourcePath, missingFilePath, opts) {
4779
4909
  lines.push(`Missing script file in ${pintor.underline(errorSourcePath)}.`);
4780
4910
  lines.push(`Update your ${pintor.yellow("<script>")} src to point to a file that exists.`);
4781
4911
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4912
+ if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
4782
4913
  lines.push('');
4783
4914
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4784
4915
  return lines.join('\n');
@@ -4788,6 +4919,7 @@ function cssError(errorSourcePath, missingFilePath, opts) {
4788
4919
  lines.push(`Missing stylesheet in ${pintor.underline(errorSourcePath)}.`);
4789
4920
  lines.push(`Update your ${pintor.yellow('<link>')} href to point to a file that exists.`);
4790
4921
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4922
+ if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
4791
4923
  lines.push('');
4792
4924
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4793
4925
  return lines.join('\n');
@@ -4799,6 +4931,7 @@ function staticAssetError(errorSourcePath, missingFilePath, opts) {
4799
4931
  const ref = opts?.refLabel || '*' + extname;
4800
4932
  lines.push(`Update the ${pintor.yellow(ref)} reference to point to a file that exists.`);
4801
4933
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4934
+ if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
4802
4935
  lines.push('');
4803
4936
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4804
4937
  return lines.join('\n');
@@ -5127,6 +5260,7 @@ function warnMissingPublicRootResources(params) {
5127
5260
  const trimmed = publicRootUrl.replace(/^\//, '');
5128
5261
  const publicRootAbs = __rspack_external_path.join(publicRootForResource, trimmed);
5129
5262
  const outputRootAssetAbs = __rspack_external_path.join(outputRoot, trimmed);
5263
+ if (resolveRootAbsoluteRef(publicRootUrl, projectRoot, publicRootForResource)) return;
5130
5264
  if (!__rspack_external_fs.existsSync(publicRootAbs) && !__rspack_external_fs.existsSync(outputRootAssetAbs)) {
5131
5265
  const displayPath = __rspack_external_path.join(outputRoot, trimmed);
5132
5266
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
@@ -5140,12 +5274,15 @@ function warnMissingPublicRootResources(params) {
5140
5274
  }
5141
5275
  function checkMissingLocalEntries(params) {
5142
5276
  const { compilation, compiler, resource, manifestDir, projectRoot, js, css } = params;
5277
+ const strictRefs = 'true' === process.env.EXTENSION_STRICT_REFS;
5143
5278
  const check = (url)=>{
5144
5279
  if (!url || isHttpLike(url) || isSpecialScheme(url)) return;
5145
- if (url.startsWith('/') && !__rspack_external_path.isAbsolute(url)) return;
5280
+ if (url.startsWith('/') && !url.startsWith(projectRoot)) return;
5146
5281
  if (!__rspack_external_fs.existsSync(url)) {
5147
5282
  const displayFile = __rspack_external_path.relative(manifestDir, resource);
5148
- reportToCompilation(compilation, compiler, fileNotFound(displayFile, url), 'error', displayFile);
5283
+ reportToCompilation(compilation, compiler, fileNotFound(displayFile, url, {
5284
+ deadRefHint: !strictRefs
5285
+ }), strictRefs ? 'error' : 'warning', displayFile);
5149
5286
  }
5150
5287
  };
5151
5288
  js?.forEach(check);
@@ -5315,12 +5452,15 @@ function isClassicScript(filePath) {
5315
5452
  }
5316
5453
  }
5317
5454
  function classicConcatEntry(feature, jsFiles) {
5455
+ const deduped = [
5456
+ ...new Set(jsFiles)
5457
+ ];
5318
5458
  const queryData = encodeURIComponent(JSON.stringify({
5319
5459
  feature,
5320
- js: jsFiles,
5460
+ js: deduped,
5321
5461
  css: []
5322
5462
  }));
5323
- return `${jsFiles[0]}?__extensionjs_classic_concat__=${queryData}`;
5463
+ return `${deduped[0]}?__extensionjs_classic_concat__=${queryData}`;
5324
5464
  }
5325
5465
  const WILDCARD_HOSTS = new Set([
5326
5466
  '0.0.0.0',
@@ -5426,8 +5566,6 @@ class AddScriptsAndStylesToCompilation {
5426
5566
  const htmlEntries = this.includeList || {};
5427
5567
  const manifestDir = __rspack_external_path.dirname(this.manifestPath);
5428
5568
  const projectRoot = compiler.options.context || manifestDir;
5429
- const publicDir = __rspack_external_path.join(projectRoot, 'public');
5430
- const hasPublicDir = __rspack_external_fs.existsSync(publicDir);
5431
5569
  const devServerHmrImports = 'development' === compiler.options.mode ? getDevServerHmrImports(compiler) : [];
5432
5570
  for (const field of Object.entries(htmlEntries)){
5433
5571
  const [feature, resource] = field;
@@ -5435,9 +5573,10 @@ class AddScriptsAndStylesToCompilation {
5435
5573
  if (!__rspack_external_fs.existsSync(resource)) continue;
5436
5574
  const htmlAssets = getAssetsFromHtml(resource);
5437
5575
  const isRemoteUrl = (p)=>/^(https?:)?\/\//i.test(p);
5438
- const looksLikePublicRootUrl = (p)=>p.startsWith('/public/') || p.startsWith('/') && !p.startsWith(projectRoot) && hasPublicDir;
5439
- const jsAssets = (htmlAssets?.js || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset));
5440
- const cssAssets = (htmlAssets?.css || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset));
5576
+ const looksLikePublicRootUrl = (p)=>p.startsWith('/public/') || p.startsWith('/') && !p.startsWith(projectRoot);
5577
+ const isMissingLocalFile = (p)=>__rspack_external_path.isAbsolute(p) && !__rspack_external_fs.existsSync(p);
5578
+ const jsAssets = (htmlAssets?.js || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
5579
+ const cssAssets = (htmlAssets?.css || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
5441
5580
  const moduleJsAssets = new Set(htmlAssets?.moduleJs || []);
5442
5581
  const concatenateClassic = jsAssets.length > 1 && jsAssets.every((asset)=>!moduleJsAssets.has(asset) && /\.(js|cjs)$/i.test(asset) && isClassicScript(asset));
5443
5582
  const jsImports = concatenateClassic ? [
@@ -5935,7 +6074,8 @@ const isScriptsFolderFeature = (feature)=>feature.startsWith("scripts/");
5935
6074
  const isBackgroundScriptsFeature = (feature)=>"background/scripts" === feature;
5936
6075
  function createSequentialEntryModule(feature, scriptImports) {
5937
6076
  const jsFiles = scriptImports;
5938
- const concatenateClassic = jsFiles.length > 1 && jsFiles.every(isClassicScript);
6077
+ const concatEligible = (f)=>/\.(js|cjs|ts)$/i.test(f);
6078
+ const concatenateClassic = jsFiles.length > 1 && jsFiles.every((f)=>concatEligible(f) && isClassicScript(f));
5939
6079
  if (concatenateClassic) return classicConcatEntry(feature, jsFiles);
5940
6080
  const source = [
5941
6081
  `/* extension.js sequential entry: ${feature} */`,
@@ -7873,6 +8013,16 @@ const BRIDGE_PRODUCER_SOURCE = `;(function () {
7873
8013
  return;
7874
8014
  }
7875
8015
 
8016
+ // Delivery ack for the broker: proves this SW's message pump actually
8017
+ // processed the frame — a successful socket WRITE proves nothing when
8018
+ // the worker is wedged-but-connected (bug 27). The broker latches a
8019
+ // content-scripts reload until this ack and replays it to the next
8020
+ // producer hello, so an edit that landed on a dead pump still converges.
8021
+ // Sent on receipt (not after reinjection): the scripting-unavailable
8022
+ // fallback restarts the whole extension, and an unacked latch would
8023
+ // replay into the fresh SW and restart it a second time.
8024
+ send({type: "reload-ack", reloadType: kind, label: label});
8025
+
7876
8026
  announceReloadInTabs(announced);
7877
8027
  performDevReload(kind, function () {
7878
8028
  // Only the content-scripts path confirms from here (reinjection ran to
@@ -7984,31 +8134,56 @@ const BRIDGE_PRODUCER_SOURCE = `;(function () {
7984
8134
 
7985
8135
  // Multi-context console forwarding: other contexts (content scripts, surface
7986
8136
  // pages) can't reliably open ws://127.0.0.1 (page CSP / connect-src), so they
7987
- // relay console via chrome.runtime.sendMessage to this SW, which owns the WS.
7988
- // We enrich with the real tabId/url from the message sender.
8137
+ // relay console to this SW, which owns the WS. The relay travels a NAMED
8138
+ // runtime.Port never runtime.sendMessage because port traffic is
8139
+ // invisible to the extension's own onMessage listeners. With sendMessage, an
8140
+ // extension whose SW echoes every message back to its tabs (wild newtube:
8141
+ // onMessage → tabs.sendMessage(msg) to all tabs) turned each relayed log
8142
+ // into a new tab message, whose subject-side console.log became another
8143
+ // relayed envelope — a self-sustaining dev-only message storm (25k rows/10min
8144
+ // observed) that starved the extension system and wedged Chromium's DevTools
8145
+ // endpoint (family B). We enrich with the real tabId/url from the port sender.
8146
+ function shipRelayedLog(ev, sender) {
8147
+ try {
8148
+ send({
8149
+ type: "log",
8150
+ event: {
8151
+ v: 1,
8152
+ id: nowId(),
8153
+ timestamp: Date.now(),
8154
+ level: ev.level || "log",
8155
+ context: ev.context || "content",
8156
+ messageParts: Array.isArray(ev.messageParts) ? ev.messageParts : [],
8157
+ url: ev.url || (sender ? sender.url : undefined),
8158
+ tabId: sender && sender.tab ? sender.tab.id : undefined,
8159
+ frameId: sender ? sender.frameId : undefined,
8160
+ runId: INSTANCE_ID
8161
+ }
8162
+ });
8163
+ } catch (e) {}
8164
+ }
8165
+ try {
8166
+ var rtPort = g.chrome;
8167
+ if (rtPort && rtPort.runtime && rtPort.runtime.onConnect) {
8168
+ rtPort.runtime.onConnect.addListener(function (port) {
8169
+ if (!port || port.name !== "__extjs-bridge-log__") return;
8170
+ try {
8171
+ port.onMessage.addListener(function (msg) {
8172
+ if (!msg || !msg.__extjsBridgeLog) return;
8173
+ shipRelayedLog(msg.__extjsBridgeLog, port.sender);
8174
+ });
8175
+ } catch (e) {}
8176
+ });
8177
+ }
8178
+ } catch (e) {}
8179
+ // Legacy sendMessage path: kept for any surface still relaying the old way
8180
+ // (harmless one-predicate listener; new relays never use it).
7989
8181
  try {
7990
8182
  var rt = g.chrome;
7991
8183
  if (rt && rt.runtime && rt.runtime.onMessage) {
7992
8184
  rt.runtime.onMessage.addListener(function (msg, sender) {
7993
8185
  if (!msg || !msg.__extjsBridgeLog) return;
7994
- var ev = msg.__extjsBridgeLog;
7995
- try {
7996
- send({
7997
- type: "log",
7998
- event: {
7999
- v: 1,
8000
- id: nowId(),
8001
- timestamp: Date.now(),
8002
- level: ev.level || "log",
8003
- context: ev.context || "content",
8004
- messageParts: Array.isArray(ev.messageParts) ? ev.messageParts : [],
8005
- url: ev.url || (sender ? sender.url : undefined),
8006
- tabId: sender && sender.tab ? sender.tab.id : undefined,
8007
- frameId: sender ? sender.frameId : undefined,
8008
- runId: INSTANCE_ID
8009
- }
8010
- });
8011
- } catch (e) {}
8186
+ shipRelayedLog(msg.__extjsBridgeLog, sender);
8012
8187
  // No async response.
8013
8188
  });
8014
8189
  }
@@ -8071,7 +8246,8 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
8071
8246
 
8072
8247
  var CONTEXT = "__EXTJS_CONTEXT__";
8073
8248
  var chrome = g.chrome;
8074
- if (!chrome || !chrome.runtime || typeof chrome.runtime.sendMessage !== "function") return;
8249
+ if (!chrome || !chrome.runtime) return;
8250
+ var canRelay = typeof chrome.runtime.connect === "function";
8075
8251
 
8076
8252
  g.__extjsBridgeRelayInstalled = true;
8077
8253
  var consoleRef = g.console || {};
@@ -8093,14 +8269,39 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
8093
8269
 
8094
8270
  function here() { try { return g.location ? g.location.href : undefined; } catch (e) { return undefined; } }
8095
8271
 
8272
+ // Lazy named port to the SW producer. Connecting wakes an idle SW like
8273
+ // sendMessage does, but port frames never reach the extension's own
8274
+ // onMessage listeners (see the loop note above). Reconnect on demand: the
8275
+ // SW idling out (or reloading) disconnects the port; the next log redials.
8276
+ var logPort = null;
8277
+ function getLogPort() {
8278
+ if (!canRelay) return null;
8279
+ if (logPort) return logPort;
8280
+ try {
8281
+ logPort = chrome.runtime.connect({name: "__extjs-bridge-log__"});
8282
+ logPort.onDisconnect.addListener(function () {
8283
+ try { void chrome.runtime.lastError; } catch (e) {}
8284
+ logPort = null;
8285
+ });
8286
+ } catch (e) { logPort = null; }
8287
+ return logPort;
8288
+ }
8289
+
8096
8290
  LEVELS.forEach(function (level) {
8097
8291
  var orig = typeof consoleRef[level] === "function" ? consoleRef[level].bind(consoleRef) : function () {};
8098
8292
  consoleRef[level] = function () {
8099
8293
  try {
8100
- chrome.runtime.sendMessage(
8101
- {__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}},
8102
- function () { void chrome.runtime.lastError; } // swallow "no receiver" while the SW wakes
8103
- );
8294
+ var p = getLogPort();
8295
+ if (p) {
8296
+ try {
8297
+ p.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}});
8298
+ } catch (e) {
8299
+ // stale port (SW restarted): drop it and redial once
8300
+ logPort = null;
8301
+ var p2 = getLogPort();
8302
+ if (p2) { try { p2.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}}); } catch (e2) {} }
8303
+ }
8304
+ }
8104
8305
  } catch (e) {}
8105
8306
  return orig.apply(consoleRef, arguments);
8106
8307
  };
@@ -10524,6 +10725,26 @@ function webpackConfig(projectStructure, devOptions) {
10524
10725
  'node_modules',
10525
10726
  __rspack_external_path.join(process.cwd(), 'node_modules')
10526
10727
  ],
10728
+ roots: [
10729
+ __rspack_external_path.join(packageJsonDir, 'public'),
10730
+ __rspack_external_path.dirname(manifestPath)
10731
+ ],
10732
+ extensionAlias: {
10733
+ '.js': [
10734
+ '.ts',
10735
+ '.tsx',
10736
+ '.js',
10737
+ '.jsx'
10738
+ ],
10739
+ '.mjs': [
10740
+ '.mts',
10741
+ '.mjs'
10742
+ ],
10743
+ '.cjs': [
10744
+ '.cts',
10745
+ '.cjs'
10746
+ ]
10747
+ },
10527
10748
  extensions: [
10528
10749
  '.js',
10529
10750
  '.cjs',
package/dist/101.mjs CHANGED
@@ -117,6 +117,9 @@ function authorInstallNotice(target) {
117
117
  function projectInstallFallbackToNpm(pmName) {
118
118
  return `${getLoggingPrefix('warn')} Dependency install with ${pmName} failed. Retrying once with npm so the build can continue.`;
119
119
  }
120
+ function projectInstallScriptsDisabled(pmName) {
121
+ return `${getLoggingPrefix('info')} Installing project dependencies with ${pmName}. Lifecycle scripts are disabled for safety — set EXTENSION_ALLOW_INSTALL_SCRIPTS=true to run them.`;
122
+ }
120
123
  function buildWebpack(projectDir, stats, browser) {
121
124
  const statsJson = stats?.toJson({
122
125
  all: false,
@@ -413,6 +416,13 @@ function buildCommandFailed(error) {
413
416
  })();
414
417
  return `${getLoggingPrefix('error')} Build failed.\n${pintor.red(fmt.truncate(message, 1200))}`;
415
418
  }
419
+ function devCommandFailed(error) {
420
+ const message = (()=>{
421
+ if (error instanceof Error && error.message) return error.message;
422
+ return String(error || 'Unknown error');
423
+ })();
424
+ return `${getLoggingPrefix('error')} Dev mode failed.\n${pintor.red(fmt.truncate(message, 1200))}`;
425
+ }
416
426
  function managedDependencyConflict(duplicates, userPackageJsonPath) {
417
427
  const list = duplicates.map((d)=>`- ${pintor.yellow(d)}`).join('\n');
418
428
  return `${getLoggingPrefix('error')} Your project declares dependencies that are managed by ${pintor.blue('Extension.js')} and referenced in ${pintor.underline('extension.config.js')}\n${pintor.red('This can cause version conflicts and break the development/build process.')}\n\n${pintor.gray('Managed dependencies (remove these from your package.json):')}\n${list}\n\n${pintor.gray('PATH')} ${pintor.underline(userPackageJsonPath)}\nIf you need a different version, open an issue so we can consider bundling it safely.\nOperation aborted.`;
@@ -674,7 +684,7 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
674
684
  }
675
685
  return false;
676
686
  }
677
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.7","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.10","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
687
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.8-canary.1783951222.f8433602","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.10","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
678
688
  function asAbsolute(p) {
679
689
  return __rspack_external_path.isAbsolute(p) ? p : __rspack_external_path.resolve(p);
680
690
  }
@@ -1634,6 +1644,10 @@ function createPlaywrightMetadataWriter(options) {
1634
1644
  if (__rspack_external_fs.existsSync(readyPath)) {
1635
1645
  const prev = JSON.parse(__rspack_external_fs.readFileSync(readyPath, 'utf-8'));
1636
1646
  if ('number' == typeof prev.cdpPort) payload.cdpPort = prev.cdpPort;
1647
+ if ('string' == typeof prev.browserExitedAt) {
1648
+ payload.browserExitedAt = prev.browserExitedAt;
1649
+ payload.browserExitCode = prev.browserExitCode ?? null;
1650
+ }
1637
1651
  }
1638
1652
  } catch {}
1639
1653
  writeJsonAtomic(readyPath, payload);
@@ -2113,4 +2127,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2113
2127
  await browserLauncher(resolvedOpts);
2114
2128
  metadata.writeReady();
2115
2129
  }
2116
- export { PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, constants_isGeckoBasedBrowser, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
2130
+ export { PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, constants_isGeckoBasedBrowser, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };