extension-develop 4.1.25 → 4.1.27

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.
@@ -13,11 +13,10 @@ import node_fs from "node:fs";
13
13
  import node_path from "node:path";
14
14
  import { utils_isUrl, getBaseNode, parseHtml, manifestJsonOutputTarget, getExtname, getBaseHref, isResourceUnderDirs, getAssetsFromHtml, normalizeManifestOutputPath, manifestPageOutputTarget, canonicalizeDir, iconOutputPath, isFromIncludeList, htmlStaticAssetOutputName, isSpecialScheme, resolveStaticAttributeName, getHtmlPageDeclaredAssetPath, themeImageOutputPath, themeIconOutputPath, applyRewrittenStaticUrl, toResourceKey, cleanLeading, getFilePath, resolveAbsoluteFsPath, cleanAssetUrl, isHttpLike, resolveHtmlRefPath } from "./938~0.mjs";
15
15
  import { prefix as messaging_prefix, isDebug } from "./852~0.mjs";
16
- import { isChromiumBasedBrowser, CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, isWebkitBasedBrowser, isGeckoBasedBrowser } from "./331~0.mjs";
16
+ import { GECKO_FAMILY_ALIASES, isEmulatorBrowser, isGeckoBasedBrowser, findNearestProjectManifestSync, readProjectDependencies, isChromiumBasedBrowser, CHROMIUM_FAMILY_ALIASES, stripBom, PROJECT_MANIFEST_FILENAMES, parseJsonSafe, isWebkitBasedBrowser } from "./474~0.mjs";
17
17
  import { maybeUsePreact, isUsingTypeScript, jsFrameworksIntegrationsEnabled, maybeUseReact, isUsingVue, classifyEntrySurface, ensureTypeScriptConfig, resolveDevelopInstallRoot, loadLoaderOptions, getUserTypeScriptConfigFile, svelteCompilerRuntimeMismatch, isUsingIntegration as messages_isUsingIntegration, maybeUseVue, maybeUseSolid, jsFrameworksHmrSummary, humanLine, ensureOptionalContractPackageResolved, jsFrameworksConfigsDetected, recordZipArtifact, hasDependency, resolveDevelopDistFile, isUsingJsxFramework, getJsxImportSource, swcParserForFile, isUsingReact, defaultSplitChunks } from "./840~0.mjs";
18
- import { bundlerFatalError, bundlerRecompiling, browserRunnerDisabled, PlaywrightPlugin, publicFolderShadowed, resolveCompanionExtensionDirs, specialFoldersSetupSummary, noEntrypointsDetected, serverRestartRequiredFromSpecialFolderMessageOnly, specialFolderChangeDetected, spacerLine, messages_ready, getPreloadedEnvKeys, publicMustBeAtProjectRoot, computeExtensionsToLoad, getSpecialFoldersDataForCompiler } from "./832~0.mjs";
18
+ import { manifestGoneDuringSession, bundlerFatalError, bundlerRecompiling, browserRunnerDisabled, PlaywrightPlugin, publicFolderShadowed, resolveCompanionExtensionDirs, specialFoldersSetupSummary, noEntrypointsDetected, serverRestartRequiredFromSpecialFolderMessageOnly, specialFolderChangeDetected, spacerLine, messages_ready, getPreloadedEnvKeys, publicMustBeAtProjectRoot, computeExtensionsToLoad, getSpecialFoldersDataForCompiler } from "./832~0.mjs";
19
19
  import { renderStatsBlocks, makeSanitizedConsole } from "./stats-handler~0.mjs";
20
- import { stripBom, findNearestProjectManifestSync, PROJECT_MANIFEST_FILENAMES, parseJsonSafe, readProjectDependencies } from "./731~0.mjs";
21
20
  import { EXTENSIONJS_CONTENT_SCRIPT_LAYER, getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, CONTENT_SCRIPT_CSS_PROBE_MARKER_PREFIX, createContentScriptCssProbeMarkerPattern, getCanonicalContentScriptJsAssetName, getCanonicalContentScriptCssAssetName, isCanonicalContentScriptAsset } from "./640~0.mjs";
22
21
  import { getURLDependencyMissing, findDroppedVendorKeys, isStaticThemeSource, workerStartedFromPageContext, importScriptsDependencyMissing, filterKeysForThisBrowser, findPrefixedManifestVersionKeys, injectedCompiledSourceLiteral, staticImportDependencyMissing, entrySplitAcrossInitialFiles, fetchedFileDependencyMissing, isStaticTheme, compiledSourceSpelling, injectedFileDependencyMissing, isValidManifestVersion, runtimeSetSurfaceDependencyMissing } from "./672~0.mjs";
23
22
  import { packagingSourceFiles, debugBrowser, debugExtensionsToLoad, treeWithSourceFiles, debugOutputPath, manifestInvalidJson, getDirs, asAbsolute, treeWithDistFilesBrowser, packagingDistributionFiles, treeWithSourceAndDistFiles, toPosixPath as paths_toPosixPath, debugContextPath, noCompanionExtensionsResolved } from "./950~0.mjs";
@@ -219,9 +218,21 @@ function setupNoBrowserBannerOnFirstDone(opts) {
219
218
  humanLine(messages_ready('development', opts.browser));
220
219
  });
221
220
  }
222
- function setupCompilerDoneDiagnostics(compiler, port) {
221
+ function setupCompilerDoneDiagnostics(compiler, port, manifestPath) {
223
222
  let reportedNoEntries = false;
223
+ let manifestSeen = false;
224
+ let reportedManifestGone = false;
224
225
  compiler.hooks.done.tap('extension.js:done', (stats)=>{
226
+ const manifestExists = Boolean(manifestPath && __rspack_external_node_fs_1b05aee1.existsSync(manifestPath));
227
+ if (manifestExists) manifestSeen = true;
228
+ if (manifestPath && manifestSeen && !manifestExists) {
229
+ if (!reportedManifestGone) {
230
+ reportedManifestGone = true;
231
+ console.error(manifestGoneDuringSession(manifestPath, !__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.dirname(manifestPath))));
232
+ }
233
+ return;
234
+ }
235
+ reportedManifestGone = false;
225
236
  try {
226
237
  if (stats?.hasErrors?.()) {
227
238
  const str = renderStatsBlocks(stats, {
@@ -1966,7 +1977,7 @@ class CompilationPlugin {
1966
1977
  manifestPath: this.manifestPath,
1967
1978
  browser: this.browser || 'chrome'
1968
1979
  }).apply(compiler);
1969
- if ('build' !== this.command && 'start' !== this.command) setupCompilerDoneDiagnostics(compiler, this.port);
1980
+ if ('build' !== this.command && 'start' !== this.command) setupCompilerDoneDiagnostics(compiler, this.port, this.manifestPath);
1970
1981
  }
1971
1982
  }
1972
1983
  let userMessageDelivered = false;
@@ -7041,9 +7052,11 @@ class ReloadPlugin {
7041
7052
  browser: this.browser
7042
7053
  }).apply(compiler);
7043
7054
  new InjectScriptsReplayShim().apply(compiler);
7044
- if (isChromiumBasedBrowser(String(this.browser))) new SetupDevContentScripts().apply(compiler);
7045
- new InjectBridgeProducer().apply(compiler);
7046
- new InjectBridgeRelay().apply(compiler);
7055
+ if (isChromiumBasedBrowser(String(this.browser)) && !isEmulatorBrowser(this.browser)) new SetupDevContentScripts().apply(compiler);
7056
+ if (!isEmulatorBrowser(this.browser)) {
7057
+ new InjectBridgeProducer().apply(compiler);
7058
+ new InjectBridgeRelay().apply(compiler);
7059
+ }
7047
7060
  new PruneStaleHotUpdates().apply(compiler);
7048
7061
  }
7049
7062
  }
@@ -7109,6 +7122,100 @@ function classicConcatEntry(feature, jsFiles) {
7109
7122
  return `${deduped[0]}?__extensionjs_classic_concat__=${queryData}`;
7110
7123
  }
7111
7124
  const EMITTED_WORKER_PATH = 'background/service_worker.js';
7125
+ const STANDARD_MANIFEST_KEYS = new Set([
7126
+ 'action',
7127
+ 'app',
7128
+ 'applications',
7129
+ 'author',
7130
+ 'automation',
7131
+ 'background',
7132
+ 'bluetooth',
7133
+ 'browser_action',
7134
+ 'browser_specific_settings',
7135
+ 'chrome_settings_overrides',
7136
+ 'chrome_url_overrides',
7137
+ 'commands',
7138
+ 'content_capabilities',
7139
+ "content_scripts",
7140
+ 'content_security_policy',
7141
+ "converted_from_user_script",
7142
+ 'cross_origin_embedder_policy',
7143
+ 'cross_origin_opener_policy',
7144
+ 'current_locale',
7145
+ 'declarative_net_request',
7146
+ 'default_locale',
7147
+ "description",
7148
+ 'developer',
7149
+ 'devtools_page',
7150
+ 'dictionaries',
7151
+ 'differential_fingerprint',
7152
+ 'display_in_launcher',
7153
+ 'display_in_new_tab_page',
7154
+ 'event_rules',
7155
+ 'export',
7156
+ 'externally_connectable',
7157
+ 'file_browser_handlers',
7158
+ 'file_system_provider_capabilities',
7159
+ 'homepage_url',
7160
+ 'host_permissions',
7161
+ 'icon_variants',
7162
+ 'icons',
7163
+ 'import',
7164
+ 'incognito',
7165
+ 'input_components',
7166
+ 'key',
7167
+ 'kiosk',
7168
+ 'kiosk_enabled',
7169
+ 'kiosk_only',
7170
+ 'l10n',
7171
+ 'manifest_version',
7172
+ 'minimum_chrome_version',
7173
+ 'minimum_edge_version',
7174
+ 'minimum_opera_version',
7175
+ 'nacl_modules',
7176
+ 'name',
7177
+ 'oauth2',
7178
+ 'offline_enabled',
7179
+ 'omnibox',
7180
+ 'optional_host_permissions',
7181
+ 'optional_permissions',
7182
+ 'options_page',
7183
+ 'options_ui',
7184
+ 'page_action',
7185
+ 'permissions',
7186
+ 'platforms',
7187
+ 'protocol_handlers',
7188
+ 'replacement_web_app',
7189
+ 'requirements',
7190
+ 'sandbox',
7191
+ 'short_name',
7192
+ 'side_panel',
7193
+ 'sidebar_action',
7194
+ 'signature',
7195
+ 'sockets',
7196
+ 'storage',
7197
+ 'system_indicator',
7198
+ 'theme',
7199
+ 'theme_experiment',
7200
+ 'trial_tokens',
7201
+ 'tts_engine',
7202
+ 'update_url',
7203
+ 'url_handlers',
7204
+ 'usb_printers',
7205
+ "user_scripts",
7206
+ 'version',
7207
+ 'version_name',
7208
+ 'web_accessible_resources',
7209
+ 'webview'
7210
+ ]);
7211
+ const STANDARD_BACKGROUND_KEYS = new Set([
7212
+ 'page',
7213
+ 'persistent',
7214
+ 'preferred_environment',
7215
+ "scripts",
7216
+ 'service_worker',
7217
+ 'type'
7218
+ ]);
7112
7219
  const MAX_TRACE_DEPTH = 8;
7113
7220
  const SOURCE_SIBLING_EXTENSIONS = [
7114
7221
  '.ts',
@@ -7165,6 +7272,7 @@ class TraceRuntimeLoadedFiles {
7165
7272
  const run = new TraceRun(compilation, compiler, __rspack_external_node_path_806ed179.dirname(this.manifestPath));
7166
7273
  let only;
7167
7274
  for(let round = 0; round <= MAX_TRACE_DEPTH; round++){
7275
+ if (!only) this.traceManifestNamedFiles(run);
7168
7276
  this.traceWorkerImportScripts(run, only);
7169
7277
  this.traceInjectedFilePayloads(run, only);
7170
7278
  this.traceFetchedFiles(run, only);
@@ -7184,6 +7292,30 @@ class TraceRuntimeLoadedFiles {
7184
7292
  return;
7185
7293
  }
7186
7294
  }
7295
+ traceManifestNamedFiles(run) {
7296
+ const manifest = this.readManifest();
7297
+ if (!manifest) return;
7298
+ const seen = run.seen.getURL;
7299
+ for (const literal of customManifestFileReferences(manifest)){
7300
+ const distRel = resolveExtensionPath(literal, '');
7301
+ if (!distRel || seen.has(distRel)) continue;
7302
+ const plan = planTracedFile({
7303
+ manifestDir: run.manifestDir,
7304
+ sourceRel: distRel,
7305
+ distRel,
7306
+ loadsAs: 'by-shape',
7307
+ hasAsset: run.hasAsset
7308
+ });
7309
+ if ('missing' !== plan.kind) {
7310
+ seen.add(distRel);
7311
+ run.apply(plan, {
7312
+ context: 'getURL',
7313
+ onMissing: ()=>{},
7314
+ onSourceSpelling: ()=>{}
7315
+ });
7316
+ }
7317
+ }
7318
+ }
7187
7319
  traceWorkerImportScripts(run, only) {
7188
7320
  const manifest = this.readManifest();
7189
7321
  const workerRef = manifest?.background?.service_worker;
@@ -7738,6 +7870,28 @@ function manifestDeclaredSourcePaths(manifest) {
7738
7870
  for (const page of Object.values(manifest.chrome_url_overrides ?? {}))add(page);
7739
7871
  return declared;
7740
7872
  }
7873
+ function customManifestFileReferences(manifest) {
7874
+ const refs = [];
7875
+ const collect = (value)=>{
7876
+ if ('string' == typeof value) {
7877
+ const trimmed = value.trim();
7878
+ if (/\.[a-zA-Z0-9]{1,8}$/.test(trimmed) && !/\s/.test(trimmed)) refs.push(trimmed);
7879
+ return;
7880
+ }
7881
+ if (Array.isArray(value)) return void value.forEach(collect);
7882
+ if (value && 'object' == typeof value) Object.values(value).forEach(collect);
7883
+ };
7884
+ for (const [key, value] of Object.entries(manifest)){
7885
+ if (!STANDARD_MANIFEST_KEYS.has(key)) {
7886
+ collect(value);
7887
+ continue;
7888
+ }
7889
+ if ('background' === key && value && 'object' == typeof value) {
7890
+ for (const [subKey, subValue] of Object.entries(value))if (!STANDARD_BACKGROUND_KEYS.has(subKey)) collect(subValue);
7891
+ }
7892
+ }
7893
+ return refs;
7894
+ }
7741
7895
  function extractGetURLLiterals(source) {
7742
7896
  const code = blankComments(source);
7743
7897
  const literals = [];
@@ -8645,6 +8799,21 @@ class WasmPlugin {
8645
8799
  this.ensureWasmResolution(compiler, projectRoot);
8646
8800
  }
8647
8801
  }
8802
+ function filesOf(value) {
8803
+ if (Array.isArray(value)) return value;
8804
+ return value ? [
8805
+ value
8806
+ ] : [];
8807
+ }
8808
+ function omitOwnedPages(pages, owned) {
8809
+ const ownedFiles = new Set(Object.values(owned).flatMap(filesOf).map((file)=>__rspack_external_node_path_806ed179.resolve(file)));
8810
+ const next = {};
8811
+ for (const [name, value] of Object.entries(pages || {})){
8812
+ const files = filesOf(value);
8813
+ if (!(files.length > 0 && files.every((file)=>ownedFiles.has(__rspack_external_node_path_806ed179.resolve(file))))) next[name] = value;
8814
+ }
8815
+ return next;
8816
+ }
8648
8817
  const COMPILED_SIBLING_EXTENSIONS = [
8649
8818
  '.ts',
8650
8819
  '.mts',
@@ -8677,7 +8846,7 @@ function javaScriptError(errorSourcePath, missingFilePath, opts) {
8677
8846
  lines.push("The page references a script file that doesn't exist.");
8678
8847
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8679
8848
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
8680
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.blue('public/')}), not your source directory.`);
8849
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.blue('public/')}.`);
8681
8850
  if (opts?.deadRefHint) lines.push("The build ships an empty placeholder for this script, so the page loads and no 404 appears in DevTools (likely dead code).");
8682
8851
  lines.push(`Update the ${pintor.blue("<script>")} src to point to a file that exists.`);
8683
8852
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -8688,7 +8857,7 @@ function cssError(errorSourcePath, missingFilePath, opts) {
8688
8857
  lines.push("The page references a stylesheet that doesn't exist.");
8689
8858
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8690
8859
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
8691
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.blue('public/')}), not your source directory.`);
8860
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.blue('public/')}.`);
8692
8861
  if (opts?.deadRefHint) lines.push("Chrome loads the page anyway and 404s this reference silently, so it is likely dead code.");
8693
8862
  lines.push(`Update the ${pintor.blue('<link>')} href to point to a file that exists.`);
8694
8863
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -8701,7 +8870,7 @@ function staticAssetError(errorSourcePath, missingFilePath, opts) {
8701
8870
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8702
8871
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
8703
8872
  const ref = opts?.refLabel || `*${extname}`;
8704
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.blue('public/')}), not your source directory.`);
8873
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.blue('public/')}.`);
8705
8874
  if (opts?.deadRefHint) lines.push("Chrome loads the page anyway and 404s this reference silently, so it is likely dead code.");
8706
8875
  lines.push(`Update the ${pintor.blue(ref)} reference to point to a file that exists.`);
8707
8876
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -9055,7 +9224,7 @@ function warnMissingPublicRootResources(params) {
9055
9224
  if (resolveRootAbsoluteRef(publicRootUrl, manifestDir, publicRootForResource) || resolveRootAbsoluteRef(publicRootUrl, projectRoot, publicRootForResource)) return;
9056
9225
  if (findCompiledRootRefSource(publicRootUrl, manifestDir, publicRootForResource) || findCompiledRootRefSource(publicRootUrl, projectRoot, publicRootForResource)) return;
9057
9226
  if (!__rspack_external_node_fs_1b05aee1.existsSync(publicRootAbs) && !__rspack_external_node_fs_1b05aee1.existsSync(outputRootAssetAbs)) {
9058
- const displayPath = __rspack_external_node_path_806ed179.join(outputRoot, trimmed);
9227
+ const displayPath = __rspack_external_node_path_806ed179.join(manifestDir, trimmed);
9059
9228
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
9060
9229
  publicRootHint: true,
9061
9230
  refLabel: publicRootUrl
@@ -9187,7 +9356,7 @@ class AddAssetsToCompilation {
9187
9356
  if (!__rspack_external_node_fs_1b05aee1.existsSync(absoluteFsPath)) {
9188
9357
  const inIncludeList = isFromIncludeList(asset, this.includeList);
9189
9358
  if (!inIncludeList && !__rspack_external_node_path_806ed179.basename(asset).startsWith('#')) {
9190
- const displayPath = isRootUrl ? __rspack_external_node_path_806ed179.join(outputRoot, cleanLeading(asset)) : absoluteFsPath;
9359
+ const displayPath = isRootUrl ? __rspack_external_node_path_806ed179.join(manifestDir, cleanLeading(asset)) : absoluteFsPath;
9191
9360
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
9192
9361
  publicRootHint: isRootUrl,
9193
9362
  refLabel: asset
@@ -9204,25 +9373,25 @@ class AddAssetsToCompilation {
9204
9373
  const filepath = htmlStaticAssetOutputName(manifestDir, resource, absoluteFsPath);
9205
9374
  const isNestedHtml = asset.endsWith('.html');
9206
9375
  const nestedHtmlAsset = isNestedHtml ? 'function' == typeof getAssetFn ? getAssetFn.call(compilation, __rspack_external_node_path_806ed179.basename(asset)) : null : null;
9207
- if (!isFromIncludeList(asset, this.includeList) || nestedHtmlAsset) {
9208
- if (!('function' == typeof getAssetFn && getAssetFn.call(compilation, filepath))) if (asset.endsWith('.html')) emitNestedHtmlAndReferencedAssets({
9209
- compilation,
9210
- filepath,
9211
- absoluteFsPath,
9212
- manifestDir
9213
- });
9214
- else {
9215
- const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9216
- compilation.emitAsset(filepath, new core_sources.RawSource(source));
9217
- }
9218
- if (!isNestedHtml && __rspack_external_node_fs_1b05aee1.existsSync(absoluteFsPath)) {
9219
- const manifestRelative = __rspack_external_node_path_806ed179.relative(manifestDir, absoluteFsPath);
9220
- if (manifestRelative && !manifestRelative.startsWith('..') && !__rspack_external_node_path_806ed179.isAbsolute(manifestRelative)) {
9221
- const sourcePathAsset = manifestRelative.split(__rspack_external_node_path_806ed179.sep).join('/');
9222
- if (sourcePathAsset !== filepath && !('function' == typeof getAssetFn && getAssetFn.call(compilation, sourcePathAsset))) {
9223
- const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9224
- compilation.emitAsset(sourcePathAsset, new core_sources.RawSource(source));
9225
- }
9376
+ if (isFromIncludeList(asset, this.includeList) && !nestedHtmlAsset) continue;
9377
+ const reachableUnderAssets = isNestedHtml || !isRootUrl;
9378
+ if (reachableUnderAssets && !('function' == typeof getAssetFn && getAssetFn.call(compilation, filepath))) if (asset.endsWith('.html')) emitNestedHtmlAndReferencedAssets({
9379
+ compilation,
9380
+ filepath,
9381
+ absoluteFsPath,
9382
+ manifestDir
9383
+ });
9384
+ else {
9385
+ const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9386
+ compilation.emitAsset(filepath, new core_sources.RawSource(source));
9387
+ }
9388
+ if (!isNestedHtml && __rspack_external_node_fs_1b05aee1.existsSync(absoluteFsPath)) {
9389
+ const manifestRelative = __rspack_external_node_path_806ed179.relative(manifestDir, absoluteFsPath);
9390
+ if (manifestRelative && !manifestRelative.startsWith('..') && !__rspack_external_node_path_806ed179.isAbsolute(manifestRelative)) {
9391
+ const sourcePathAsset = manifestRelative.split(__rspack_external_node_path_806ed179.sep).join('/');
9392
+ if (sourcePathAsset !== filepath && !('function' == typeof getAssetFn && getAssetFn.call(compilation, sourcePathAsset))) {
9393
+ const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9394
+ compilation.emitAsset(sourcePathAsset, new core_sources.RawSource(source));
9226
9395
  }
9227
9396
  }
9228
9397
  }
@@ -9547,8 +9716,7 @@ function handleCantResolveError(includesList, error, compilation, manifestDir) {
9547
9716
  break;
9548
9717
  }
9549
9718
  }
9550
- const outputRoot = compilation?.options?.output?.path || '';
9551
- const overrideNotFoundPath = isPublicRoot ? __rspack_external_node_path_806ed179.join(outputRoot, String(matchedRawAttr || base).replace(/^\//, '')) : matchedRawAttr && !matchedRawAttr.startsWith('/') ? __rspack_external_node_path_806ed179.join(dir, matchedRawAttr) : wrongFilename;
9719
+ const overrideNotFoundPath = isPublicRoot ? __rspack_external_node_path_806ed179.join(manifestDir, String(matchedRawAttr || base).replace(/^\//, '')) : matchedRawAttr && !matchedRawAttr.startsWith('/') ? __rspack_external_node_path_806ed179.join(dir, matchedRawAttr) : wrongFilename;
9552
9720
  const errorMsg = fileNotFound(resource, overrideNotFoundPath || wrongFilename, {
9553
9721
  publicRootHint: isPublicRoot
9554
9722
  });
@@ -9869,7 +10037,7 @@ function iconsMissingFile(manifestField, filePath, opts) {
9869
10037
  lines.push(`Can't find an icon file listed in ${pintor.blue(manifestField)}.`);
9870
10038
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(filePath)}`);
9871
10039
  lines.push(opts?.fatal ? `Browsers reject the whole extension when this file is missing.\nThe build stops here.` : `Browsers can reject or misrender the extension when this file is missing.\nThe build continues.`);
9872
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.blue('public/')}), not your source directory.`);
10040
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.blue('public/')}.`);
9873
10041
  lines.push(`Update the icon path in your ${pintor.blue('manifest.json')} to a file that ships with the extension.`);
9874
10042
  return lines.join('\n');
9875
10043
  }
@@ -9878,7 +10046,7 @@ function themeImageMissingFile(manifestField, filePath, opts) {
9878
10046
  lines.push(`Check the ${pintor.yellow(manifestField)} field in your ${pintor.yellow('manifest.json')} file.`);
9879
10047
  lines.push("The theme image path must point to an existing file that will be packaged with the extension.");
9880
10048
  lines.push(`Browsers reject the whole extension when this file is missing.\nThe build stops here to protect you.`);
9881
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
10049
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.yellow('public/')}.`);
9882
10050
  lines.push('');
9883
10051
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(filePath)}`);
9884
10052
  return lines.join('\n');
@@ -10046,7 +10214,7 @@ class EmitFile {
10046
10214
  const isThemeImage = 'theme' === group && 'images' === sub;
10047
10215
  if (!__rspack_external_node_fs_1b05aee1.existsSync(resolved)) {
10048
10216
  const isPublicRoot = entry.startsWith('/') && !entry.startsWith(projectPath);
10049
- const displayPath = !__rspack_external_node_path_806ed179.isAbsolute(entry) && isPublicRoot ? __rspack_external_node_path_806ed179.join(projectPath, 'public', entry.slice(1)) : __rspack_external_node_path_806ed179.isAbsolute(entry) ? entry : __rspack_external_node_path_806ed179.join(projectPath, entry);
10217
+ const displayPath = !__rspack_external_node_path_806ed179.isAbsolute(entry) && isPublicRoot ? __rspack_external_node_path_806ed179.join(projectPath, entry.slice(1)) : __rspack_external_node_path_806ed179.isAbsolute(entry) ? entry : __rspack_external_node_path_806ed179.join(projectPath, entry);
10050
10218
  const isFatal = 'icons' === group || isDefaultIconFamily || isThemeImage;
10051
10219
  const severity = isFatal ? 'error' : 'warning';
10052
10220
  reportToCompilation(compilation, compiler, isThemeImage ? themeImageMissingFile(feature, displayPath, {
@@ -10179,7 +10347,7 @@ function jsonMissingFile(manifestField, filePath, opts) {
10179
10347
  lines.push(`Can't find the JSON file listed in ${pintor.blue(manifestField)}.`);
10180
10348
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(filePath)}`);
10181
10349
  lines.push(opts?.fatal ? `Browsers can reject or crash the extension when required JSON files like rulesets are missing.\nThe build stops here.` : `Browsers can reject or misread the extension when this file is missing.\nThe build continues.`);
10182
- if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.blue('public/')}), not your source directory.`);
10350
+ if (opts?.publicRootHint) lines.push(`A path starting with '/' resolves from the extension root, so the file must sit at that path in your project or in ${pintor.blue('public/')}.`);
10183
10351
  lines.push(`Update the JSON path in your ${pintor.blue('manifest.json')} to a file that ships with the extension.`);
10184
10352
  return lines.join('\n');
10185
10353
  }
@@ -10356,7 +10524,7 @@ function processJsonAssets(compilation, manifestPath, includeList) {
10356
10524
  const jsonFields = includeList || {};
10357
10525
  const manifestDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
10358
10526
  const projectPath = getProjectPathFromCompilation(compilation, manifestPath);
10359
- const publicDir = __rspack_external_node_path_806ed179.join(projectPath, 'public');
10527
+ __rspack_external_node_path_806ed179.join(projectPath, 'public');
10360
10528
  if (isDebug()) {
10361
10529
  const featureKeys = Object.keys(jsonFields || {});
10362
10530
  const criticalCount = featureKeys.filter((key)=>isCriticalJsonFeature(key)).length;
@@ -10375,8 +10543,7 @@ function processJsonAssets(compilation, manifestPath, includeList) {
10375
10543
  for (const thisResource of resourceArr)if (thisResource) {
10376
10544
  const { abs, isUnderPublic, isPublicRoot } = resolveJsonResource(thisResource, manifestDir, projectPath);
10377
10545
  if (!__rspack_external_node_fs_1b05aee1.existsSync(abs)) {
10378
- const outputRoot = compilation?.options?.output?.path || '';
10379
- const displayPath = isPublicRoot ? __rspack_external_node_path_806ed179.join(outputRoot || publicDir, String(thisResource).slice(1)) : abs;
10546
+ const displayPath = abs;
10380
10547
  const isFatal = isCriticalJsonFeature(feature);
10381
10548
  const notFound = new core_WebpackError(jsonMissingFile(feature, displayPath, {
10382
10549
  publicRootHint: isPublicRoot,
@@ -14990,15 +15157,18 @@ class plugin_web_extension_WebExtensionPlugin {
14990
15157
  ...manifestFieldsData.scripts
14991
15158
  }
14992
15159
  }).apply(compiler);
15160
+ const ownedPages = {
15161
+ ...manifestFieldsData.html,
15162
+ ...discoverDevtoolsPanelPages(manifestPath, this.browser),
15163
+ ...settingsOverridesStartupPages(manifestPath, this.browser)
15164
+ };
14993
15165
  new HtmlPlugin({
14994
15166
  devSession: this.devSession,
14995
15167
  manifestPath,
14996
15168
  browser: this.browser,
14997
15169
  includeList: {
14998
- ...manifestFieldsData.html,
14999
- ...discoverDevtoolsPanelPages(manifestPath, this.browser),
15000
- ...settingsOverridesStartupPages(manifestPath, this.browser),
15001
- ...specialFoldersData.pages
15170
+ ...ownedPages,
15171
+ ...omitOwnedPages(specialFoldersData.pages, ownedPages)
15002
15172
  }
15003
15173
  }).apply(compiler);
15004
15174
  new ScriptsPlugin({
@@ -15393,7 +15563,7 @@ function webpackConfig(projectStructure, devOptions) {
15393
15563
  },
15394
15564
  optimization: {
15395
15565
  emitOnErrors: false,
15396
- minimize: 'production' === devOptions.mode,
15566
+ minimize: 'production' === devOptions.mode && false !== devOptions.minify,
15397
15567
  minimizer: [
15398
15568
  new SwcJsMinimizerRspackPlugin(),
15399
15569
  new LightningCssMinimizerRspackPlugin({
package/dist/types.d.ts CHANGED
@@ -65,7 +65,7 @@ export interface JsFramework {
65
65
  import type { Configuration } from '@rspack/core';
66
66
  import type { SafariPackageSummary } from './lib/build-summary.js';
67
67
  import type { CompanionExtensionsConfig } from './plugin-special-folders/folder-extensions/types.js';
68
- export type BrowserType = 'chrome' | 'edge' | 'firefox' | 'chromium' | 'brave' | 'opera' | 'vivaldi' | 'yandex' | 'waterfox' | 'librewolf' | 'chromium-based' | 'gecko-based' | 'firefox-based' | 'safari' | 'webkit-based';
68
+ export type BrowserType = 'chrome' | 'edge' | 'firefox' | 'chromium' | 'brave' | 'opera' | 'vivaldi' | 'yandex' | 'waterfox' | 'librewolf' | 'zen' | 'floorp' | 'chromium-based' | 'gecko-based' | 'firefox-based' | 'safari' | 'webkit-based' | 'chromium-emulator';
69
69
  export interface BrowserOptionsBase {
70
70
  noOpen?: boolean;
71
71
  profile?: string | false;
@@ -215,6 +215,11 @@ export interface BuildOptions {
215
215
  * Needs `addons-linter` installed in the project. Defaults to `true`.
216
216
  */
217
217
  addonLint?: boolean;
218
+ /**
219
+ * Minify first-party code in production builds. Defaults to `true` for
220
+ * every target but `opera`, whose store reviews readable source only.
221
+ */
222
+ minify?: boolean;
218
223
  /**
219
224
  * Override the bundler mode (and NODE_ENV). Defaults to 'production' to
220
225
  * preserve historical behavior. Setting 'development' is useful for
@@ -447,7 +452,7 @@ export interface FileConfig {
447
452
  extensions?: CompanionExtensionsConfig;
448
453
  transpilePackages?: string[];
449
454
  };
450
- build?: Pick<BuildOptions, 'browser' | 'zipFilename' | 'zip' | 'zipSource' | 'polyfill' | 'silent' | 'addonLint' | 'safariBinary' | 'appName' | 'bundleId' | 'macOsOnly'> & {
455
+ build?: Pick<BuildOptions, 'browser' | 'zipFilename' | 'zip' | 'zipSource' | 'polyfill' | 'silent' | 'addonLint' | 'minify' | 'safariBinary' | 'appName' | 'bundleId' | 'macOsOnly'> & {
451
456
  extensions?: CompanionExtensionsConfig;
452
457
  transpilePackages?: string[];
453
458
  perfBudgets?: PerfBudgetsConfig;
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "runtime"
44
44
  ],
45
45
  "name": "extension-develop",
46
- "version": "4.1.25",
46
+ "version": "4.1.27",
47
47
  "description": "Develop, build, preview, and package Extension.js projects.",
48
48
  "author": {
49
49
  "name": "Cezar Augusto",
@@ -51,6 +51,7 @@
51
51
  "url": "https://cezaraugusto.com"
52
52
  },
53
53
  "homepage": "https://github.com/extension-js/extension.js/tree/main/programs/develop#readme",
54
+ "funding": "https://github.com/sponsors/cezaraugusto",
54
55
  "bugs": {
55
56
  "url": "https://github.com/extension-js/extension.js/issues"
56
57
  },
@@ -99,11 +100,11 @@
99
100
  "@rspack/plugin-react-refresh": "2.0.2",
100
101
  "@vue/compiler-sfc": "3.5.26",
101
102
  "acorn": "^8.16.0",
102
- "browser-extension-manifest-fields": "^3.0.1",
103
+ "browser-extension-manifest-fields": "^3.0.2",
103
104
  "case-sensitive-paths-webpack-plugin": "^2.4.0",
104
105
  "content-security-policy-parser": "^0.6.0",
105
106
  "cross-spawn": "^7.0.6",
106
- "dotenv": "^17.2.3",
107
+ "dotenv": "^18.0.0",
107
108
  "es-module-lexer": "^3.0.2",
108
109
  "extension-from-store": "^0.2.5",
109
110
  "fflate": "^0.8.3",
package/dist/331~0.mjs DELETED
@@ -1,43 +0,0 @@
1
- import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import * as __rspack_external_node_path_806ed179 from "node:path";
3
- __rspack_external_node_path_806ed179.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
4
- const CHROMIUM_BASED_BROWSERS = [
5
- 'chrome',
6
- 'edge',
7
- 'brave',
8
- 'opera',
9
- 'vivaldi',
10
- 'yandex'
11
- ];
12
- const GECKO_BASED_BROWSERS = [
13
- 'firefox',
14
- 'waterfox',
15
- 'librewolf'
16
- ];
17
- const WEBKIT_BASED_BROWSERS = [
18
- 'safari'
19
- ];
20
- const CHROMIUM_FAMILY_ALIASES = [
21
- 'chromium',
22
- 'chrome',
23
- 'edge',
24
- 'chromium-based'
25
- ];
26
- const GECKO_FAMILY_ALIASES = [
27
- 'firefox',
28
- 'gecko-based'
29
- ];
30
- [
31
- ...CHROMIUM_BASED_BROWSERS,
32
- ...GECKO_BASED_BROWSERS
33
- ];
34
- function isChromiumBasedBrowser(browser) {
35
- return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
36
- }
37
- function isGeckoBasedBrowser(browser) {
38
- return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
39
- }
40
- function isWebkitBasedBrowser(browser) {
41
- return WEBKIT_BASED_BROWSERS.includes(browser) || String(browser).includes('webkit');
42
- }
43
- export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, isChromiumBasedBrowser, isGeckoBasedBrowser, isWebkitBasedBrowser };