extension-develop 4.0.7 → 4.0.8

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 (35) hide show
  1. package/dist/0~rspack-config.mjs +275 -71
  2. package/dist/101.mjs +9 -2
  3. package/dist/839.mjs +43 -5
  4. package/dist/845.mjs +10 -1
  5. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  6. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  7. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  8. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  9. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  10. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  11. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  12. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  13. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  14. package/dist/extension-js-devtools/extension-js/chrome/events.ndjson +6 -6
  15. package/dist/extension-js-devtools/extension-js/chrome/ready.json +5 -5
  16. package/dist/extension-js-devtools/extension-js/chromium/events.ndjson +6 -6
  17. package/dist/extension-js-devtools/extension-js/chromium/ready.json +5 -5
  18. package/dist/extension-js-devtools/extension-js/edge/events.ndjson +6 -6
  19. package/dist/extension-js-devtools/extension-js/edge/ready.json +5 -5
  20. package/dist/extension-js-devtools/extension-js/firefox/events.ndjson +6 -6
  21. package/dist/extension-js-devtools/extension-js/firefox/ready.json +5 -5
  22. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  23. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  24. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  25. package/dist/extension-js-theme/extension-js/chrome/events.ndjson +6 -6
  26. package/dist/extension-js-theme/extension-js/chrome/ready.json +5 -5
  27. package/dist/extension-js-theme/extension-js/chromium/events.ndjson +6 -6
  28. package/dist/extension-js-theme/extension-js/chromium/ready.json +5 -5
  29. package/dist/extension-js-theme/extension-js/edge/events.ndjson +6 -6
  30. package/dist/extension-js-theme/extension-js/edge/ready.json +5 -5
  31. package/dist/extension-js-theme/extension-js/firefox/events.ndjson +8 -8
  32. package/dist/extension-js-theme/extension-js/firefox/ready.json +5 -5
  33. package/dist/feature-scripts-classic-concat-loader.js +15 -2
  34. package/dist/feature-scripts-classic-concat-loader.mjs +15 -2
  35. package/package.json +1 -1
@@ -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: {
@@ -2302,7 +2363,53 @@ class CssPlugin {
2302
2363
  console.log(cssConfigsDetected(postcssConfig, tailwindConfig, browserslistSource));
2303
2364
  }
2304
2365
  }
2366
+ tolerateDeadUrlRefs(compiler) {
2367
+ const manifestDir = __rspack_external_path.dirname(this.manifestPath);
2368
+ const projectPath = compiler.options.context || process.cwd();
2369
+ const roots = [
2370
+ __rspack_external_path.join(projectPath, 'public'),
2371
+ manifestDir
2372
+ ];
2373
+ const assetExt = /\.(png|jpe?g|gif|webp|svg|avif|ico|bmp|cur|woff2?|ttf|otf|eot|mp3|mp4|webm|ogg|wav)$/i;
2374
+ let compilation = null;
2375
+ const warned = new Set();
2376
+ if (!compiler.hooks?.thisCompilation?.tap || !compiler.hooks?.normalModuleFactory?.tap) return;
2377
+ compiler.hooks.thisCompilation.tap(`${CssPlugin.name}:dead-url`, (c)=>{
2378
+ compilation = c;
2379
+ warned.clear();
2380
+ });
2381
+ compiler.hooks.normalModuleFactory.tap(`${CssPlugin.name}:dead-url`, (nmf)=>{
2382
+ nmf.hooks.beforeResolve.tap(`${CssPlugin.name}:dead-url`, (data)=>{
2383
+ const issuer = String(data?.contextInfo?.issuer || '').split('?')[0];
2384
+ if (!/\.(css|scss|sass|less)$/i.test(issuer)) return;
2385
+ const raw = String(data?.request || '');
2386
+ const req = raw.split('?')[0].split('#')[0];
2387
+ if (!req || req.startsWith('//') || /^[a-z][a-z0-9+.-]*:/i.test(req)) return;
2388
+ if (req.startsWith('~') || req.startsWith('@')) return;
2389
+ const isRootRef = req.startsWith('/');
2390
+ const isRelativeRef = req.startsWith('./') || req.startsWith('../');
2391
+ const isBareAssetRef = !isRootRef && !isRelativeRef && assetExt.test(req);
2392
+ if (!isRootRef && !isRelativeRef && !isBareAssetRef) return;
2393
+ const issuerDir = data?.context || __rspack_external_path.dirname(issuer);
2394
+ const candidates = isRootRef ? roots.map((root)=>__rspack_external_path.join(root, req.slice(1))) : [
2395
+ __rspack_external_path.resolve(issuerDir, req),
2396
+ ...isBareAssetRef ? roots.map((root)=>__rspack_external_path.join(root, req)) : []
2397
+ ];
2398
+ if (candidates.some((candidate)=>__rspack_external_fs.existsSync(candidate))) return;
2399
+ if ('true' === process.env.EXTENSION_STRICT_REFS) return;
2400
+ const key = `${issuer}|${req}`;
2401
+ if (!warned.has(key) && compilation?.warnings) {
2402
+ warned.add(key);
2403
+ const warning = new core_WebpackError(deadCssUrlRef(__rspack_external_path.relative(manifestDir, issuer) || issuer, raw));
2404
+ warning.file = __rspack_external_path.relative(manifestDir, issuer);
2405
+ compilation.warnings.push(warning);
2406
+ }
2407
+ return false;
2408
+ });
2409
+ });
2410
+ }
2305
2411
  async apply(compiler) {
2412
+ this.tolerateDeadUrlRefs(compiler);
2306
2413
  const mode = compiler.options.mode || 'development';
2307
2414
  if ('production' === mode) return void compiler.hooks.beforeRun.tapPromise(CssPlugin.name, ()=>this.configureOptions(compiler));
2308
2415
  const configuring = this.configureOptions(compiler);
@@ -2353,7 +2460,7 @@ class StaticAssetsPlugin {
2353
2460
  rules: []
2354
2461
  };
2355
2462
  compiler.options.module.rules = compiler.options.module.rules || [];
2356
- const filenamePattern = 'production' === this.mode ? 'assets/[name].[contenthash:8][ext]' : 'assets/[name][ext]';
2463
+ const filenamePattern = 'assets/[name].[contenthash:8][ext]';
2357
2464
  const defaultSvgRule = {
2358
2465
  test: /\.svg$/i,
2359
2466
  type: 'asset',
@@ -3872,8 +3979,7 @@ function emitDirectoryAsAssets(compilation, absDir, baseDir) {
3872
3979
  walk(absDir);
3873
3980
  }
3874
3981
  function emitFileAsAsset(compilation, absPath) {
3875
- const mode = compilation.options?.mode || 'development';
3876
- const filenamePattern = 'production' === mode ? 'assets/[name].[contenthash:8][ext]' : 'assets/[name][ext]';
3982
+ const filenamePattern = 'assets/[name].[contenthash:8][ext]';
3877
3983
  const ext = __rspack_external_path.extname(absPath);
3878
3984
  const name = __rspack_external_path.basename(absPath, ext);
3879
3985
  const content = __rspack_external_fs.readFileSync(absPath);
@@ -4306,15 +4412,32 @@ const DEV_CONNECT_SOURCES = [
4306
4412
  'http://127.0.0.1:*',
4307
4413
  'http://localhost:*'
4308
4414
  ];
4415
+ const LOOPBACK_HOSTS = new Set([
4416
+ '127.0.0.1',
4417
+ 'localhost',
4418
+ '[::1]',
4419
+ '::1'
4420
+ ]);
4421
+ function devConnectSources() {
4422
+ const sources = [
4423
+ ...DEV_CONNECT_SOURCES
4424
+ ];
4425
+ const raw = String(process.env.EXTENSION_DEV_SERVER_CONNECTABLE_HOST || '').trim();
4426
+ if (!raw || LOOPBACK_HOSTS.has(raw)) return sources;
4427
+ const host = raw.includes(':') && !raw.startsWith('[') ? `[${raw}]` : raw;
4428
+ sources.push(`ws://${host}:*`, `http://${host}:*`);
4429
+ return sources;
4430
+ }
4309
4431
  function loosenConnectSrcForDev(csp) {
4432
+ const devSources = devConnectSources();
4310
4433
  const connectSrc = csp.get('connect-src');
4311
4434
  const defaultSrc = csp.get('default-src');
4312
4435
  if (connectSrc) {
4313
- for (const source of DEV_CONNECT_SOURCES)if (!connectSrc.includes(source)) connectSrc.push(source);
4436
+ for (const source of devSources)if (!connectSrc.includes(source)) connectSrc.push(source);
4314
4437
  csp.set('connect-src', connectSrc);
4315
4438
  } else if (defaultSrc) csp.set('connect-src', [
4316
4439
  ...defaultSrc,
4317
- ...DEV_CONNECT_SOURCES
4440
+ ...devSources
4318
4441
  ]);
4319
4442
  }
4320
4443
  function patchV2CSP(manifest) {
@@ -4779,6 +4902,7 @@ function javaScriptError(errorSourcePath, missingFilePath, opts) {
4779
4902
  lines.push(`Missing script file in ${pintor.underline(errorSourcePath)}.`);
4780
4903
  lines.push(`Update your ${pintor.yellow("<script>")} src to point to a file that exists.`);
4781
4904
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4905
+ 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
4906
  lines.push('');
4783
4907
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4784
4908
  return lines.join('\n');
@@ -4788,6 +4912,7 @@ function cssError(errorSourcePath, missingFilePath, opts) {
4788
4912
  lines.push(`Missing stylesheet in ${pintor.underline(errorSourcePath)}.`);
4789
4913
  lines.push(`Update your ${pintor.yellow('<link>')} href to point to a file that exists.`);
4790
4914
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4915
+ 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
4916
  lines.push('');
4792
4917
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4793
4918
  return lines.join('\n');
@@ -4799,6 +4924,7 @@ function staticAssetError(errorSourcePath, missingFilePath, opts) {
4799
4924
  const ref = opts?.refLabel || '*' + extname;
4800
4925
  lines.push(`Update the ${pintor.yellow(ref)} reference to point to a file that exists.`);
4801
4926
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
4927
+ 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
4928
  lines.push('');
4803
4929
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
4804
4930
  return lines.join('\n');
@@ -5127,6 +5253,7 @@ function warnMissingPublicRootResources(params) {
5127
5253
  const trimmed = publicRootUrl.replace(/^\//, '');
5128
5254
  const publicRootAbs = __rspack_external_path.join(publicRootForResource, trimmed);
5129
5255
  const outputRootAssetAbs = __rspack_external_path.join(outputRoot, trimmed);
5256
+ if (resolveRootAbsoluteRef(publicRootUrl, projectRoot, publicRootForResource)) return;
5130
5257
  if (!__rspack_external_fs.existsSync(publicRootAbs) && !__rspack_external_fs.existsSync(outputRootAssetAbs)) {
5131
5258
  const displayPath = __rspack_external_path.join(outputRoot, trimmed);
5132
5259
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
@@ -5140,12 +5267,15 @@ function warnMissingPublicRootResources(params) {
5140
5267
  }
5141
5268
  function checkMissingLocalEntries(params) {
5142
5269
  const { compilation, compiler, resource, manifestDir, projectRoot, js, css } = params;
5270
+ const strictRefs = 'true' === process.env.EXTENSION_STRICT_REFS;
5143
5271
  const check = (url)=>{
5144
5272
  if (!url || isHttpLike(url) || isSpecialScheme(url)) return;
5145
- if (url.startsWith('/') && !__rspack_external_path.isAbsolute(url)) return;
5273
+ if (url.startsWith('/') && !url.startsWith(projectRoot)) return;
5146
5274
  if (!__rspack_external_fs.existsSync(url)) {
5147
5275
  const displayFile = __rspack_external_path.relative(manifestDir, resource);
5148
- reportToCompilation(compilation, compiler, fileNotFound(displayFile, url), 'error', displayFile);
5276
+ reportToCompilation(compilation, compiler, fileNotFound(displayFile, url, {
5277
+ deadRefHint: !strictRefs
5278
+ }), strictRefs ? 'error' : 'warning', displayFile);
5149
5279
  }
5150
5280
  };
5151
5281
  js?.forEach(check);
@@ -5315,12 +5445,15 @@ function isClassicScript(filePath) {
5315
5445
  }
5316
5446
  }
5317
5447
  function classicConcatEntry(feature, jsFiles) {
5448
+ const deduped = [
5449
+ ...new Set(jsFiles)
5450
+ ];
5318
5451
  const queryData = encodeURIComponent(JSON.stringify({
5319
5452
  feature,
5320
- js: jsFiles,
5453
+ js: deduped,
5321
5454
  css: []
5322
5455
  }));
5323
- return `${jsFiles[0]}?__extensionjs_classic_concat__=${queryData}`;
5456
+ return `${deduped[0]}?__extensionjs_classic_concat__=${queryData}`;
5324
5457
  }
5325
5458
  const WILDCARD_HOSTS = new Set([
5326
5459
  '0.0.0.0',
@@ -5426,8 +5559,6 @@ class AddScriptsAndStylesToCompilation {
5426
5559
  const htmlEntries = this.includeList || {};
5427
5560
  const manifestDir = __rspack_external_path.dirname(this.manifestPath);
5428
5561
  const projectRoot = compiler.options.context || manifestDir;
5429
- const publicDir = __rspack_external_path.join(projectRoot, 'public');
5430
- const hasPublicDir = __rspack_external_fs.existsSync(publicDir);
5431
5562
  const devServerHmrImports = 'development' === compiler.options.mode ? getDevServerHmrImports(compiler) : [];
5432
5563
  for (const field of Object.entries(htmlEntries)){
5433
5564
  const [feature, resource] = field;
@@ -5435,9 +5566,10 @@ class AddScriptsAndStylesToCompilation {
5435
5566
  if (!__rspack_external_fs.existsSync(resource)) continue;
5436
5567
  const htmlAssets = getAssetsFromHtml(resource);
5437
5568
  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));
5569
+ const looksLikePublicRootUrl = (p)=>p.startsWith('/public/') || p.startsWith('/') && !p.startsWith(projectRoot);
5570
+ const isMissingLocalFile = (p)=>__rspack_external_path.isAbsolute(p) && !__rspack_external_fs.existsSync(p);
5571
+ const jsAssets = (htmlAssets?.js || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
5572
+ const cssAssets = (htmlAssets?.css || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
5441
5573
  const moduleJsAssets = new Set(htmlAssets?.moduleJs || []);
5442
5574
  const concatenateClassic = jsAssets.length > 1 && jsAssets.every((asset)=>!moduleJsAssets.has(asset) && /\.(js|cjs)$/i.test(asset) && isClassicScript(asset));
5443
5575
  const jsImports = concatenateClassic ? [
@@ -5935,7 +6067,8 @@ const isScriptsFolderFeature = (feature)=>feature.startsWith("scripts/");
5935
6067
  const isBackgroundScriptsFeature = (feature)=>"background/scripts" === feature;
5936
6068
  function createSequentialEntryModule(feature, scriptImports) {
5937
6069
  const jsFiles = scriptImports;
5938
- const concatenateClassic = jsFiles.length > 1 && jsFiles.every(isClassicScript);
6070
+ const concatEligible = (f)=>/\.(js|cjs|ts)$/i.test(f);
6071
+ const concatenateClassic = jsFiles.length > 1 && jsFiles.every((f)=>concatEligible(f) && isClassicScript(f));
5939
6072
  if (concatenateClassic) return classicConcatEntry(feature, jsFiles);
5940
6073
  const source = [
5941
6074
  `/* extension.js sequential entry: ${feature} */`,
@@ -7984,31 +8117,56 @@ const BRIDGE_PRODUCER_SOURCE = `;(function () {
7984
8117
 
7985
8118
  // Multi-context console forwarding: other contexts (content scripts, surface
7986
8119
  // 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.
8120
+ // relay console to this SW, which owns the WS. The relay travels a NAMED
8121
+ // runtime.Port never runtime.sendMessage because port traffic is
8122
+ // invisible to the extension's own onMessage listeners. With sendMessage, an
8123
+ // extension whose SW echoes every message back to its tabs (wild newtube:
8124
+ // onMessage → tabs.sendMessage(msg) to all tabs) turned each relayed log
8125
+ // into a new tab message, whose subject-side console.log became another
8126
+ // relayed envelope — a self-sustaining dev-only message storm (25k rows/10min
8127
+ // observed) that starved the extension system and wedged Chromium's DevTools
8128
+ // endpoint (family B). We enrich with the real tabId/url from the port sender.
8129
+ function shipRelayedLog(ev, sender) {
8130
+ try {
8131
+ send({
8132
+ type: "log",
8133
+ event: {
8134
+ v: 1,
8135
+ id: nowId(),
8136
+ timestamp: Date.now(),
8137
+ level: ev.level || "log",
8138
+ context: ev.context || "content",
8139
+ messageParts: Array.isArray(ev.messageParts) ? ev.messageParts : [],
8140
+ url: ev.url || (sender ? sender.url : undefined),
8141
+ tabId: sender && sender.tab ? sender.tab.id : undefined,
8142
+ frameId: sender ? sender.frameId : undefined,
8143
+ runId: INSTANCE_ID
8144
+ }
8145
+ });
8146
+ } catch (e) {}
8147
+ }
8148
+ try {
8149
+ var rtPort = g.chrome;
8150
+ if (rtPort && rtPort.runtime && rtPort.runtime.onConnect) {
8151
+ rtPort.runtime.onConnect.addListener(function (port) {
8152
+ if (!port || port.name !== "__extjs-bridge-log__") return;
8153
+ try {
8154
+ port.onMessage.addListener(function (msg) {
8155
+ if (!msg || !msg.__extjsBridgeLog) return;
8156
+ shipRelayedLog(msg.__extjsBridgeLog, port.sender);
8157
+ });
8158
+ } catch (e) {}
8159
+ });
8160
+ }
8161
+ } catch (e) {}
8162
+ // Legacy sendMessage path: kept for any surface still relaying the old way
8163
+ // (harmless one-predicate listener; new relays never use it).
7989
8164
  try {
7990
8165
  var rt = g.chrome;
7991
8166
  if (rt && rt.runtime && rt.runtime.onMessage) {
7992
8167
  rt.runtime.onMessage.addListener(function (msg, sender) {
7993
8168
  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) {}
8169
+ shipRelayedLog(msg.__extjsBridgeLog, sender);
8012
8170
  // No async response.
8013
8171
  });
8014
8172
  }
@@ -8071,7 +8229,8 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
8071
8229
 
8072
8230
  var CONTEXT = "__EXTJS_CONTEXT__";
8073
8231
  var chrome = g.chrome;
8074
- if (!chrome || !chrome.runtime || typeof chrome.runtime.sendMessage !== "function") return;
8232
+ if (!chrome || !chrome.runtime) return;
8233
+ var canRelay = typeof chrome.runtime.connect === "function";
8075
8234
 
8076
8235
  g.__extjsBridgeRelayInstalled = true;
8077
8236
  var consoleRef = g.console || {};
@@ -8093,14 +8252,39 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
8093
8252
 
8094
8253
  function here() { try { return g.location ? g.location.href : undefined; } catch (e) { return undefined; } }
8095
8254
 
8255
+ // Lazy named port to the SW producer. Connecting wakes an idle SW like
8256
+ // sendMessage does, but port frames never reach the extension's own
8257
+ // onMessage listeners (see the loop note above). Reconnect on demand: the
8258
+ // SW idling out (or reloading) disconnects the port; the next log redials.
8259
+ var logPort = null;
8260
+ function getLogPort() {
8261
+ if (!canRelay) return null;
8262
+ if (logPort) return logPort;
8263
+ try {
8264
+ logPort = chrome.runtime.connect({name: "__extjs-bridge-log__"});
8265
+ logPort.onDisconnect.addListener(function () {
8266
+ try { void chrome.runtime.lastError; } catch (e) {}
8267
+ logPort = null;
8268
+ });
8269
+ } catch (e) { logPort = null; }
8270
+ return logPort;
8271
+ }
8272
+
8096
8273
  LEVELS.forEach(function (level) {
8097
8274
  var orig = typeof consoleRef[level] === "function" ? consoleRef[level].bind(consoleRef) : function () {};
8098
8275
  consoleRef[level] = function () {
8099
8276
  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
- );
8277
+ var p = getLogPort();
8278
+ if (p) {
8279
+ try {
8280
+ p.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}});
8281
+ } catch (e) {
8282
+ // stale port (SW restarted): drop it and redial once
8283
+ logPort = null;
8284
+ var p2 = getLogPort();
8285
+ if (p2) { try { p2.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}}); } catch (e2) {} }
8286
+ }
8287
+ }
8104
8288
  } catch (e) {}
8105
8289
  return orig.apply(consoleRef, arguments);
8106
8290
  };
@@ -10524,6 +10708,26 @@ function webpackConfig(projectStructure, devOptions) {
10524
10708
  'node_modules',
10525
10709
  __rspack_external_path.join(process.cwd(), 'node_modules')
10526
10710
  ],
10711
+ roots: [
10712
+ __rspack_external_path.join(packageJsonDir, 'public'),
10713
+ __rspack_external_path.dirname(manifestPath)
10714
+ ],
10715
+ extensionAlias: {
10716
+ '.js': [
10717
+ '.ts',
10718
+ '.tsx',
10719
+ '.js',
10720
+ '.jsx'
10721
+ ],
10722
+ '.mjs': [
10723
+ '.mts',
10724
+ '.mjs'
10725
+ ],
10726
+ '.cjs': [
10727
+ '.cts',
10728
+ '.cjs'
10729
+ ]
10730
+ },
10527
10731
  extensions: [
10528
10732
  '.js',
10529
10733
  '.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,
@@ -674,7 +677,7 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
674
677
  }
675
678
  return false;
676
679
  }
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"}}');
680
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.8","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
681
  function asAbsolute(p) {
679
682
  return __rspack_external_path.isAbsolute(p) ? p : __rspack_external_path.resolve(p);
680
683
  }
@@ -1634,6 +1637,10 @@ function createPlaywrightMetadataWriter(options) {
1634
1637
  if (__rspack_external_fs.existsSync(readyPath)) {
1635
1638
  const prev = JSON.parse(__rspack_external_fs.readFileSync(readyPath, 'utf-8'));
1636
1639
  if ('number' == typeof prev.cdpPort) payload.cdpPort = prev.cdpPort;
1640
+ if ('string' == typeof prev.browserExitedAt) {
1641
+ payload.browserExitedAt = prev.browserExitedAt;
1642
+ payload.browserExitCode = prev.browserExitCode ?? null;
1643
+ }
1637
1644
  }
1638
1645
  } catch {}
1639
1646
  writeJsonAtomic(readyPath, payload);
@@ -2113,4 +2120,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2113
2120
  await browserLauncher(resolvedOpts);
2114
2121
  metadata.writeReady();
2115
2122
  }
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 };
2123
+ 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, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
package/dist/839.mjs CHANGED
@@ -4,7 +4,7 @@ import { execFileSync, spawn, spawnSync as external_child_process_spawnSync } fr
4
4
  import { buildExecEnv, detectPackageManagerFromLockfile } from "prefers-yarn";
5
5
  import pintor from "pintor";
6
6
  import { EventEmitter } from "node:events";
7
- import { package_namespaceObject, buildSuccessWithWarnings, buildWarningsDetails, loadCommandConfig, needsInstall, getDirs, buildCommandFailed, sanitize, writingTypeDefinitions, projectInstallFallbackToNpm, buildWebpack, assertNoManagedDependencyConflicts, debugDirs, debugBrowser, normalizeBrowser, debugOutputPath, loadCustomConfig, buildSuccess, writingTypeDefinitionsError, getDistPath, loadBrowserConfig, getProjectStructure, authorInstallNotice, resolveCompanionExtensionsConfig, getSpecialFoldersDataForProjectRoot } from "./101.mjs";
7
+ import { package_namespaceObject, buildSuccessWithWarnings, buildWarningsDetails, loadCommandConfig, needsInstall, getDirs, buildCommandFailed, getSpecialFoldersDataForProjectRoot, writingTypeDefinitions, sanitize, projectInstallFallbackToNpm, buildWebpack, assertNoManagedDependencyConflicts, debugDirs, debugBrowser, normalizeBrowser, debugOutputPath, loadCustomConfig, buildSuccess, writingTypeDefinitionsError, getDistPath, loadBrowserConfig, projectInstallScriptsDisabled, authorInstallNotice, getProjectStructure, resolveCompanionExtensionsConfig } from "./101.mjs";
8
8
  import { stripBom, parseJsonSafe } from "./23.mjs";
9
9
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./80.mjs";
10
10
  import { getCanonicalContentScriptEntryName } from "./291.mjs";
@@ -14,6 +14,11 @@ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(imp
14
14
  import * as __rspack_external_fs from "fs";
15
15
  import * as __rspack_external_path from "path";
16
16
  import * as __rspack_external_fs_promises_400951f8 from "fs/promises";
17
+ const RUST_MIN_STACK_BYTES = 268435456;
18
+ function ensureRustMinStack(env = process.env) {
19
+ if (!env.RUST_MIN_STACK) env.RUST_MIN_STACK = String(RUST_MIN_STACK_BYTES);
20
+ }
21
+ ensureRustMinStack();
17
22
  function getBuildSummary(browser, info) {
18
23
  const assets = info?.assets || [];
19
24
  return {
@@ -347,6 +352,29 @@ function projectInstallArgs(pm, projectDir) {
347
352
  '--ignore-workspace'
348
353
  ];
349
354
  }
355
+ function installScriptSuppression(pm) {
356
+ if ('true' === process.env.EXTENSION_ALLOW_INSTALL_SCRIPTS) return {
357
+ args: [],
358
+ env: {}
359
+ };
360
+ if ('deno' === pm.name) return {
361
+ args: [],
362
+ env: {}
363
+ };
364
+ if ('yarn' === pm.name) return {
365
+ args: [],
366
+ env: {
367
+ YARN_ENABLE_SCRIPTS: 'false',
368
+ npm_config_ignore_scripts: 'true'
369
+ }
370
+ };
371
+ return {
372
+ args: [
373
+ "--ignore-scripts"
374
+ ],
375
+ env: {}
376
+ };
377
+ }
350
378
  function resolveNpmPackageManager() {
351
379
  return hydrateResolvedPackageManager('npm') || {
352
380
  name: 'npm'
@@ -397,7 +425,10 @@ function execInstallCommand(command, args, options) {
397
425
  const child = spawn(invocation.command, invocation.args, {
398
426
  cwd: options?.cwd,
399
427
  stdio,
400
- env: env || process.env,
428
+ env: {
429
+ ...env || process.env,
430
+ ...options?.env
431
+ },
401
432
  ...useShell ? {
402
433
  shell: true
403
434
  } : {}
@@ -414,27 +445,34 @@ async function ensureUserProjectDependencies(packageJsonDir) {
414
445
  const pm = resolvePackageManager({
415
446
  cwd: packageJsonDir
416
447
  });
448
+ const suppression = installScriptSuppression(pm);
417
449
  const cmd = buildInstallCommand(pm, [
418
450
  'install',
451
+ ...suppression.args,
419
452
  ...projectInstallArgs(pm, packageJsonDir)
420
453
  ]);
454
+ if (suppression.args.length || Object.keys(suppression.env).length) console.warn(projectInstallScriptsDisabled(pm.name));
421
455
  try {
422
456
  await execInstallCommand(cmd.command, cmd.args, {
423
457
  cwd: packageJsonDir,
424
- stdio: 'inherit'
458
+ stdio: 'inherit',
459
+ env: suppression.env
425
460
  });
426
461
  } catch (error) {
427
462
  if ('npm' === pm.name) throw error;
428
463
  if ('deno' === pm.name) throw error;
429
464
  console.warn(projectInstallFallbackToNpm(pm.name));
430
465
  const npmPm = resolveNpmPackageManager();
466
+ const npmSuppression = installScriptSuppression(npmPm);
431
467
  const npmCmd = buildInstallCommand(npmPm, [
432
468
  'install',
433
- '--no-package-lock'
469
+ '--no-package-lock',
470
+ ...npmSuppression.args
434
471
  ]);
435
472
  await execInstallCommand(npmCmd.command, npmCmd.args, {
436
473
  cwd: packageJsonDir,
437
- stdio: 'inherit'
474
+ stdio: 'inherit',
475
+ env: npmSuppression.env
438
476
  });
439
477
  }
440
478
  }