extension-develop 4.1.14 → 4.1.15

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 (56) hide show
  1. package/dist/0~dev-server.mjs +2 -2
  2. package/dist/0~rspack-config.mjs +184 -59
  3. package/dist/101.mjs +1 -1
  4. package/dist/266.mjs +40 -1
  5. package/dist/372.mjs +2 -1
  6. package/dist/77.mjs +4 -1
  7. package/dist/{518.mjs → 834.mjs} +1 -42
  8. package/dist/839.mjs +106 -3
  9. package/dist/86.mjs +45 -0
  10. package/dist/dead-css-url-loader.mjs +1 -1
  11. package/dist/extension-js-devtools/chrome/options/index.html +1 -1
  12. package/dist/extension-js-devtools/chrome/options/index.js +1 -1
  13. package/dist/extension-js-devtools/chrome/pages/centralized-logger.html +1 -1
  14. package/dist/extension-js-devtools/chrome/pages/centralized-logger.js +4 -4
  15. package/dist/extension-js-devtools/chrome/pages/welcome.html +1 -1
  16. package/dist/extension-js-devtools/chrome/pages/welcome.js +4 -4
  17. package/dist/extension-js-devtools/chrome/shared/commons.js +1 -0
  18. package/dist/extension-js-devtools/chrome/shared/framework.js +1 -0
  19. package/dist/extension-js-devtools/chromium/options/index.html +1 -1
  20. package/dist/extension-js-devtools/chromium/options/index.js +1 -1
  21. package/dist/extension-js-devtools/chromium/pages/centralized-logger.html +1 -1
  22. package/dist/extension-js-devtools/chromium/pages/centralized-logger.js +4 -4
  23. package/dist/extension-js-devtools/chromium/pages/welcome.html +1 -1
  24. package/dist/extension-js-devtools/chromium/pages/welcome.js +4 -4
  25. package/dist/extension-js-devtools/chromium/shared/commons.js +1 -0
  26. package/dist/extension-js-devtools/chromium/shared/framework.js +1 -0
  27. package/dist/extension-js-devtools/edge/options/index.html +1 -1
  28. package/dist/extension-js-devtools/edge/options/index.js +1 -1
  29. package/dist/extension-js-devtools/edge/pages/centralized-logger.html +1 -1
  30. package/dist/extension-js-devtools/edge/pages/centralized-logger.js +4 -4
  31. package/dist/extension-js-devtools/edge/pages/welcome.html +1 -1
  32. package/dist/extension-js-devtools/edge/pages/welcome.js +4 -4
  33. package/dist/extension-js-devtools/edge/shared/commons.js +1 -0
  34. package/dist/extension-js-devtools/edge/shared/framework.js +1 -0
  35. package/dist/extension-js-devtools/firefox/options/index.html +1 -1
  36. package/dist/extension-js-devtools/firefox/options/index.js +1 -1
  37. package/dist/extension-js-devtools/firefox/pages/centralized-logger.html +1 -1
  38. package/dist/extension-js-devtools/firefox/pages/centralized-logger.js +4 -4
  39. package/dist/extension-js-devtools/firefox/pages/welcome.html +1 -1
  40. package/dist/extension-js-devtools/firefox/pages/welcome.js +4 -4
  41. package/dist/extension-js-devtools/firefox/shared/commons.js +1 -0
  42. package/dist/extension-js-devtools/firefox/shared/framework.js +1 -0
  43. package/dist/lib/messages.d.ts +1 -0
  44. package/dist/lib/normalize-split-chunks.d.ts +7 -0
  45. package/dist/lib/split-chunks.d.ts +13 -0
  46. package/dist/plugin-css/index.d.ts +1 -0
  47. package/dist/plugin-css/public-css-url-loader.d.ts +13 -0
  48. package/dist/plugin-web-extension/feature-html/html-lib/inject.d.ts +12 -1
  49. package/dist/plugin-web-extension/feature-html/html-lib/patch-html.d.ts +1 -1
  50. package/dist/plugin-web-extension/feature-html/steps/update-html-file.d.ts +2 -1
  51. package/dist/plugin-web-extension/feature-scripts/messages.d.ts +21 -0
  52. package/dist/plugin-web-extension/feature-scripts/steps/trace-runtime-loaded-files.d.ts +2 -0
  53. package/dist/plugin-web-extension/feature-scripts/steps/warn-split-initial-chunks.d.ts +7 -0
  54. package/dist/plugin-web-extension/shared/initial-files.d.ts +11 -0
  55. package/dist/public-css-url-loader.mjs +37 -0
  56. package/package.json +1 -1
@@ -6,7 +6,7 @@ import { rspack } from "@rspack/core";
6
6
  import { RspackDevServer } from "@rspack/dev-server";
7
7
  import { merge } from "webpack-merge";
8
8
  import { WebSocket, WebSocketServer } from "ws";
9
- import { classifyReloadFromSources, attachLifecycleStream, readContentScriptCount, humanLine, buildSourceFeatureIndex, createChangedSourcesTracker, createLifecycleStream, dispatchReload } from "./839.mjs";
9
+ import { classifyReloadFromSources, attachLifecycleStream, readContentScriptCount, humanLine, createChangedSourcesTracker, buildSourceFeatureIndex, applySplitChunksGuard, createLifecycleStream, dispatchReload } from "./839.mjs";
10
10
  import { runnerCleanupError, autoExitForceKill, loadCommandConfig, sanitize, extensionJsRunnerError, portInUse, devServerStartTimeout, autoExitTriggered, loadProjectConfigDefaults, runnerUncaughtException, shouldWarnPortConflict, devServerRestarting, DEV_COMMAND_DEFAULTS, mergeOptionLayers, runnerUnhandledRejection, createPlaywrightMetadataWriter, autoExitModeEnabled, getSessionRunId, isGeckoBasedBrowser, loadCustomConfig, loadBrowserConfig, resolveCompanionExtensionsConfig, getSpecialFoldersDataForProjectRoot } from "./101.mjs";
11
11
  import { CONTROL_WS_PATH, writePersistedControlPort, writeControlToken, clearControlToken, readPersistedControlPort } from "./887.mjs";
12
12
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./80.mjs";
@@ -1305,7 +1305,7 @@ async function dev_server_devServer(projectStructure, devOptions) {
1305
1305
  async function createCompilerAndServer(opts) {
1306
1306
  const baseConfig = webpackConfig(projectStructure, webpackConfigOptions);
1307
1307
  const customWebpackConfig = await loadCustomConfig(packageJsonDir);
1308
- const compilerConfig = merge(customWebpackConfig(baseConfig), {});
1308
+ const compilerConfig = applySplitChunksGuard(merge(customWebpackConfig(baseConfig), {}));
1309
1309
  const compiler = rspack(compilerConfig);
1310
1310
  const uninstallManifestGuard = installManifestDiskWriteGuard(manifestOutputPath);
1311
1311
  const releaseOutputFsGuard = suppressManifestOutputWrites(compiler, manifestOutputPath);
@@ -16,15 +16,17 @@ import { package_namespaceObject, bundlerFatalError, bundlerRecompiling, browser
16
16
  import { stripBom, parseJsonSafe } from "./23.mjs";
17
17
  import { isResourceUnderDirs, canonicalizeDir, toResourceKey } from "./93.mjs";
18
18
  import { prefix as messaging_prefix, isDebug } from "./349.mjs";
19
- import { jsFrameworksHmrSummary, isUsingTypeScript, resolvePackageManager, humanLine, jsFrameworksIntegrationsEnabled, jsFrameworksConfigsDetected, recordZipArtifact, hasDependency, resolveDevelopInstallRoot, resolveDevelopDistFile, isUsingCustomLoader, ensureTypeScriptConfig, isUsingIntegration as messages_isUsingIntegration, getUserTypeScriptConfigFile } from "./839.mjs";
19
+ import { isUsingTypeScript, resolvePackageManager, jsFrameworksIntegrationsEnabled, classifyEntrySurface, ensureTypeScriptConfig, resolveDevelopInstallRoot, isUsingCustomLoader, getUserTypeScriptConfigFile, isUsingIntegration as messages_isUsingIntegration, jsFrameworksHmrSummary, humanLine, jsFrameworksConfigsDetected, recordZipArtifact, hasDependency, resolveDevelopDistFile, defaultSplitChunks } from "./839.mjs";
20
20
  import { renderStatsBlocks, makeSanitizedConsole } from "./0~stats-handler.mjs";
21
- import { utils_isUrl, getBaseNode, manifestJsonOutputTarget, getExtname, getBaseHref, toPosixPath, getAssetsFromHtml, normalizeManifestOutputPath, isFromIncludeList, htmlStaticAssetOutputName, manifestPageOutputTarget, iconOutputPath, isSpecialScheme, resolveStaticAttributeName, getHtmlPageDeclaredAssetPath, themeImageOutputPath, themeIconOutputPath, applyRewrittenStaticUrl, cleanLeading, getFilePath, parseHtml, resolveAbsoluteFsPath, cleanAssetUrl, isHttpLike, resolveHtmlRefPath } from "./518.mjs";
21
+ import { utils_isUrl, getBaseNode, manifestJsonOutputTarget, getExtname, getBaseHref, getAssetsFromHtml, normalizeManifestOutputPath, isFromIncludeList, htmlStaticAssetOutputName, isSpecialScheme, manifestPageOutputTarget, iconOutputPath, resolveStaticAttributeName, getHtmlPageDeclaredAssetPath, themeImageOutputPath, themeIconOutputPath, applyRewrittenStaticUrl, cleanLeading, getFilePath, parseHtml, resolveAbsoluteFsPath, cleanAssetUrl, isHttpLike, resolveHtmlRefPath } from "./834.mjs";
22
22
  import { EXTENSIONJS_CONTENT_SCRIPT_LAYER, getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, CONTENT_SCRIPT_CSS_PROBE_MARKER_PREFIX, createContentScriptCssProbeMarkerPattern, getCanonicalContentScriptJsAssetName, getCanonicalContentScriptCssAssetName, isCanonicalContentScriptAsset } from "./291.mjs";
23
23
  import { packagingSourceFiles, debugBrowser, debugExtensionsToLoad, treeWithSourceFiles, debugOutputPath, manifestInvalidJson, getDirs, asAbsolute, treeWithDistFilesBrowser, packagingDistributionFiles, treeWithSourceAndDistFiles, toPosixPath as paths_toPosixPath, debugContextPath, noCompanionExtensionsResolved } from "./77.mjs";
24
24
  import { hasProjectDependency, findNearestProjectManifestSync, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./80.mjs";
25
25
  import { cssMinifierDroppedRules, postCssConfigUnreadable, missingSassDependency, deadCssUrlRef, postCssPluginNotResolved, postCssConfigPluginsShape, cssIntegrationsEnabled, cssConfigsDetected, isUsingIntegration } from "./845.mjs";
26
26
  import { minifierDroppedTokens, restoreVerbatimCssAssets } from "./129.mjs";
27
- import { injectedFileDependencyMissing, importScriptsDependencyMissing, getURLDependencyMissing, staticImportDependencyMissing, fetchedFileDependencyMissing, runtimeSetSurfaceDependencyMissing } from "./266.mjs";
27
+ import { restorePublicRootRefs, PUBLIC_ROOT_SCHEME } from "./public-css-url-loader.mjs";
28
+ import { toPosixPath } from "./86.mjs";
29
+ import { getURLDependencyMissing, entrySplitAcrossInitialFiles, fetchedFileDependencyMissing, importScriptsDependencyMissing, injectedCompiledSourceLiteral, injectedFileDependencyMissing, staticImportDependencyMissing, runtimeSetSurfaceDependencyMissing } from "./266.mjs";
28
30
  import { inspectPublicFolders, publicResolveRoots, rememberPublicRoots } from "./278.mjs";
29
31
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
30
32
  import { dirname as __rspack_dirname } from "node:path";
@@ -2822,6 +2824,13 @@ async function buildCssRules(projectPath, mode, usage, opts) {
2822
2824
  }
2823
2825
  let ruleType = type;
2824
2826
  let parser;
2827
+ if ('css' === nonModuleType && manifestPath && 'asset/inline' !== type) use.unshift({
2828
+ loader: resolveDevelopDistFile('public-css-url-loader'),
2829
+ options: {
2830
+ manifestPath,
2831
+ projectPath
2832
+ }
2833
+ });
2825
2834
  if ('asset/inline' === type && manifestPath) {
2826
2835
  use.unshift({
2827
2836
  loader: resolveDevelopDistFile('dead-css-url-loader'),
@@ -2899,7 +2908,8 @@ async function cssInContentScriptLoader(projectPath, manifestPath, mode, usage =
2899
2908
  async function cssInHtmlLoader(projectPath, mode, manifestPath, usage = {}) {
2900
2909
  return buildCssRules(projectPath, mode, usage, {
2901
2910
  nonModuleType: 'css',
2902
- issuer: (issuer)=>!isContentScriptEntry(issuer, manifestPath, projectPath)
2911
+ issuer: (issuer)=>!isContentScriptEntry(issuer, manifestPath, projectPath),
2912
+ manifestPath
2903
2913
  });
2904
2914
  }
2905
2915
  class CssPlugin {
@@ -2984,6 +2994,22 @@ class CssPlugin {
2984
2994
  });
2985
2995
  });
2986
2996
  }
2997
+ restorePublicRootRefs(compiler) {
2998
+ if (!compiler.hooks?.thisCompilation?.tap) return;
2999
+ compiler.hooks.thisCompilation.tap(`${CssPlugin.name}:public`, (c)=>{
3000
+ if (!c?.hooks?.processAssets?.tap) return;
3001
+ c.hooks.processAssets.tap({
3002
+ name: `${CssPlugin.name}:public-root-restore`,
3003
+ stage: core_Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE + 2
3004
+ }, ()=>{
3005
+ for (const asset of c.getAssets()){
3006
+ if (!/\.(css|js)$/.test(asset.name)) continue;
3007
+ const before = asset.source.source().toString();
3008
+ if (before.includes(PUBLIC_ROOT_SCHEME)) c.updateAsset(asset.name, new core_sources.RawSource(restorePublicRootRefs(before)));
3009
+ }
3010
+ });
3011
+ });
3012
+ }
2987
3013
  tolerateDeadUrlRefs(compiler) {
2988
3014
  const manifestDir = __rspack_external_node_path_c5b9b54f.dirname(this.manifestPath);
2989
3015
  const projectPath = compiler.options.context || process.cwd();
@@ -3032,6 +3058,7 @@ class CssPlugin {
3032
3058
  }
3033
3059
  async apply(compiler) {
3034
3060
  this.keepCssParityInProduction(compiler);
3061
+ this.restorePublicRootRefs(compiler);
3035
3062
  this.tolerateDeadUrlRefs(compiler);
3036
3063
  const mode = compiler.options.mode || 'development';
3037
3064
  if ('production' === mode) return void compiler.hooks.beforeRun.tapPromise(CssPlugin.name, ()=>this.configureOptions(compiler));
@@ -6891,6 +6918,15 @@ const SOURCE_SIBLING_EXTENSIONS = [
6891
6918
  '.jsx',
6892
6919
  '.mjs'
6893
6920
  ];
6921
+ const COMPILED_TO_JS_EXTENSIONS = new Set([
6922
+ '.ts',
6923
+ '.tsx',
6924
+ '.jsx',
6925
+ '.mts',
6926
+ '.cts',
6927
+ '.mjs',
6928
+ '.cjs'
6929
+ ]);
6894
6930
  class TraceRuntimeLoadedFiles {
6895
6931
  manifestPath;
6896
6932
  constructor(options){
@@ -7098,17 +7134,25 @@ class TraceRuntimeLoadedFiles {
7098
7134
  const content = asset.source.source().toString();
7099
7135
  for (const literal of extractInjectedFileLiterals(content)){
7100
7136
  const distRel = resolveExtensionPath(literal, '');
7101
- if (!(!distRel || seen.has(distRel))) {
7102
- seen.add(distRel);
7103
- copyThroughOrWarn(compilation, {
7104
- manifestDir,
7105
- sourceRel: distRel,
7106
- distRel,
7107
- warning: (expected, sourceSibling)=>injectedFileDependencyMissing(asset.name, literal, expected, sourceSibling),
7108
- warningName: 'InjectedScriptFilesMissing',
7109
- warningFile: asset.name
7110
- });
7137
+ if (!distRel || seen.has(distRel)) continue;
7138
+ seen.add(distRel);
7139
+ const emittedPath = compiledSourceEmittedPath(distRel);
7140
+ if (emittedPath && compilation.getAsset(emittedPath)) {
7141
+ const warn = new core_WebpackError(injectedCompiledSourceLiteral(asset.name, literal, emittedPath));
7142
+ warn.name = 'InjectedScriptCompiledSource';
7143
+ warn.file = asset.name;
7144
+ compilation.warnings ||= [];
7145
+ compilation.warnings.push(warn);
7146
+ continue;
7111
7147
  }
7148
+ copyThroughOrWarn(compilation, {
7149
+ manifestDir,
7150
+ sourceRel: distRel,
7151
+ distRel,
7152
+ warning: (expected, sourceSibling)=>injectedFileDependencyMissing(asset.name, literal, expected, sourceSibling),
7153
+ warningName: 'InjectedScriptFilesMissing',
7154
+ warningFile: asset.name
7155
+ });
7112
7156
  }
7113
7157
  }
7114
7158
  }
@@ -7161,6 +7205,11 @@ function findSourceSibling(abs) {
7161
7205
  const base = abs.slice(0, -3);
7162
7206
  return SOURCE_SIBLING_EXTENSIONS.map((ext)=>base + ext).find((candidate)=>__rspack_external_node_fs_5ea92f0c.existsSync(candidate));
7163
7207
  }
7208
+ function compiledSourceEmittedPath(distRel) {
7209
+ const ext = __rspack_external_node_path_c5b9b54f.posix.extname(distRel);
7210
+ if (!COMPILED_TO_JS_EXTENSIONS.has(ext.toLowerCase())) return null;
7211
+ return `${distRel.slice(0, -ext.length)}.js`;
7212
+ }
7164
7213
  function trace_runtime_loaded_files_unixify(filePath) {
7165
7214
  return filePath.replace(/\\/g, '/');
7166
7215
  }
@@ -7290,20 +7339,38 @@ function extractImportScriptsLiterals(source) {
7290
7339
  function extractInjectedFileLiterals(source) {
7291
7340
  const code = blankComments(source);
7292
7341
  const literals = [];
7293
- const callRe = /\b(?:executeScript|insertCSS|removeCSS)\s*\(/g;
7294
- let match;
7295
- while(match = callRe.exec(code)){
7296
- const args = readBalancedArgs(code, match.index + match[0].length - 1);
7297
- if (null == args) continue;
7298
- const filesRe = /["']?files["']?\s*:\s*\[([^\]]*)\]/g;
7299
- let filesMatch;
7300
- while(filesMatch = filesRe.exec(args))for (const element of splitTopLevelArgs(filesMatch[1])){
7301
- const literal = pureStringLiteral(element);
7302
- if (null != literal) literals.push(literal);
7342
+ const calls = [
7343
+ {
7344
+ callRe: /\b(?:executeScript|insertCSS|removeCSS)\s*\(/g,
7345
+ arrayProps: [
7346
+ 'files'
7347
+ ]
7348
+ },
7349
+ {
7350
+ callRe: /\b(?:registerContentScripts|updateContentScripts)\s*\(/g,
7351
+ arrayProps: [
7352
+ 'js',
7353
+ 'css'
7354
+ ]
7355
+ }
7356
+ ];
7357
+ for (const { callRe, arrayProps } of calls){
7358
+ let match;
7359
+ while(match = callRe.exec(code)){
7360
+ const args = readBalancedArgs(code, match.index + match[0].length - 1);
7361
+ if (null == args) continue;
7362
+ for (const prop of arrayProps){
7363
+ const arrayRe = new RegExp(`(?<![\\w$.])["']?${prop}["']?\\s*:\\s*\\[([^\\]]*)\\]`, 'g');
7364
+ let arrayMatch;
7365
+ while(arrayMatch = arrayRe.exec(args))for (const element of splitTopLevelArgs(arrayMatch[1])){
7366
+ const literal = pureStringLiteral(element);
7367
+ if (null != literal) literals.push(literal);
7368
+ }
7369
+ }
7370
+ const fileRe = /["']?file["']?\s*:\s*(['"])((?:\\.|(?!\1)[^\\])*)\1/g;
7371
+ let fileMatch;
7372
+ while(fileMatch = fileRe.exec(args))literals.push(unescapeStringBody(fileMatch[2]));
7303
7373
  }
7304
- const fileRe = /["']?file["']?\s*:\s*(['"])((?:\\.|(?!\1)[^\\])*)\1/g;
7305
- let fileMatch;
7306
- while(fileMatch = fileRe.exec(args))literals.push(unescapeStringBody(fileMatch[2]));
7307
7374
  }
7308
7375
  return literals;
7309
7376
  }
@@ -8226,26 +8293,32 @@ function bakeBaseHref(htmlDocument) {
8226
8293
  node.childNodes = node.childNodes.filter((child)=>child !== baseNode);
8227
8294
  });
8228
8295
  }
8229
- function injectJsScript(bodyNode, feature, firstScriptAttrs) {
8230
- const scriptTag = __rspack_external_parse5_utilities_78b19c6a.createNode("script");
8231
- scriptTag.attrs = [
8296
+ const PROPAGATED_SCRIPT_ATTRS = new Set([
8297
+ 'type',
8298
+ 'defer',
8299
+ 'async'
8300
+ ]);
8301
+ function scriptTagAttrs(src, firstScriptAttrs) {
8302
+ const attrs = [
8232
8303
  {
8233
8304
  name: 'src',
8234
- value: getFilePath(feature, '.js', true)
8305
+ value: src
8235
8306
  }
8236
8307
  ];
8237
- const propagateScriptAttrs = new Set([
8238
- 'type',
8239
- 'defer',
8240
- 'async'
8241
- ]);
8242
- if (firstScriptAttrs) {
8243
- for (const attr of firstScriptAttrs)if (propagateScriptAttrs.has(attr.name) && !scriptTag.attrs.find((a)=>a.name === attr.name)) scriptTag.attrs.push({
8244
- name: attr.name,
8245
- value: attr.value
8246
- });
8247
- }
8248
- __rspack_external_parse5_utilities_78b19c6a.append(bodyNode, scriptTag);
8308
+ for (const attr of firstScriptAttrs || [])if (PROPAGATED_SCRIPT_ATTRS.has(attr.name) && !attrs.find((a)=>a.name === attr.name)) attrs.push({
8309
+ name: attr.name,
8310
+ value: attr.value
8311
+ });
8312
+ return attrs;
8313
+ }
8314
+ function createScriptTag(src, firstScriptAttrs) {
8315
+ const scriptTag = __rspack_external_parse5_utilities_78b19c6a.createNode("script");
8316
+ scriptTag.attrs = scriptTagAttrs(src, firstScriptAttrs);
8317
+ return scriptTag;
8318
+ }
8319
+ function injectJsScript(bodyNode, feature, firstScriptAttrs, siblingScripts = []) {
8320
+ for (const src of siblingScripts)__rspack_external_parse5_utilities_78b19c6a.append(bodyNode, createScriptTag(src, firstScriptAttrs));
8321
+ __rspack_external_parse5_utilities_78b19c6a.append(bodyNode, createScriptTag(getFilePath(feature, '.js', true), firstScriptAttrs));
8249
8322
  }
8250
8323
  function warnIfPublicRootAssetMissing(compilation, htmlEntry, cleanPath) {
8251
8324
  const projectDir = __rspack_external_node_path_c5b9b54f.dirname(__rspack_external_node_path_c5b9b54f.dirname(htmlEntry));
@@ -8258,7 +8331,15 @@ function warnIfPublicRootAssetMissing(compilation, htmlEntry, cleanPath) {
8258
8331
  warn.message = filtered.join('\n').trim();
8259
8332
  compilation.warnings.push(warn);
8260
8333
  }
8261
- function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir) {
8334
+ function insertBefore(reference, node) {
8335
+ const parent = reference.parentNode;
8336
+ if (!parent || !Array.isArray(parent.childNodes)) return;
8337
+ const index = parent.childNodes.indexOf(reference);
8338
+ if (-1 === index) return;
8339
+ node.parentNode = parent;
8340
+ parent.childNodes.splice(index, 0, node);
8341
+ }
8342
+ function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir, siblingScripts = []) {
8262
8343
  const htmlFile = __rspack_external_node_fs_5ea92f0c.readFileSync(htmlEntry, {
8263
8344
  encoding: 'utf8'
8264
8345
  });
@@ -8319,19 +8400,9 @@ function patchHtml(compilation, feature, htmlEntry, includeList, manifestDir) {
8319
8400
  if (bundledScriptNodes.length > 0) {
8320
8401
  for (const scriptNode of bundledScriptNodes.slice(0, -1))__rspack_external_parse5_utilities_78b19c6a.remove(scriptNode);
8321
8402
  const lastScriptNode = bundledScriptNodes[bundledScriptNodes.length - 1];
8322
- const propagateScriptAttrs = new Set([
8323
- 'type',
8324
- 'defer',
8325
- 'async'
8326
- ]);
8327
- lastScriptNode.attrs = [
8328
- {
8329
- name: 'src',
8330
- value: getFilePath(feature, '.js', true)
8331
- },
8332
- ...(firstScriptAttrs || []).filter((attr)=>propagateScriptAttrs.has(attr.name))
8333
- ];
8334
- } else if (bodyNode) injectJsScript(bodyNode, feature, firstScriptAttrs);
8403
+ for (const src of siblingScripts)insertBefore(lastScriptNode, createScriptTag(src, firstScriptAttrs));
8404
+ lastScriptNode.attrs = scriptTagAttrs(getFilePath(feature, '.js', true), firstScriptAttrs);
8405
+ } else if (bodyNode) injectJsScript(bodyNode, feature, firstScriptAttrs, siblingScripts);
8335
8406
  }
8336
8407
  bakeBaseHref(htmlDocument);
8337
8408
  return __rspack_external_parse5_utilities_78b19c6a.stringify(htmlDocument);
@@ -9035,6 +9106,34 @@ class ThrowIfRecompileIsNeeded {
9035
9106
  });
9036
9107
  }
9037
9108
  }
9109
+ const HOT_UPDATE_FILE = /\.hot-update\.m?js$/i;
9110
+ function isJsFile(file) {
9111
+ return /\.m?js$/i.test(file) && !HOT_UPDATE_FILE.test(file);
9112
+ }
9113
+ function initialJsFiles(entrypoint) {
9114
+ const files = new Set();
9115
+ const runtimeChunk = entrypoint.getRuntimeChunk?.();
9116
+ for (const file of runtimeChunk?.files || [])if (isJsFile(file)) files.add(file);
9117
+ for (const file of entrypoint.getFiles())if (isJsFile(file)) files.add(file);
9118
+ return [
9119
+ ...files
9120
+ ];
9121
+ }
9122
+ function entryOwnJsFile(entryName, entrypoint, files) {
9123
+ const entryChunk = entrypoint.getEntrypointChunk?.();
9124
+ for (const file of entryChunk?.files || [])if (isJsFile(file) && files.includes(file)) return file;
9125
+ const byName = new RegExp(`^${entryName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(\\.[a-z0-9]+)?\\.m?js$`, 'i');
9126
+ return files.find((file)=>byName.test(file)) || files[files.length - 1];
9127
+ }
9128
+ function siblingScriptsFor(compilation, feature) {
9129
+ const entrypoints = compilation.entrypoints;
9130
+ const entrypoint = 'function' == typeof entrypoints?.get ? entrypoints.get(feature) : null;
9131
+ if (!entrypoint || 'function' != typeof entrypoint.getFiles) return [];
9132
+ const files = initialJsFiles(entrypoint);
9133
+ if (files.length <= 1) return [];
9134
+ const ownFile = entryOwnJsFile(feature, entrypoint, files);
9135
+ return files.filter((file)=>file !== ownFile).map((file)=>getFilePath(file, '', true));
9136
+ }
9038
9137
  class UpdateHtmlFile {
9039
9138
  manifestPath;
9040
9139
  includeList;
@@ -9057,7 +9156,7 @@ class UpdateHtmlFile {
9057
9156
  const getAssetFn = compilation.getAsset;
9058
9157
  const existing = 'function' == typeof getAssetFn ? getAssetFn.call(compilation, assetFilename) : compilation.assets?.[assetFilename];
9059
9158
  if (!existing) continue;
9060
- const updated = patchHtml(compilation, feature, resolved, this.includeList || {}, projectDir);
9159
+ const updated = patchHtml(compilation, feature, resolved, this.includeList || {}, projectDir, siblingScriptsFor(compilation, feature));
9061
9160
  const updatedHtml = 'string' == typeof updated ? updated : updated && 'string' == typeof updated.html ? updated.html : null;
9062
9161
  if ('string' == typeof updatedHtml) compilation.updateAsset(assetFilename, new core_sources.RawSource(updatedHtml));
9063
9162
  }
@@ -13212,6 +13311,31 @@ function parsesAsModule(source) {
13212
13311
  return false;
13213
13312
  }
13214
13313
  }
13314
+ class WarnSplitInitialChunks {
13315
+ apply(compiler) {
13316
+ if (!compiler?.hooks?.thisCompilation?.tap) return;
13317
+ compiler.hooks.thisCompilation.tap("scripts:warn-split-initial-chunks", (compilation)=>{
13318
+ compilation.hooks.processAssets.tap({
13319
+ name: "scripts:warn-split-initial-chunks",
13320
+ stage: core_Compilation.PROCESS_ASSETS_STAGE_REPORT
13321
+ }, ()=>{
13322
+ const entrypoints = compilation.entrypoints;
13323
+ for (const [entryName, entrypoint] of entrypoints){
13324
+ const surface = classifyEntrySurface(entryName);
13325
+ if ('page' === surface) continue;
13326
+ const files = initialJsFiles(entrypoint);
13327
+ if (files.length <= 1) continue;
13328
+ const ownFile = entryOwnJsFile(entryName, entrypoint, files);
13329
+ const extraFiles = files.filter((file)=>file !== ownFile);
13330
+ if (!ownFile || 0 === extraFiles.length) continue;
13331
+ const warn = new core_WebpackError(entrySplitAcrossInitialFiles(entryName, surface, ownFile, extraFiles));
13332
+ warn.file = ownFile;
13333
+ compilation.warnings.push(warn);
13334
+ }
13335
+ });
13336
+ });
13337
+ }
13338
+ }
13215
13339
  class ScriptsPlugin {
13216
13340
  manifestPath;
13217
13341
  includeList;
@@ -13241,6 +13365,7 @@ class ScriptsPlugin {
13241
13365
  }).apply(compiler);
13242
13366
  if ('production' === compiler.options.mode) new AddPublicPathRuntimeModule().apply(compiler);
13243
13367
  new ValidateEmittedScriptSyntax().apply(compiler);
13368
+ new WarnSplitInitialChunks().apply(compiler);
13244
13369
  }
13245
13370
  }
13246
13371
  class CollectContentEntryImports {
@@ -14040,7 +14165,7 @@ function webpackConfig(projectStructure, devOptions) {
14040
14165
  sideEffects: true,
14041
14166
  usedExports: 'global',
14042
14167
  concatenateModules: 'production' === devOptions.mode,
14043
- splitChunks: false,
14168
+ splitChunks: defaultSplitChunks(),
14044
14169
  runtimeChunk: false,
14045
14170
  moduleIds: 'deterministic',
14046
14171
  chunkIds: 'deterministic'
package/dist/101.mjs CHANGED
@@ -352,7 +352,7 @@ async function isUsingExperimentalConfig(projectPath) {
352
352
  }
353
353
  return false;
354
354
  }
355
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.14","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","acorn":"^8.16.0","browser-extension-manifest-fields":"^2.3.1","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.2.5","fflate":"^0.8.3","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.23","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","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"}}');
355
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.15","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","acorn":"^8.16.0","browser-extension-manifest-fields":"^2.3.1","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.2.5","fflate":"^0.8.3","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.23","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","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"}}');
356
356
  function sanitize(obj) {
357
357
  return Object.fromEntries(Object.entries(obj || {}).filter(([, value])=>void 0 !== value));
358
358
  }
package/dist/266.mjs CHANGED
@@ -21,6 +21,45 @@ function injectedFileDependencyMissing(assetName, literal, expectedPath, sourceS
21
21
  lines.push(`Move the file to ${pintor.blue(expectedPath)} or ${pintor.blue('public/')} so it ships with the extension.`);
22
22
  return lines.join('\n');
23
23
  }
24
+ function injectedCompiledSourceLiteral(assetName, literal, emittedPath) {
25
+ const lines = [];
26
+ lines.push(`${assetName} injects '${literal}', but ${literal} is compiled to ${emittedPath}.`);
27
+ lines.push(`${pintor.gray('REQUESTED')} ${pintor.underline(literal)}`);
28
+ lines.push(`${pintor.gray('EMITTED')} ${pintor.underline(emittedPath)}`);
29
+ lines.push("The browser asks for the source path, which the output does not contain, so the injection fails at runtime.");
30
+ lines.push(`Inject the emitted path: ${pintor.blue(emittedPath)}.`);
31
+ return lines.join('\n');
32
+ }
33
+ const SPLIT_ENTRY_RECIPE_URL = 'https://extension.js.org/docs/features/rspack-configuration#share-a-module-between-entries';
34
+ const SPLIT_ENTRY_SURFACES = {
35
+ page: {
36
+ loads: (entryName)=>`${entryName}.html references only`,
37
+ effect: 'the page renders blank'
38
+ },
39
+ background: {
40
+ loads: ()=>'the background registration loads only',
41
+ effect: "the background script never starts"
42
+ },
43
+ content_script: {
44
+ loads: ()=>"the content_scripts declaration injects only",
45
+ effect: "the content script never runs on the page"
46
+ },
47
+ script: {
48
+ loads: ()=>'the runtime injection loads only',
49
+ effect: "the script never runs"
50
+ }
51
+ };
52
+ function entrySplitAcrossInitialFiles(entryName, surface, ownFile, extraFiles) {
53
+ const shape = SPLIT_ENTRY_SURFACES[surface];
54
+ const count = extraFiles.length + 1;
55
+ const lines = [];
56
+ lines.push(`${entryName} is split into ${count} initial files, but ${shape.loads(entryName)} ${ownFile}.`);
57
+ lines.push(`${pintor.gray('LOADED')} ${pintor.underline(ownFile)}`);
58
+ lines.push(`${pintor.gray('NOT LOADED')} ${extraFiles.map((file)=>pintor.underline(file)).join(', ')}`);
59
+ lines.push(`The entry waits for the other files at runtime and never runs, so ${shape.effect}.`);
60
+ lines.push(`Only a user-set optimization.splitChunks cache group does this. Use chunks: 'async' and import() the shared module: ${pintor.blue(SPLIT_ENTRY_RECIPE_URL)}`);
61
+ return lines.join('\n');
62
+ }
24
63
  function fetchedFileDependencyMissing(assetName, literal, expectedPath) {
25
64
  const lines = [];
26
65
  lines.push(`${assetName} loads '${literal}' at runtime (fetch/XMLHttpRequest/new URL), but the file isn't in the output.`);
@@ -57,4 +96,4 @@ function reservedScriptsFolder(relPath, indicators) {
57
96
  const reasons = indicators.map((r)=>`- ${pintor.gray(r)}`).join('\n');
58
97
  return `${prefix('error')} scripts/ is a reserved folder in Extension.js.\n${pintor.gray('PATH')} ${pintor.underline(relPath)}\nEvery file under ${pintor.blue("scripts/")} is wrapped with the browser content-script mount runtime, so Node.js-only files placed here fail to parse or run.\nThis file looks Node.js-only:\n${reasons}\nRename the folder at the project root (for example ${pintor.blue('bin/')}, ${pintor.blue('tools/')}, or ${pintor.blue('tasks/')}), or move the file out of scripts/.`;
59
98
  }
60
- export { fetchedFileDependencyMissing, getURLDependencyMissing, importScriptsDependencyMissing, injectedFileDependencyMissing, reservedScriptsFolder, runtimeSetSurfaceDependencyMissing, staticImportDependencyMissing };
99
+ export { entrySplitAcrossInitialFiles, fetchedFileDependencyMissing, getURLDependencyMissing, importScriptsDependencyMissing, injectedCompiledSourceLiteral, injectedFileDependencyMissing, reservedScriptsFolder, runtimeSetSurfaceDependencyMissing, staticImportDependencyMissing };
package/dist/372.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import { replaceCssUrlRefs, toPosixPath, htmlStaticAssetOutputName } from "./518.mjs";
2
+ import { htmlStaticAssetOutputName } from "./834.mjs";
3
+ import { replaceCssUrlRefs, toPosixPath } from "./86.mjs";
3
4
  import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
4
5
  import * as __rspack_external_node_path_c5b9b54f from "node:path";
5
6
  const EXTENSION_ROOT_PLACEHOLDER = '__EXTENSIONJS_EXTENSION_ROOT__/';
package/dist/77.mjs CHANGED
@@ -337,6 +337,9 @@ function debugDirs(manifestDir, packageJsonDir) {
337
337
  function debugBrowser(browser, chromiumBinary, geckoBinary) {
338
338
  return `${messaging_prefix('debug')} browser target=${String(browser)} chromiumBinary=${String(chromiumBinary || 'auto')} geckoBinary=${String(geckoBinary || 'auto')}`;
339
339
  }
340
+ function debugSplitChunksNarrowed(optionPaths) {
341
+ return `${messaging_prefix('debug')} chunks narrowed=${optionPaths.join(',')} single-file=background,content_scripts/,scripts/`;
342
+ }
340
343
  function debugOutputPath(pathValue) {
341
344
  return `${messaging_prefix('debug')} output path=${pathValue}`;
342
345
  }
@@ -930,4 +933,4 @@ function actionsPath(projectPath, browser) {
930
933
  function buildSummaryPath(projectPath, browser) {
931
934
  return __rspack_external_node_path_c5b9b54f.join(browserArtifactsDir(projectPath, browser), 'build-summary.json');
932
935
  }
933
- export { actionsPath, anotherDevSessionActive, asAbsolute, authorInstallNotice, browserArtifactsDir, browserDistDir, browserLaunchFailed, browserProfileRootDir, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildSummaryPath, buildWarningsDetails, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, controlPortFilePath, controlTokenPath, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, devCommandFailed, devtoolsEngineFor, downloadingText, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, eventsPath, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, invalidRemoteZip, isUsingExperimentalConfig, legacyControlPortFilePath, legacyControlTokenPath, localZipNotFound, logsPath, managedDependencyConflict, manifestInvalidJson, needsInstall, noCompanionExtensionsResolved, normalizeBrowser, notAZipArchive, packagingDistributionFiles, packagingSourceFiles, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallScriptsDisabled, readyContractPath, resolveProjectStructureSync, sessionArtifactsRootDir, sessionStateDir, starting, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
936
+ export { actionsPath, anotherDevSessionActive, asAbsolute, authorInstallNotice, browserArtifactsDir, browserDistDir, browserLaunchFailed, browserProfileRootDir, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildSummaryPath, buildWarningsDetails, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, controlPortFilePath, controlTokenPath, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, debugSplitChunksNarrowed, devCommandFailed, devtoolsEngineFor, downloadingText, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, eventsPath, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, invalidRemoteZip, isUsingExperimentalConfig, legacyControlPortFilePath, legacyControlTokenPath, localZipNotFound, logsPath, managedDependencyConflict, manifestInvalidJson, needsInstall, noCompanionExtensionsResolved, normalizeBrowser, notAZipArchive, packagingDistributionFiles, packagingSourceFiles, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallScriptsDisabled, readyContractPath, resolveProjectStructureSync, sessionArtifactsRootDir, sessionStateDir, starting, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
@@ -390,45 +390,4 @@ function getBaseNode(htmlDocument) {
390
390
  }
391
391
  }
392
392
  }
393
- const ASSET_EXT = /\.(png|jpe?g|gif|webp|svg|avif|ico|bmp|cur|woff2?|ttf|otf|eot|mp3|mp4|webm|ogg|wav)$/i;
394
- const URL_REF = /url\(\s*(?:"([^"\n]*)"|'([^'\n]*)'|([^)'"\s]*))\s*\)/g;
395
- function toPosixPath(value) {
396
- return String(value).split(__rspack_external_node_path_c5b9b54f.sep).join('/');
397
- }
398
- function isDeadCssUrlRef(rawRequest, { issuerDir, roots }) {
399
- const req = String(rawRequest).split('?')[0].split('#')[0];
400
- if (!req || req.startsWith('//') || /^[a-z][a-z0-9+.-]*:/i.test(req)) return false;
401
- if (req.startsWith('~') || req.startsWith('@')) return false;
402
- const isRootRef = req.startsWith('/');
403
- const isRelativeRef = req.startsWith('./') || req.startsWith('../');
404
- const isBareAssetRef = !isRootRef && !isRelativeRef && ASSET_EXT.test(req);
405
- if (!isRootRef && !isRelativeRef && !isBareAssetRef) return false;
406
- const candidates = isRootRef ? roots.map((root)=>__rspack_external_node_path_c5b9b54f.join(root, req.slice(1))) : [
407
- __rspack_external_node_path_c5b9b54f.resolve(issuerDir, req),
408
- ...isBareAssetRef ? roots.map((root)=>__rspack_external_node_path_c5b9b54f.join(root, req)) : []
409
- ];
410
- return !candidates.some((candidate)=>__rspack_external_node_fs_5ea92f0c.existsSync(candidate));
411
- }
412
- function replaceCssUrlRefs(source, replacer) {
413
- return source.replace(URL_REF, (whole, dq, sq, bare)=>{
414
- const request = dq ?? sq ?? bare ?? '';
415
- if (!request) return whole;
416
- const next = replacer(request);
417
- if (void 0 === next) return whole;
418
- return `url("${next.replace(/["\\]/g, '\\$&')}")`;
419
- });
420
- }
421
- function extractCssUrlRefs(source) {
422
- const found = [];
423
- const seen = new Set();
424
- URL_REF.lastIndex = 0;
425
- let match;
426
- while(null !== (match = URL_REF.exec(source))){
427
- const request = match[1] ?? match[2] ?? match[3] ?? '';
428
- if (!request || seen.has(request)) continue;
429
- seen.add(request);
430
- found.push(request);
431
- }
432
- return found;
433
- }
434
- export { applyRewrittenStaticUrl, cleanAssetUrl, cleanLeading, extractCssUrlRefs, getAssetsFromHtml, getBaseHref, getBaseNode, getExtname, getFilePath, getHtmlPageDeclaredAssetPath, htmlStaticAssetOutputName, iconOutputPath, isDeadCssUrlRef, isFromIncludeList, isHttpLike, isSpecialScheme, manifestJsonOutputTarget, manifestPageOutputTarget, normalizeManifestOutputPath, parseHtml, replaceCssUrlRefs, resolveAbsoluteFsPath, resolveHtmlRefPath, resolveStaticAttributeName, themeIconOutputPath, themeImageOutputPath, toPosixPath, utils_isUrl };
393
+ export { applyRewrittenStaticUrl, cleanAssetUrl, cleanLeading, getAssetsFromHtml, getBaseHref, getBaseNode, getExtname, getFilePath, getHtmlPageDeclaredAssetPath, htmlStaticAssetOutputName, iconOutputPath, isFromIncludeList, isHttpLike, isSpecialScheme, manifestJsonOutputTarget, manifestPageOutputTarget, normalizeManifestOutputPath, parseHtml, resolveAbsoluteFsPath, resolveHtmlRefPath, resolveStaticAttributeName, themeIconOutputPath, themeImageOutputPath, utils_isUrl };