extension-develop 4.0.30 → 4.0.32
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.
- package/README.md +5 -5
- package/dist/0~rspack-config.mjs +136 -63
- package/dist/101.mjs +50 -42
- package/dist/plugin-compilation/env.d.ts +6 -0
- package/dist/plugin-web-extension/feature-manifest/manifest-lib/legacy-paths.d.ts +26 -0
- package/dist/plugin-web-extension/feature-manifest/messages.d.ts +1 -1
- package/dist/plugin-web-extension/feature-manifest/steps/legacy-warnings.d.ts +1 -0
- package/dist/plugin-web-extension/feature-manifest/steps/update-manifest.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,7 +172,7 @@ Options accepted by each command. Values shown are typical types or enumerations
|
|
|
172
172
|
- Supported sections:
|
|
173
173
|
- config(config: Configuration): mutate the assembled Rspack config. Supports a function or a plain object. When an object is provided, it is deep‑merged on top of the assembled config.
|
|
174
174
|
- commands.dev | .build | .start | .preview: per‑command options (browser, profile, binaries, flags, preferences, unified logger defaults, packaging). These defaults are applied for all respective commands.
|
|
175
|
-
- browser.chrome | .firefox | .edge | .chromium-based | .gecko-based: start flags, excluded flags, preferences, binaries, profile reuse (persistProfile), and per-browser `extensions`.
|
|
175
|
+
- browser.chrome | .firefox | .edge | .safari | .chromium-based | .gecko-based | .webkit-based: start flags, excluded flags, preferences, binaries, profile reuse (persistProfile), and per-browser `extensions`.
|
|
176
176
|
- extensions: load-only companion extensions (unpacked dirs) loaded alongside your extension in dev/preview/start.
|
|
177
177
|
- Example: { dir: "./extensions" } loads every "./extensions/\*" folder that contains a manifest.json.
|
|
178
178
|
- Precedence when composing options (one contract for every command): stock defaults → browser._ → commands._ → CLI flags.
|
|
@@ -180,11 +180,11 @@ Options accepted by each command. Values shown are typical types or enumerations
|
|
|
180
180
|
- Example: `commands.dev.polyfill: false` turns the polyfill off for the team, and `--polyfill` turns it back on for one run.
|
|
181
181
|
- Lists (`browserFlags`, `excludeBrowserFlags`): concatenate across layers in order (browser, then command, then CLI) and dedupe.
|
|
182
182
|
- Objects (`preferences`): deep-merge, later layers win on key conflict.
|
|
183
|
-
- Browser key aliases when resolving `browser.*` from `extension.config
|
|
184
|
-
- When the runtime asks for `chromium`, `loadBrowserConfig` prefers `browser.chromium` and then falls back to `browser['chromium-based']`.
|
|
183
|
+
- Browser key aliases when resolving `browser.*` from `extension.config.*` (engine families adopt product blocks; named products do not adopt engine-based blocks):
|
|
185
184
|
- When the runtime asks for `chromium-based`, it prefers `browser['chromium-based']` and then `browser.chromium`.
|
|
186
|
-
- When the runtime asks for `firefox`, it prefers `browser.firefox` and then `browser['gecko-based']`.
|
|
187
185
|
- When the runtime asks for `gecko-based`, it prefers `browser['gecko-based']` and then `browser.firefox`.
|
|
186
|
+
- When the runtime asks for `webkit-based` **or any webkit-flavored fork name** (e.g. `acme-webkit`), it prefers the exact `browser.<name>` block, then `browser['webkit-based']`, then `browser.safari`.
|
|
187
|
+
- Named product `safari` only uses `browser.safari` (does not adopt `webkit-based`).
|
|
188
188
|
- When detected, a one‑time notice is printed to indicate config is active.
|
|
189
189
|
|
|
190
190
|
### Companion extensions (load-only)
|
|
@@ -300,7 +300,7 @@ dist/
|
|
|
300
300
|
| plugin-css | core | - Auto‑wires CSS for HTML and content scripts<br/>- Optional SASS/LESS/PostCSS when configs exist<br/>- Integrates Stylelint when configured |
|
|
301
301
|
| plugin-js-frameworks | core | - Detects React/Preact/Vue/Svelte and TypeScript<br/>- Configures SWC parsing, loaders/plugins, and safe aliases<br/>- Sets `tsconfig` resolution<br/>- Defers heavy work to `beforeRun` in production |
|
|
302
302
|
| plugin-static-assets | core | - Emits images, fonts, and misc files to `assets/`<br/>- Inlines small SVGs (≤2KB), emits larger ones<br/>- Content hashing in production; stable names in development<br/>- Respects existing custom SVG rules |
|
|
303
|
-
| plugin-compatibility | core | - Cross‑browser helpers<br/>- Normalizes browser‑specific manifest fields<br/>- Optional `webextension-polyfill` for Chromium
|
|
303
|
+
| plugin-compatibility | core | - Cross‑browser helpers<br/>- Normalizes browser‑specific manifest fields<br/>- Optional `webextension-polyfill` for Chromium (skipped for Firefox/Safari) |
|
|
304
304
|
| plugin-compilation | core | - Loads env and templating (`EXTENSION_PUBLIC_*`)<br/>- Optional `dist/<browser>` cleaning<br/>- Compact, de‑duplicated compilation summary |
|
|
305
305
|
|
|
306
306
|
## Notes and compatibility
|
package/dist/0~rspack-config.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { filterKeysForThisBrowser as external_browser_extension_manifest_fields_
|
|
|
12
12
|
import content_security_policy_parser from "content-security-policy-parser";
|
|
13
13
|
import node_fs from "node:fs";
|
|
14
14
|
import node_path from "node:path";
|
|
15
|
-
import { debugExtensionsToLoad, package_namespaceObject, getDirs, asAbsolute, browserRunnerDisabled, treeWithDistFilesBrowser, packagingDistributionFiles, toPosixPath, resolveCompanionExtensionDirs, debugContextPath, PlaywrightPlugin,
|
|
15
|
+
import { debugExtensionsToLoad, package_namespaceObject, getDirs, asAbsolute, browserRunnerDisabled, treeWithDistFilesBrowser, packagingDistributionFiles, toPosixPath, resolveCompanionExtensionDirs, debugContextPath, PlaywrightPlugin, isGeckoBasedBrowser, spacerLine, isWebkitBasedBrowser, messages_ready, CHROMIUM_FAMILY_ALIASES, treeWithSourceAndDistFiles, computeExtensionsToLoad, noCompanionExtensionsResolved, treeWithSourceFiles, bundlerFatalError, bundlerRecompiling, noEntrypointsDetected, GECKO_FAMILY_ALIASES, packagingSourceFiles, debugBrowser, debugOutputPath, manifestInvalidJson, isChromiumBasedBrowser, getSpecialFoldersDataForCompiler } from "./101.mjs";
|
|
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";
|
|
@@ -246,6 +246,11 @@ class PolyfillPlugin {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
+
function polyfillSkipReason(browser) {
|
|
250
|
+
if (isGeckoBasedBrowser(String(browser))) return 'Firefox bundles browser.* APIs';
|
|
251
|
+
if (isWebkitBasedBrowser(String(browser))) return 'Safari ships a native promise-based browser.* namespace';
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
249
254
|
class CompatibilityPlugin {
|
|
250
255
|
static name = 'plugin-compatibility';
|
|
251
256
|
manifestPath;
|
|
@@ -257,9 +262,9 @@ class CompatibilityPlugin {
|
|
|
257
262
|
this.polyfill = options.polyfill || false;
|
|
258
263
|
}
|
|
259
264
|
apply(compiler) {
|
|
260
|
-
const
|
|
261
|
-
if (this.polyfill) if (
|
|
262
|
-
if (isDebug()) console.log(compatibilityPolyfillSkipped(
|
|
265
|
+
const skipReason = polyfillSkipReason(this.browser);
|
|
266
|
+
if (this.polyfill) if (skipReason) {
|
|
267
|
+
if (isDebug()) console.log(compatibilityPolyfillSkipped(skipReason, this.browser));
|
|
263
268
|
} else {
|
|
264
269
|
if (isDebug()) console.log(compatibilityPolyfillEnabled(this.browser, 'webextension-polyfill'));
|
|
265
270
|
new PolyfillPlugin({
|
|
@@ -1001,10 +1006,12 @@ function declarativeNetRequest(manifest) {
|
|
|
1001
1006
|
return manifest.declarative_net_request && {
|
|
1002
1007
|
declarative_net_request: {
|
|
1003
1008
|
...manifest.declarative_net_request,
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1009
|
+
...Array.isArray(manifest.declarative_net_request.rule_resources) && {
|
|
1010
|
+
rule_resources: manifest.declarative_net_request.rule_resources.map((resourceObj)=>({
|
|
1011
|
+
...resourceObj,
|
|
1012
|
+
path: resourceObj.path && getFilename(`declarative_net_request/${resourceObj.id}.json`, resourceObj.path)
|
|
1013
|
+
}))
|
|
1014
|
+
}
|
|
1008
1015
|
}
|
|
1009
1016
|
};
|
|
1010
1017
|
}
|
|
@@ -1254,6 +1261,7 @@ class EnvPlugin {
|
|
|
1254
1261
|
if (processShim) new ProvidePlugin({
|
|
1255
1262
|
process: processShim
|
|
1256
1263
|
}).apply(compiler);
|
|
1264
|
+
const templateVars = buildTemplateVars(combinedVars, this.browser, mode);
|
|
1257
1265
|
compiler.hooks.thisCompilation.tap('manifest:update-manifest', (compilation)=>{
|
|
1258
1266
|
compilation.hooks.processAssets.tap({
|
|
1259
1267
|
name: 'env:module',
|
|
@@ -1264,29 +1272,11 @@ class EnvPlugin {
|
|
|
1264
1272
|
if (filename.endsWith('.json') || filename.endsWith('.html')) {
|
|
1265
1273
|
let fileContent = String(compilation.assets[filename]?.source() ?? '');
|
|
1266
1274
|
const resolveVar = (name)=>{
|
|
1267
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
1268
|
-
|
|
1269
|
-
if ('string' == typeof systemValue) return systemValue;
|
|
1270
|
-
}
|
|
1271
|
-
if (Object.prototype.hasOwnProperty.call(envVars, name)) {
|
|
1272
|
-
const explicitEnvValue = envVars[name];
|
|
1273
|
-
if ('string' == typeof explicitEnvValue) return explicitEnvValue;
|
|
1274
|
-
}
|
|
1275
|
-
if (Object.prototype.hasOwnProperty.call(defaultsVars, name)) {
|
|
1276
|
-
const defaultsValue = defaultsVars[name];
|
|
1277
|
-
if ('string' == typeof defaultsValue) return defaultsValue;
|
|
1278
|
-
}
|
|
1279
|
-
const combinedValue = combinedVars[name];
|
|
1280
|
-
return 'string' == typeof combinedValue ? combinedValue : `$${name}`;
|
|
1275
|
+
if (Object.prototype.hasOwnProperty.call(templateVars, name)) return templateVars[name];
|
|
1276
|
+
return `$${name}`;
|
|
1281
1277
|
};
|
|
1282
|
-
fileContent = fileContent.replace(/\$EXTENSION_PUBLIC_[A-
|
|
1283
|
-
|
|
1284
|
-
return resolveVar(envVarName);
|
|
1285
|
-
});
|
|
1286
|
-
fileContent = fileContent.replace(/\$EXTENSION_[A-Z_]+/g, (match)=>{
|
|
1287
|
-
const envVarName = match.slice(1);
|
|
1288
|
-
return resolveVar(envVarName);
|
|
1289
|
-
});
|
|
1278
|
+
fileContent = fileContent.replace(/\$EXTENSION_PUBLIC_[A-Z0-9_]+/g, (match)=>resolveVar(match.slice(1)));
|
|
1279
|
+
fileContent = fileContent.replace(/\$EXTENSION_[A-Z0-9_]+/g, (match)=>resolveVar(match.slice(1)));
|
|
1290
1280
|
compilation.updateAsset(filename, new core_sources.RawSource(fileContent));
|
|
1291
1281
|
if ('manifest.json' === filename) setCurrentManifestContent(compilation, fileContent);
|
|
1292
1282
|
}
|
|
@@ -1295,6 +1285,17 @@ class EnvPlugin {
|
|
|
1295
1285
|
});
|
|
1296
1286
|
}
|
|
1297
1287
|
}
|
|
1288
|
+
function buildTemplateVars(combinedVars, browser, mode) {
|
|
1289
|
+
const vars = {};
|
|
1290
|
+
for (const [key, value] of Object.entries(combinedVars))if ('string' == typeof value && key.startsWith('EXTENSION_')) vars[key] = value;
|
|
1291
|
+
const browserValue = String(browser);
|
|
1292
|
+
const modeValue = String(mode);
|
|
1293
|
+
vars.EXTENSION_BROWSER = browserValue;
|
|
1294
|
+
vars.EXTENSION_PUBLIC_BROWSER = browserValue;
|
|
1295
|
+
vars.EXTENSION_MODE = modeValue;
|
|
1296
|
+
vars.EXTENSION_PUBLIC_MODE = modeValue;
|
|
1297
|
+
return vars;
|
|
1298
|
+
}
|
|
1298
1299
|
function sanitize(input) {
|
|
1299
1300
|
return input.toLowerCase().replace(/[^a-z0-9 ]/gi, '').trim().replace(/\s+/g, '-');
|
|
1300
1301
|
}
|
|
@@ -8672,11 +8673,16 @@ class ThrowIfRecompileIsNeeded {
|
|
|
8672
8673
|
this.storeInitialHtmlAssets(htmlFields);
|
|
8673
8674
|
compiler.hooks.make.tapAsync('html:throw-if-recompile-is-needed', (compilation, done)=>{
|
|
8674
8675
|
const files = compiler.modifiedFiles || new Set();
|
|
8675
|
-
const
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8676
|
+
const isRemoteUrl = (p)=>/^(https?:)?\/\//i.test(p);
|
|
8677
|
+
const looksLikePublicRootUrl = (p)=>p.startsWith('/') && !__rspack_external_node_fs_5ea92f0c.existsSync(p);
|
|
8678
|
+
for (const changedFile of files){
|
|
8679
|
+
if (!this.initialHtmlAssets[changedFile]) continue;
|
|
8680
|
+
let updatedAssets;
|
|
8681
|
+
try {
|
|
8682
|
+
updatedAssets = getAssetsFromHtml(changedFile, __rspack_external_node_fs_5ea92f0c.readFileSync(changedFile, 'utf8'));
|
|
8683
|
+
} catch {
|
|
8684
|
+
updatedAssets = void 0;
|
|
8685
|
+
}
|
|
8680
8686
|
const updatedJsEntries = (updatedAssets?.js || []).filter((p)=>!looksLikePublicRootUrl(p) && !isRemoteUrl(p));
|
|
8681
8687
|
const updatedCssEntries = (updatedAssets?.css || []).filter((p)=>!looksLikePublicRootUrl(p) && !isRemoteUrl(p));
|
|
8682
8688
|
const { js, css } = this.initialHtmlAssets[changedFile];
|
|
@@ -9591,11 +9597,11 @@ function serverRestartRequiredFromManifestError(fileAdded, fileRemoved) {
|
|
|
9591
9597
|
lines.push("Restart the dev server to pick up changes to manifest entrypoints.");
|
|
9592
9598
|
return lines.join('\n');
|
|
9593
9599
|
}
|
|
9594
|
-
function legacyManifestPathWarning(legacyPath) {
|
|
9600
|
+
function legacyManifestPathWarning(field, legacyPath, modernPath) {
|
|
9595
9601
|
const lines = [];
|
|
9596
|
-
lines.push(`${messaging_prefix('warn')} The
|
|
9602
|
+
lines.push(`${messaging_prefix('warn')} The ${pintor.blue(field)} field uses a deprecated scaffold path.`);
|
|
9597
9603
|
lines.push(`${pintor.gray('PATH')} ${pintor.underline(legacyPath)}`);
|
|
9598
|
-
lines.push(
|
|
9604
|
+
lines.push(`Point it at ${pintor.underline(modernPath)}, Extension.js already emits the page there.`);
|
|
9599
9605
|
return lines.join('\n');
|
|
9600
9606
|
}
|
|
9601
9607
|
function fatalManifestShapeFixed(field, detail) {
|
|
@@ -10053,40 +10059,100 @@ class EmitManifest {
|
|
|
10053
10059
|
});
|
|
10054
10060
|
}
|
|
10055
10061
|
}
|
|
10062
|
+
const LEGACY_MANIFEST_PATH_RULES = [
|
|
10063
|
+
{
|
|
10064
|
+
field: 'devtools_page',
|
|
10065
|
+
legacyPath: 'devtools_page/devtools_page.html',
|
|
10066
|
+
modernPath: 'devtools/index.html'
|
|
10067
|
+
},
|
|
10068
|
+
{
|
|
10069
|
+
field: 'options_ui.page',
|
|
10070
|
+
legacyPath: 'options_ui/page.html',
|
|
10071
|
+
modernPath: 'options/index.html'
|
|
10072
|
+
},
|
|
10073
|
+
{
|
|
10074
|
+
field: 'background.page',
|
|
10075
|
+
legacyPath: 'background/page.html',
|
|
10076
|
+
modernPath: 'background/index.html'
|
|
10077
|
+
},
|
|
10078
|
+
{
|
|
10079
|
+
field: 'browser_action.default_popup',
|
|
10080
|
+
legacyPath: 'browser_action/default_popup.html',
|
|
10081
|
+
modernPath: 'action/index.html'
|
|
10082
|
+
},
|
|
10083
|
+
{
|
|
10084
|
+
field: 'page_action.default_popup',
|
|
10085
|
+
legacyPath: 'page_action/default_popup.html',
|
|
10086
|
+
modernPath: 'action/index.html'
|
|
10087
|
+
},
|
|
10088
|
+
{
|
|
10089
|
+
field: 'side_panel.default_path',
|
|
10090
|
+
legacyPath: 'side_panel/default_path.html',
|
|
10091
|
+
modernPath: 'sidebar/index.html'
|
|
10092
|
+
},
|
|
10093
|
+
{
|
|
10094
|
+
field: 'sidebar_action.default_panel',
|
|
10095
|
+
legacyPath: 'sidebar_action/default_panel.html',
|
|
10096
|
+
modernPath: 'sidebar/index.html'
|
|
10097
|
+
}
|
|
10098
|
+
];
|
|
10099
|
+
function normalizeLegacyPathRef(raw) {
|
|
10100
|
+
return String(raw || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\//, '');
|
|
10101
|
+
}
|
|
10102
|
+
function readField(manifest, field) {
|
|
10103
|
+
if (!manifest || 'object' != typeof manifest || Array.isArray(manifest)) return;
|
|
10104
|
+
let current = manifest;
|
|
10105
|
+
for (const part of field.split('.')){
|
|
10106
|
+
if (!current || 'object' != typeof current || Array.isArray(current) || !(part in current)) return;
|
|
10107
|
+
current = current[part];
|
|
10108
|
+
}
|
|
10109
|
+
return current;
|
|
10110
|
+
}
|
|
10111
|
+
function findLegacyManifestPathHits(manifest) {
|
|
10112
|
+
const hits = [];
|
|
10113
|
+
for (const rule of LEGACY_MANIFEST_PATH_RULES){
|
|
10114
|
+
const value = readField(manifest, rule.field);
|
|
10115
|
+
if ('string' == typeof value && value.trim()) {
|
|
10116
|
+
if (normalizeLegacyPathRef(value) === rule.legacyPath) hits.push({
|
|
10117
|
+
field: rule.field,
|
|
10118
|
+
legacyPath: rule.legacyPath,
|
|
10119
|
+
modernPath: rule.modernPath
|
|
10120
|
+
});
|
|
10121
|
+
}
|
|
10122
|
+
}
|
|
10123
|
+
return hits;
|
|
10124
|
+
}
|
|
10056
10125
|
class ManifestLegacyWarnings {
|
|
10057
10126
|
static name = 'manifest:legacy-warnings';
|
|
10127
|
+
reportedHits = new Set();
|
|
10058
10128
|
apply(compiler) {
|
|
10059
|
-
if ('production' === (compiler.options.mode || 'development')) return;
|
|
10060
|
-
const legacy = [
|
|
10061
|
-
'devtools_page/devtools_page.html',
|
|
10062
|
-
'options_ui/page.html',
|
|
10063
|
-
'background/page.html',
|
|
10064
|
-
'browser_action/default_popup.html',
|
|
10065
|
-
'page_action/default_popup.html',
|
|
10066
|
-
'side_panel/default_path.html',
|
|
10067
|
-
'sidebar_action/default_panel.html'
|
|
10068
|
-
];
|
|
10069
10129
|
compiler.hooks.thisCompilation.tap(ManifestLegacyWarnings.name, (compilation)=>{
|
|
10070
10130
|
compilation.hooks.processAssets.tap({
|
|
10071
10131
|
name: ManifestLegacyWarnings.name,
|
|
10072
10132
|
stage: core_Compilation.PROCESS_ASSETS_STAGE_REPORT
|
|
10073
10133
|
}, ()=>{
|
|
10074
|
-
const
|
|
10075
|
-
if (!
|
|
10076
|
-
const
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
count++;
|
|
10134
|
+
const original = getOriginalManifestContent(compilation);
|
|
10135
|
+
if (!original) return;
|
|
10136
|
+
const manifest = parseJsonSafe(original);
|
|
10137
|
+
const hits = findLegacyManifestPathHits(manifest);
|
|
10138
|
+
if (0 === hits.length) return;
|
|
10139
|
+
const isDev = 'development' === compiler.options.mode;
|
|
10140
|
+
let printed = 0;
|
|
10141
|
+
for (const hit of hits){
|
|
10142
|
+
const signature = `${hit.field}\0${hit.legacyPath}`;
|
|
10143
|
+
if (isDev) {
|
|
10144
|
+
if (this.reportedHits.has(signature)) continue;
|
|
10145
|
+
this.reportedHits.add(signature);
|
|
10087
10146
|
}
|
|
10088
|
-
|
|
10089
|
-
|
|
10147
|
+
const message = legacyManifestPathWarning(hit.field, hit.legacyPath, hit.modernPath);
|
|
10148
|
+
humanLine(message);
|
|
10149
|
+
const warn = new core_WebpackError(message);
|
|
10150
|
+
warn.name = 'ManifestLegacyWarning';
|
|
10151
|
+
warn.file = 'manifest.json';
|
|
10152
|
+
compilation.warnings.push(warn);
|
|
10153
|
+
printed++;
|
|
10154
|
+
}
|
|
10155
|
+
if (isDebug()) console.log(manifestLegacyWarningsSummary(printed));
|
|
10090
10156
|
});
|
|
10091
10157
|
});
|
|
10092
10158
|
}
|
|
@@ -11953,6 +12019,7 @@ function patchGeckoBackground(manifest, browser) {
|
|
|
11953
12019
|
class UpdateManifest {
|
|
11954
12020
|
manifestPath;
|
|
11955
12021
|
browser;
|
|
12022
|
+
reportedFatalFixes = new Set();
|
|
11956
12023
|
constructor(options){
|
|
11957
12024
|
this.manifestPath = options.manifestPath;
|
|
11958
12025
|
this.browser = options.browser || 'chrome';
|
|
@@ -12001,7 +12068,13 @@ class UpdateManifest {
|
|
|
12001
12068
|
} catch {}
|
|
12002
12069
|
const sanitized = sanitizeFatalManifestShapes(patchedManifest, __rspack_external_node_path_c5b9b54f.dirname(this.manifestPath));
|
|
12003
12070
|
patchedManifest = sanitized.manifest;
|
|
12071
|
+
const isDev = 'development' === compiler.options.mode;
|
|
12004
12072
|
for (const fix of sanitized.fixes){
|
|
12073
|
+
if (isDev) {
|
|
12074
|
+
const signature = `${fix.field}\0${fix.detail}`;
|
|
12075
|
+
if (this.reportedFatalFixes.has(signature)) continue;
|
|
12076
|
+
this.reportedFatalFixes.add(signature);
|
|
12077
|
+
}
|
|
12005
12078
|
const message = fatalManifestShapeFixed(fix.field, fix.detail);
|
|
12006
12079
|
humanLine(message);
|
|
12007
12080
|
const warn = new core_WebpackError(message);
|
package/dist/101.mjs
CHANGED
|
@@ -19,6 +19,46 @@ import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
|
|
|
19
19
|
import * as __rspack_external_node_os_74b4b876 from "node:os";
|
|
20
20
|
import * as __rspack_external_node_path_c5b9b54f from "node:path";
|
|
21
21
|
import * as __rspack_external_node_vm_bd3d9cea from "node:vm";
|
|
22
|
+
__rspack_external_node_path_c5b9b54f.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
|
|
23
|
+
const CHROMIUM_BASED_BROWSERS = [
|
|
24
|
+
'chrome',
|
|
25
|
+
'edge',
|
|
26
|
+
'brave',
|
|
27
|
+
'opera',
|
|
28
|
+
'vivaldi',
|
|
29
|
+
'yandex'
|
|
30
|
+
];
|
|
31
|
+
const GECKO_BASED_BROWSERS = [
|
|
32
|
+
'firefox',
|
|
33
|
+
'waterfox',
|
|
34
|
+
'librewolf'
|
|
35
|
+
];
|
|
36
|
+
const WEBKIT_BASED_BROWSERS = [
|
|
37
|
+
'safari'
|
|
38
|
+
];
|
|
39
|
+
const CHROMIUM_FAMILY_ALIASES = [
|
|
40
|
+
'chromium',
|
|
41
|
+
'chrome',
|
|
42
|
+
'edge',
|
|
43
|
+
'chromium-based'
|
|
44
|
+
];
|
|
45
|
+
const GECKO_FAMILY_ALIASES = [
|
|
46
|
+
'firefox',
|
|
47
|
+
'gecko-based'
|
|
48
|
+
];
|
|
49
|
+
[
|
|
50
|
+
...CHROMIUM_BASED_BROWSERS,
|
|
51
|
+
...GECKO_BASED_BROWSERS
|
|
52
|
+
];
|
|
53
|
+
function isChromiumBasedBrowser(browser) {
|
|
54
|
+
return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
|
|
55
|
+
}
|
|
56
|
+
function isGeckoBasedBrowser(browser) {
|
|
57
|
+
return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
|
|
58
|
+
}
|
|
59
|
+
function isWebkitBasedBrowser(browser) {
|
|
60
|
+
return WEBKIT_BASED_BROWSERS.includes(browser) || String(browser).includes('webkit');
|
|
61
|
+
}
|
|
22
62
|
function getLoggingPrefix(type) {
|
|
23
63
|
return messaging_prefix(type);
|
|
24
64
|
}
|
|
@@ -601,14 +641,22 @@ async function loadBrowserConfig(projectPath, browser = 'chrome') {
|
|
|
601
641
|
const userConfig = await loadConfigFile(configPath);
|
|
602
642
|
if (userConfig?.browser) {
|
|
603
643
|
const browsers = userConfig.browser;
|
|
644
|
+
const browserName = String(browser);
|
|
604
645
|
if ('chromium-based' === browser) {
|
|
605
646
|
if (browsers['chromium-based']) return browsers['chromium-based'];
|
|
606
647
|
if (browsers.chromium) return browsers.chromium;
|
|
607
648
|
} else if ('gecko-based' === browser) {
|
|
608
649
|
if (browsers['gecko-based']) return browsers['gecko-based'];
|
|
609
650
|
if (browsers.firefox) return browsers.firefox;
|
|
651
|
+
} else if (isWebkitBasedBrowser(browserName)) {
|
|
652
|
+
const direct = browsers[browserName];
|
|
653
|
+
if (direct) return direct;
|
|
654
|
+
if ('safari' !== browserName) {
|
|
655
|
+
if (browsers['webkit-based']) return browsers['webkit-based'];
|
|
656
|
+
if (browsers.safari) return browsers.safari;
|
|
657
|
+
}
|
|
610
658
|
} else {
|
|
611
|
-
const direct = browsers[
|
|
659
|
+
const direct = browsers[browserName];
|
|
612
660
|
if (direct) return direct;
|
|
613
661
|
}
|
|
614
662
|
}
|
|
@@ -634,7 +682,7 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
|
|
|
634
682
|
}
|
|
635
683
|
return false;
|
|
636
684
|
}
|
|
637
|
-
var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.
|
|
685
|
+
var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.32","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","adm-zip":"^0.6.0","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.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"}}');
|
|
638
686
|
function asAbsolute(p) {
|
|
639
687
|
return __rspack_external_node_path_c5b9b54f.isAbsolute(p) ? p : __rspack_external_node_path_c5b9b54f.resolve(p);
|
|
640
688
|
}
|
|
@@ -1182,46 +1230,6 @@ function assertNoManagedDependencyConflicts(userManifestPath, projectPath) {
|
|
|
1182
1230
|
}
|
|
1183
1231
|
if (duplicates.length > 0) throw new Error(managedDependencyConflict(duplicates, userManifestPath));
|
|
1184
1232
|
}
|
|
1185
|
-
__rspack_external_node_path_c5b9b54f.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
|
|
1186
|
-
const CHROMIUM_BASED_BROWSERS = [
|
|
1187
|
-
'chrome',
|
|
1188
|
-
'edge',
|
|
1189
|
-
'brave',
|
|
1190
|
-
'opera',
|
|
1191
|
-
'vivaldi',
|
|
1192
|
-
'yandex'
|
|
1193
|
-
];
|
|
1194
|
-
const GECKO_BASED_BROWSERS = [
|
|
1195
|
-
'firefox',
|
|
1196
|
-
'waterfox',
|
|
1197
|
-
'librewolf'
|
|
1198
|
-
];
|
|
1199
|
-
const WEBKIT_BASED_BROWSERS = [
|
|
1200
|
-
'safari'
|
|
1201
|
-
];
|
|
1202
|
-
const CHROMIUM_FAMILY_ALIASES = [
|
|
1203
|
-
'chromium',
|
|
1204
|
-
'chrome',
|
|
1205
|
-
'edge',
|
|
1206
|
-
'chromium-based'
|
|
1207
|
-
];
|
|
1208
|
-
const GECKO_FAMILY_ALIASES = [
|
|
1209
|
-
'firefox',
|
|
1210
|
-
'gecko-based'
|
|
1211
|
-
];
|
|
1212
|
-
[
|
|
1213
|
-
...CHROMIUM_BASED_BROWSERS,
|
|
1214
|
-
...GECKO_BASED_BROWSERS
|
|
1215
|
-
];
|
|
1216
|
-
function isChromiumBasedBrowser(browser) {
|
|
1217
|
-
return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
|
|
1218
|
-
}
|
|
1219
|
-
function isGeckoBasedBrowser(browser) {
|
|
1220
|
-
return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
|
|
1221
|
-
}
|
|
1222
|
-
function isWebkitBasedBrowser(browser) {
|
|
1223
|
-
return WEBKIT_BASED_BROWSERS.includes(browser) || String(browser).includes('webkit');
|
|
1224
|
-
}
|
|
1225
1233
|
function idFromHash(hash) {
|
|
1226
1234
|
const hex = hash.subarray(0, 16).toString('hex');
|
|
1227
1235
|
let id = '';
|
|
@@ -7,3 +7,9 @@ export declare class EnvPlugin {
|
|
|
7
7
|
constructor(options: Partial<PluginInterface>);
|
|
8
8
|
apply(compiler: Compiler): void;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Env values available to `$EXTENSION_*` placeholders in emitted .json/.html.
|
|
12
|
+
* Mirrors DefinePlugin: dotenv/process values plus the per-build-target
|
|
13
|
+
* browser and mode synthetics JS already reads via import.meta.env.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildTemplateVars(combinedVars: Record<string, unknown>, browser: DevOptions['browser'], mode: string): Record<string, string>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Old Extension.js scaffold layout → current standardized HTML destinations.
|
|
3
|
+
* Detection is field-scoped on purpose: a string that merely looks like an old
|
|
4
|
+
* path in description, web_accessible_resources, or any other field is not a hit.
|
|
5
|
+
*/
|
|
6
|
+
export interface LegacyManifestPathRule {
|
|
7
|
+
/** Dot-path into the author manifest (e.g. `options_ui.page`). */
|
|
8
|
+
field: string;
|
|
9
|
+
/** Exact path the old scaffold wrote into that field. */
|
|
10
|
+
legacyPath: string;
|
|
11
|
+
/** Canonical emit destination Extension.js rewrites the field to. */
|
|
12
|
+
modernPath: string;
|
|
13
|
+
}
|
|
14
|
+
export interface LegacyManifestPathHit {
|
|
15
|
+
field: string;
|
|
16
|
+
legacyPath: string;
|
|
17
|
+
modernPath: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const LEGACY_MANIFEST_PATH_RULES: readonly LegacyManifestPathRule[];
|
|
20
|
+
/** Collapse author path noise so `./x` and `/x` match the scaffold form. */
|
|
21
|
+
export declare function normalizeLegacyPathRef(raw: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Field-by-field scan of the *author* manifest for old scaffold HTML paths.
|
|
24
|
+
* Call this on the pre-rewrite source; the emitted asset already has modern paths.
|
|
25
|
+
*/
|
|
26
|
+
export declare function findLegacyManifestPathHits(manifest: unknown): LegacyManifestPathHit[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function serverRestartRequiredFromManifestError(fileAdded: string, fileRemoved: string): string;
|
|
2
|
-
export declare function legacyManifestPathWarning(legacyPath: string): string;
|
|
2
|
+
export declare function legacyManifestPathWarning(field: string, legacyPath: string, modernPath: string): string;
|
|
3
3
|
export declare function fatalManifestShapeFixed(field: string, detail: string): string;
|
|
4
4
|
export declare function invalidThemeValue(field: string, detail: string, value: string): string;
|
|
5
5
|
export declare function themeNotSupportedByBrowser(browser: string): string;
|
|
@@ -3,6 +3,7 @@ import type { DevOptions, PluginInterface } from '../../../types';
|
|
|
3
3
|
export declare class UpdateManifest {
|
|
4
4
|
readonly manifestPath: string;
|
|
5
5
|
readonly browser: DevOptions['browser'];
|
|
6
|
+
private reportedFatalFixes;
|
|
6
7
|
constructor(options: PluginInterface);
|
|
7
8
|
private applyDevOverrides;
|
|
8
9
|
apply(compiler: Compiler): void;
|