extension-develop 4.1.25 → 4.1.26

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
18
  import { 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";
@@ -7041,9 +7040,11 @@ class ReloadPlugin {
7041
7040
  browser: this.browser
7042
7041
  }).apply(compiler);
7043
7042
  new InjectScriptsReplayShim().apply(compiler);
7044
- if (isChromiumBasedBrowser(String(this.browser))) new SetupDevContentScripts().apply(compiler);
7045
- new InjectBridgeProducer().apply(compiler);
7046
- new InjectBridgeRelay().apply(compiler);
7043
+ if (isChromiumBasedBrowser(String(this.browser)) && !isEmulatorBrowser(this.browser)) new SetupDevContentScripts().apply(compiler);
7044
+ if (!isEmulatorBrowser(this.browser)) {
7045
+ new InjectBridgeProducer().apply(compiler);
7046
+ new InjectBridgeRelay().apply(compiler);
7047
+ }
7047
7048
  new PruneStaleHotUpdates().apply(compiler);
7048
7049
  }
7049
7050
  }
@@ -7109,6 +7110,100 @@ function classicConcatEntry(feature, jsFiles) {
7109
7110
  return `${deduped[0]}?__extensionjs_classic_concat__=${queryData}`;
7110
7111
  }
7111
7112
  const EMITTED_WORKER_PATH = 'background/service_worker.js';
7113
+ const STANDARD_MANIFEST_KEYS = new Set([
7114
+ 'action',
7115
+ 'app',
7116
+ 'applications',
7117
+ 'author',
7118
+ 'automation',
7119
+ 'background',
7120
+ 'bluetooth',
7121
+ 'browser_action',
7122
+ 'browser_specific_settings',
7123
+ 'chrome_settings_overrides',
7124
+ 'chrome_url_overrides',
7125
+ 'commands',
7126
+ 'content_capabilities',
7127
+ "content_scripts",
7128
+ 'content_security_policy',
7129
+ "converted_from_user_script",
7130
+ 'cross_origin_embedder_policy',
7131
+ 'cross_origin_opener_policy',
7132
+ 'current_locale',
7133
+ 'declarative_net_request',
7134
+ 'default_locale',
7135
+ "description",
7136
+ 'developer',
7137
+ 'devtools_page',
7138
+ 'dictionaries',
7139
+ 'differential_fingerprint',
7140
+ 'display_in_launcher',
7141
+ 'display_in_new_tab_page',
7142
+ 'event_rules',
7143
+ 'export',
7144
+ 'externally_connectable',
7145
+ 'file_browser_handlers',
7146
+ 'file_system_provider_capabilities',
7147
+ 'homepage_url',
7148
+ 'host_permissions',
7149
+ 'icon_variants',
7150
+ 'icons',
7151
+ 'import',
7152
+ 'incognito',
7153
+ 'input_components',
7154
+ 'key',
7155
+ 'kiosk',
7156
+ 'kiosk_enabled',
7157
+ 'kiosk_only',
7158
+ 'l10n',
7159
+ 'manifest_version',
7160
+ 'minimum_chrome_version',
7161
+ 'minimum_edge_version',
7162
+ 'minimum_opera_version',
7163
+ 'nacl_modules',
7164
+ 'name',
7165
+ 'oauth2',
7166
+ 'offline_enabled',
7167
+ 'omnibox',
7168
+ 'optional_host_permissions',
7169
+ 'optional_permissions',
7170
+ 'options_page',
7171
+ 'options_ui',
7172
+ 'page_action',
7173
+ 'permissions',
7174
+ 'platforms',
7175
+ 'protocol_handlers',
7176
+ 'replacement_web_app',
7177
+ 'requirements',
7178
+ 'sandbox',
7179
+ 'short_name',
7180
+ 'side_panel',
7181
+ 'sidebar_action',
7182
+ 'signature',
7183
+ 'sockets',
7184
+ 'storage',
7185
+ 'system_indicator',
7186
+ 'theme',
7187
+ 'theme_experiment',
7188
+ 'trial_tokens',
7189
+ 'tts_engine',
7190
+ 'update_url',
7191
+ 'url_handlers',
7192
+ 'usb_printers',
7193
+ "user_scripts",
7194
+ 'version',
7195
+ 'version_name',
7196
+ 'web_accessible_resources',
7197
+ 'webview'
7198
+ ]);
7199
+ const STANDARD_BACKGROUND_KEYS = new Set([
7200
+ 'page',
7201
+ 'persistent',
7202
+ 'preferred_environment',
7203
+ "scripts",
7204
+ 'service_worker',
7205
+ 'type'
7206
+ ]);
7112
7207
  const MAX_TRACE_DEPTH = 8;
7113
7208
  const SOURCE_SIBLING_EXTENSIONS = [
7114
7209
  '.ts',
@@ -7165,6 +7260,7 @@ class TraceRuntimeLoadedFiles {
7165
7260
  const run = new TraceRun(compilation, compiler, __rspack_external_node_path_806ed179.dirname(this.manifestPath));
7166
7261
  let only;
7167
7262
  for(let round = 0; round <= MAX_TRACE_DEPTH; round++){
7263
+ if (!only) this.traceManifestNamedFiles(run);
7168
7264
  this.traceWorkerImportScripts(run, only);
7169
7265
  this.traceInjectedFilePayloads(run, only);
7170
7266
  this.traceFetchedFiles(run, only);
@@ -7184,6 +7280,30 @@ class TraceRuntimeLoadedFiles {
7184
7280
  return;
7185
7281
  }
7186
7282
  }
7283
+ traceManifestNamedFiles(run) {
7284
+ const manifest = this.readManifest();
7285
+ if (!manifest) return;
7286
+ const seen = run.seen.getURL;
7287
+ for (const literal of customManifestFileReferences(manifest)){
7288
+ const distRel = resolveExtensionPath(literal, '');
7289
+ if (!distRel || seen.has(distRel)) continue;
7290
+ const plan = planTracedFile({
7291
+ manifestDir: run.manifestDir,
7292
+ sourceRel: distRel,
7293
+ distRel,
7294
+ loadsAs: 'by-shape',
7295
+ hasAsset: run.hasAsset
7296
+ });
7297
+ if ('missing' !== plan.kind) {
7298
+ seen.add(distRel);
7299
+ run.apply(plan, {
7300
+ context: 'getURL',
7301
+ onMissing: ()=>{},
7302
+ onSourceSpelling: ()=>{}
7303
+ });
7304
+ }
7305
+ }
7306
+ }
7187
7307
  traceWorkerImportScripts(run, only) {
7188
7308
  const manifest = this.readManifest();
7189
7309
  const workerRef = manifest?.background?.service_worker;
@@ -7738,6 +7858,28 @@ function manifestDeclaredSourcePaths(manifest) {
7738
7858
  for (const page of Object.values(manifest.chrome_url_overrides ?? {}))add(page);
7739
7859
  return declared;
7740
7860
  }
7861
+ function customManifestFileReferences(manifest) {
7862
+ const refs = [];
7863
+ const collect = (value)=>{
7864
+ if ('string' == typeof value) {
7865
+ const trimmed = value.trim();
7866
+ if (/\.[a-zA-Z0-9]{1,8}$/.test(trimmed) && !/\s/.test(trimmed)) refs.push(trimmed);
7867
+ return;
7868
+ }
7869
+ if (Array.isArray(value)) return void value.forEach(collect);
7870
+ if (value && 'object' == typeof value) Object.values(value).forEach(collect);
7871
+ };
7872
+ for (const [key, value] of Object.entries(manifest)){
7873
+ if (!STANDARD_MANIFEST_KEYS.has(key)) {
7874
+ collect(value);
7875
+ continue;
7876
+ }
7877
+ if ('background' === key && value && 'object' == typeof value) {
7878
+ for (const [subKey, subValue] of Object.entries(value))if (!STANDARD_BACKGROUND_KEYS.has(subKey)) collect(subValue);
7879
+ }
7880
+ }
7881
+ return refs;
7882
+ }
7741
7883
  function extractGetURLLiterals(source) {
7742
7884
  const code = blankComments(source);
7743
7885
  const literals = [];
@@ -8645,6 +8787,21 @@ class WasmPlugin {
8645
8787
  this.ensureWasmResolution(compiler, projectRoot);
8646
8788
  }
8647
8789
  }
8790
+ function filesOf(value) {
8791
+ if (Array.isArray(value)) return value;
8792
+ return value ? [
8793
+ value
8794
+ ] : [];
8795
+ }
8796
+ function omitOwnedPages(pages, owned) {
8797
+ const ownedFiles = new Set(Object.values(owned).flatMap(filesOf).map((file)=>__rspack_external_node_path_806ed179.resolve(file)));
8798
+ const next = {};
8799
+ for (const [name, value] of Object.entries(pages || {})){
8800
+ const files = filesOf(value);
8801
+ if (!(files.length > 0 && files.every((file)=>ownedFiles.has(__rspack_external_node_path_806ed179.resolve(file))))) next[name] = value;
8802
+ }
8803
+ return next;
8804
+ }
8648
8805
  const COMPILED_SIBLING_EXTENSIONS = [
8649
8806
  '.ts',
8650
8807
  '.mts',
@@ -8677,7 +8834,7 @@ function javaScriptError(errorSourcePath, missingFilePath, opts) {
8677
8834
  lines.push("The page references a script file that doesn't exist.");
8678
8835
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8679
8836
  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.`);
8837
+ 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
8838
  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
8839
  lines.push(`Update the ${pintor.blue("<script>")} src to point to a file that exists.`);
8683
8840
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -8688,7 +8845,7 @@ function cssError(errorSourcePath, missingFilePath, opts) {
8688
8845
  lines.push("The page references a stylesheet that doesn't exist.");
8689
8846
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8690
8847
  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.`);
8848
+ 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
8849
  if (opts?.deadRefHint) lines.push("Chrome loads the page anyway and 404s this reference silently, so it is likely dead code.");
8693
8850
  lines.push(`Update the ${pintor.blue('<link>')} href to point to a file that exists.`);
8694
8851
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -8701,7 +8858,7 @@ function staticAssetError(errorSourcePath, missingFilePath, opts) {
8701
8858
  lines.push(`${pintor.gray('PATH')} ${pintor.underline(errorSourcePath)}`);
8702
8859
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
8703
8860
  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.`);
8861
+ 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
8862
  if (opts?.deadRefHint) lines.push("Chrome loads the page anyway and 404s this reference silently, so it is likely dead code.");
8706
8863
  lines.push(`Update the ${pintor.blue(ref)} reference to point to a file that exists.`);
8707
8864
  if (opts?.deadRefHint) lines.push(`Set ${pintor.blue('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
@@ -9055,7 +9212,7 @@ function warnMissingPublicRootResources(params) {
9055
9212
  if (resolveRootAbsoluteRef(publicRootUrl, manifestDir, publicRootForResource) || resolveRootAbsoluteRef(publicRootUrl, projectRoot, publicRootForResource)) return;
9056
9213
  if (findCompiledRootRefSource(publicRootUrl, manifestDir, publicRootForResource) || findCompiledRootRefSource(publicRootUrl, projectRoot, publicRootForResource)) return;
9057
9214
  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);
9215
+ const displayPath = __rspack_external_node_path_806ed179.join(manifestDir, trimmed);
9059
9216
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
9060
9217
  publicRootHint: true,
9061
9218
  refLabel: publicRootUrl
@@ -9187,7 +9344,7 @@ class AddAssetsToCompilation {
9187
9344
  if (!__rspack_external_node_fs_1b05aee1.existsSync(absoluteFsPath)) {
9188
9345
  const inIncludeList = isFromIncludeList(asset, this.includeList);
9189
9346
  if (!inIncludeList && !__rspack_external_node_path_806ed179.basename(asset).startsWith('#')) {
9190
- const displayPath = isRootUrl ? __rspack_external_node_path_806ed179.join(outputRoot, cleanLeading(asset)) : absoluteFsPath;
9347
+ const displayPath = isRootUrl ? __rspack_external_node_path_806ed179.join(manifestDir, cleanLeading(asset)) : absoluteFsPath;
9191
9348
  reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
9192
9349
  publicRootHint: isRootUrl,
9193
9350
  refLabel: asset
@@ -9204,25 +9361,25 @@ class AddAssetsToCompilation {
9204
9361
  const filepath = htmlStaticAssetOutputName(manifestDir, resource, absoluteFsPath);
9205
9362
  const isNestedHtml = asset.endsWith('.html');
9206
9363
  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
- }
9364
+ if (isFromIncludeList(asset, this.includeList) && !nestedHtmlAsset) continue;
9365
+ const reachableUnderAssets = isNestedHtml || !isRootUrl;
9366
+ if (reachableUnderAssets && !('function' == typeof getAssetFn && getAssetFn.call(compilation, filepath))) if (asset.endsWith('.html')) emitNestedHtmlAndReferencedAssets({
9367
+ compilation,
9368
+ filepath,
9369
+ absoluteFsPath,
9370
+ manifestDir
9371
+ });
9372
+ else {
9373
+ const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9374
+ compilation.emitAsset(filepath, new core_sources.RawSource(source));
9375
+ }
9376
+ if (!isNestedHtml && __rspack_external_node_fs_1b05aee1.existsSync(absoluteFsPath)) {
9377
+ const manifestRelative = __rspack_external_node_path_806ed179.relative(manifestDir, absoluteFsPath);
9378
+ if (manifestRelative && !manifestRelative.startsWith('..') && !__rspack_external_node_path_806ed179.isAbsolute(manifestRelative)) {
9379
+ const sourcePathAsset = manifestRelative.split(__rspack_external_node_path_806ed179.sep).join('/');
9380
+ if (sourcePathAsset !== filepath && !('function' == typeof getAssetFn && getAssetFn.call(compilation, sourcePathAsset))) {
9381
+ const source = __rspack_external_node_fs_1b05aee1.readFileSync(absoluteFsPath);
9382
+ compilation.emitAsset(sourcePathAsset, new core_sources.RawSource(source));
9226
9383
  }
9227
9384
  }
9228
9385
  }
@@ -9547,8 +9704,7 @@ function handleCantResolveError(includesList, error, compilation, manifestDir) {
9547
9704
  break;
9548
9705
  }
9549
9706
  }
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;
9707
+ 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
9708
  const errorMsg = fileNotFound(resource, overrideNotFoundPath || wrongFilename, {
9553
9709
  publicRootHint: isPublicRoot
9554
9710
  });
@@ -9869,7 +10025,7 @@ function iconsMissingFile(manifestField, filePath, opts) {
9869
10025
  lines.push(`Can't find an icon file listed in ${pintor.blue(manifestField)}.`);
9870
10026
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(filePath)}`);
9871
10027
  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.`);
10028
+ 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
10029
  lines.push(`Update the icon path in your ${pintor.blue('manifest.json')} to a file that ships with the extension.`);
9874
10030
  return lines.join('\n');
9875
10031
  }
@@ -9878,7 +10034,7 @@ function themeImageMissingFile(manifestField, filePath, opts) {
9878
10034
  lines.push(`Check the ${pintor.yellow(manifestField)} field in your ${pintor.yellow('manifest.json')} file.`);
9879
10035
  lines.push("The theme image path must point to an existing file that will be packaged with the extension.");
9880
10036
  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.`);
10037
+ 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
10038
  lines.push('');
9883
10039
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(filePath)}`);
9884
10040
  return lines.join('\n');
@@ -10046,7 +10202,7 @@ class EmitFile {
10046
10202
  const isThemeImage = 'theme' === group && 'images' === sub;
10047
10203
  if (!__rspack_external_node_fs_1b05aee1.existsSync(resolved)) {
10048
10204
  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);
10205
+ 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
10206
  const isFatal = 'icons' === group || isDefaultIconFamily || isThemeImage;
10051
10207
  const severity = isFatal ? 'error' : 'warning';
10052
10208
  reportToCompilation(compilation, compiler, isThemeImage ? themeImageMissingFile(feature, displayPath, {
@@ -10179,7 +10335,7 @@ function jsonMissingFile(manifestField, filePath, opts) {
10179
10335
  lines.push(`Can't find the JSON file listed in ${pintor.blue(manifestField)}.`);
10180
10336
  lines.push(`${pintor.gray('NOT FOUND')} ${pintor.underline(filePath)}`);
10181
10337
  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.`);
10338
+ 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
10339
  lines.push(`Update the JSON path in your ${pintor.blue('manifest.json')} to a file that ships with the extension.`);
10184
10340
  return lines.join('\n');
10185
10341
  }
@@ -10356,7 +10512,7 @@ function processJsonAssets(compilation, manifestPath, includeList) {
10356
10512
  const jsonFields = includeList || {};
10357
10513
  const manifestDir = __rspack_external_node_path_806ed179.dirname(manifestPath);
10358
10514
  const projectPath = getProjectPathFromCompilation(compilation, manifestPath);
10359
- const publicDir = __rspack_external_node_path_806ed179.join(projectPath, 'public');
10515
+ __rspack_external_node_path_806ed179.join(projectPath, 'public');
10360
10516
  if (isDebug()) {
10361
10517
  const featureKeys = Object.keys(jsonFields || {});
10362
10518
  const criticalCount = featureKeys.filter((key)=>isCriticalJsonFeature(key)).length;
@@ -10375,8 +10531,7 @@ function processJsonAssets(compilation, manifestPath, includeList) {
10375
10531
  for (const thisResource of resourceArr)if (thisResource) {
10376
10532
  const { abs, isUnderPublic, isPublicRoot } = resolveJsonResource(thisResource, manifestDir, projectPath);
10377
10533
  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;
10534
+ const displayPath = abs;
10380
10535
  const isFatal = isCriticalJsonFeature(feature);
10381
10536
  const notFound = new core_WebpackError(jsonMissingFile(feature, displayPath, {
10382
10537
  publicRootHint: isPublicRoot,
@@ -14990,15 +15145,18 @@ class plugin_web_extension_WebExtensionPlugin {
14990
15145
  ...manifestFieldsData.scripts
14991
15146
  }
14992
15147
  }).apply(compiler);
15148
+ const ownedPages = {
15149
+ ...manifestFieldsData.html,
15150
+ ...discoverDevtoolsPanelPages(manifestPath, this.browser),
15151
+ ...settingsOverridesStartupPages(manifestPath, this.browser)
15152
+ };
14993
15153
  new HtmlPlugin({
14994
15154
  devSession: this.devSession,
14995
15155
  manifestPath,
14996
15156
  browser: this.browser,
14997
15157
  includeList: {
14998
- ...manifestFieldsData.html,
14999
- ...discoverDevtoolsPanelPages(manifestPath, this.browser),
15000
- ...settingsOverridesStartupPages(manifestPath, this.browser),
15001
- ...specialFoldersData.pages
15158
+ ...ownedPages,
15159
+ ...omitOwnedPages(specialFoldersData.pages, ownedPages)
15002
15160
  }
15003
15161
  }).apply(compiler);
15004
15162
  new ScriptsPlugin({
@@ -15393,7 +15551,7 @@ function webpackConfig(projectStructure, devOptions) {
15393
15551
  },
15394
15552
  optimization: {
15395
15553
  emitOnErrors: false,
15396
- minimize: 'production' === devOptions.mode,
15554
+ minimize: 'production' === devOptions.mode && false !== devOptions.minify,
15397
15555
  minimizer: [
15398
15556
  new SwcJsMinimizerRspackPlugin(),
15399
15557
  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.26",
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
  },
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 };