extension-develop 4.0.7 → 4.0.8-canary.1783955851.8f7bd584
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/dist/0~dev-server.mjs +4 -1
- package/dist/0~rspack-config.mjs +298 -76
- package/dist/101.mjs +32 -6
- package/dist/839.mjs +45 -6
- package/dist/845.mjs +18 -1
- package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
- package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
- package/dist/extension-js-devtools/chrome/pages/centralized-logger.js +4 -4
- package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
- package/dist/extension-js-devtools/chrome/pages/welcome.js +1 -1
- package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
- package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
- package/dist/extension-js-devtools/chromium/pages/centralized-logger.js +4 -4
- package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
- package/dist/extension-js-devtools/chromium/pages/welcome.js +1 -1
- package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
- package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
- package/dist/extension-js-devtools/edge/pages/centralized-logger.js +4 -4
- package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
- package/dist/extension-js-devtools/edge/pages/welcome.js +1 -1
- package/dist/extension-js-devtools/extension-js/chrome/events.ndjson +122 -6
- package/dist/extension-js-devtools/extension-js/chrome/ready.json +7 -7
- package/dist/extension-js-devtools/extension-js/chromium/events.ndjson +124 -6
- package/dist/extension-js-devtools/extension-js/chromium/ready.json +7 -7
- package/dist/extension-js-devtools/extension-js/edge/events.ndjson +122 -6
- package/dist/extension-js-devtools/extension-js/edge/ready.json +7 -7
- package/dist/extension-js-devtools/extension-js/firefox/events.ndjson +122 -6
- package/dist/extension-js-devtools/extension-js/firefox/ready.json +7 -7
- package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
- package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
- package/dist/extension-js-devtools/firefox/pages/centralized-logger.js +4 -4
- package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
- package/dist/extension-js-devtools/firefox/pages/welcome.js +1 -1
- package/dist/extension-js-theme/extension-js/chrome/events.ndjson +122 -6
- package/dist/extension-js-theme/extension-js/chrome/ready.json +7 -7
- package/dist/extension-js-theme/extension-js/chromium/events.ndjson +122 -6
- package/dist/extension-js-theme/extension-js/chromium/ready.json +7 -7
- package/dist/extension-js-theme/extension-js/edge/events.ndjson +122 -6
- package/dist/extension-js-theme/extension-js/edge/ready.json +7 -7
- package/dist/extension-js-theme/extension-js/firefox/events.ndjson +210 -8
- package/dist/extension-js-theme/extension-js/firefox/ready.json +7 -7
- package/dist/feature-scripts-classic-concat-loader.js +15 -2
- package/dist/feature-scripts-classic-concat-loader.mjs +15 -2
- package/dist/preprocessor-passthrough-loader.mjs +10 -0
- package/package.json +1 -1
package/dist/0~dev-server.mjs
CHANGED
|
@@ -491,6 +491,9 @@ class BridgeBroker {
|
|
|
491
491
|
case 'result':
|
|
492
492
|
if ('producer' === this.roles.get(conn)) this.onResult(frame);
|
|
493
493
|
return;
|
|
494
|
+
case 'reload-ack':
|
|
495
|
+
if ('producer' === this.roles.get(conn) && this.pendingReload?.reloadType === frame.reloadType) this.pendingReload = void 0;
|
|
496
|
+
return;
|
|
494
497
|
default:
|
|
495
498
|
return;
|
|
496
499
|
}
|
|
@@ -516,7 +519,7 @@ class BridgeBroker {
|
|
|
516
519
|
conn.send(frame);
|
|
517
520
|
notified++;
|
|
518
521
|
} catch {}
|
|
519
|
-
this.pendingReload = 0 === notified ? frame : void 0;
|
|
522
|
+
this.pendingReload = 0 === notified || "content-scripts" === frame.reloadType ? frame : void 0;
|
|
520
523
|
return notified;
|
|
521
524
|
}
|
|
522
525
|
pingProducers() {
|
package/dist/0~rspack-config.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { isResourceUnderDirs, canonicalizeDir, toResourceKey } from "./93.mjs";
|
|
|
17
17
|
import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, EXTENSIONJS_CONTENT_SCRIPT_LAYER, isCanonicalContentScriptAsset, getCanonicalContentScriptJsAssetName, getCanonicalContentScriptCssAssetName } from "./291.mjs";
|
|
18
18
|
import { stripBom, parseJsonSafe } from "./23.mjs";
|
|
19
19
|
import { scrubBrand, makeSanitizedConsole } from "./0~branding.mjs";
|
|
20
|
-
import { cssIntegrationsEnabled, cssConfigsDetected, missingSassDependency, isUsingIntegration, postCssPluginNotResolved } from "./845.mjs";
|
|
20
|
+
import { cssIntegrationsEnabled, cssConfigsDetected, deadCssUrlRef, missingSassDependency, isUsingIntegration, postCssPluginNotResolved } from "./845.mjs";
|
|
21
21
|
import { isUsingTypeScript, jsFrameworksIntegrationsEnabled, ensureTypeScriptConfig, ensureOptionalContractModuleLoaded, resolveDevelopInstallRoot, getUserTypeScriptConfigFile, isUsingCustomLoader, isUsingIntegration as messages_isUsingIntegration, loadOptionalContractModuleWithoutInstall, resolveOptionalContractPackageWithoutInstall, jsFrameworksHmrSummary, jsFrameworksConfigsDetected, hasDependency, resolveDevelopDistFile, optional_deps_resolver_ensureOptionalContractPackageResolved } from "./839.mjs";
|
|
22
22
|
import { PROJECT_MANIFEST_FILENAMES, findNearestProjectManifestSync, readProjectDependencies } from "./80.mjs";
|
|
23
23
|
import { injectedFileDependencyMissing, getURLDependencyMissing, staticImportDependencyMissing, backgroundIsRequiredMessageOnly, fetchedFileDependencyMissing, importScriptsDependencyMissing } from "./266.mjs";
|
|
@@ -293,6 +293,89 @@ function checkManifestInPublic(compilation, publicDir) {
|
|
|
293
293
|
}
|
|
294
294
|
} catch {}
|
|
295
295
|
}
|
|
296
|
+
function isFromFilepathList(filePath, filepathList) {
|
|
297
|
+
return Object.values(filepathList || {}).some((value)=>value === filePath);
|
|
298
|
+
}
|
|
299
|
+
function getFilename(feature, filePath) {
|
|
300
|
+
const entryExt = __rspack_external_path.extname(filePath);
|
|
301
|
+
let fileOutputpath = feature;
|
|
302
|
+
if ([
|
|
303
|
+
'.js',
|
|
304
|
+
'.jsx',
|
|
305
|
+
'.tsx',
|
|
306
|
+
'.ts',
|
|
307
|
+
'.vue',
|
|
308
|
+
'.svelte'
|
|
309
|
+
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.js');
|
|
310
|
+
if ([
|
|
311
|
+
'.html',
|
|
312
|
+
'.njk',
|
|
313
|
+
'.nunjucks'
|
|
314
|
+
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.html');
|
|
315
|
+
if ([
|
|
316
|
+
'.css',
|
|
317
|
+
'.scss',
|
|
318
|
+
'.sass',
|
|
319
|
+
'.less'
|
|
320
|
+
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.css');
|
|
321
|
+
return unixify(fileOutputpath || '');
|
|
322
|
+
}
|
|
323
|
+
function unixify(filePath) {
|
|
324
|
+
return filePath.replace(/\\/g, '/');
|
|
325
|
+
}
|
|
326
|
+
function resolveRootAbsoluteRef(ref, projectRoot, publicRoot) {
|
|
327
|
+
if (!ref || !ref.startsWith('/')) return;
|
|
328
|
+
if (projectRoot && ref.startsWith(projectRoot)) return;
|
|
329
|
+
if (ref.startsWith('//')) return;
|
|
330
|
+
const trimmed = ref.replace(/^\/+/, '');
|
|
331
|
+
if (!trimmed) return;
|
|
332
|
+
if (publicRoot && __rspack_external_fs.existsSync(__rspack_external_path.join(publicRoot, trimmed))) return;
|
|
333
|
+
const candidate = __rspack_external_path.resolve(projectRoot, trimmed);
|
|
334
|
+
const rel = __rspack_external_path.relative(projectRoot, candidate);
|
|
335
|
+
if (rel.startsWith('..') || __rspack_external_path.isAbsolute(rel)) return;
|
|
336
|
+
if (!__rspack_external_fs.existsSync(candidate) || !__rspack_external_fs.statSync(candidate).isFile()) return;
|
|
337
|
+
return candidate;
|
|
338
|
+
}
|
|
339
|
+
function collectRootAbsoluteRefs(source) {
|
|
340
|
+
const refs = new Set();
|
|
341
|
+
const attrRe = /(?:src|href)\s*=\s*["'](\/[^"'#?]*)["']/gi;
|
|
342
|
+
const urlRe = /url\(\s*["']?(\/[^"')#?]+)["']?\s*\)/gi;
|
|
343
|
+
let m;
|
|
344
|
+
while(m = attrRe.exec(source))refs.add(m[1]);
|
|
345
|
+
while(m = urlRe.exec(source))refs.add(m[1]);
|
|
346
|
+
return refs;
|
|
347
|
+
}
|
|
348
|
+
function emitRootAbsoluteRefs(compilation, context, publicDir) {
|
|
349
|
+
const scanned = new Set();
|
|
350
|
+
for(let pass = 0; pass < 10; pass++){
|
|
351
|
+
const refs = new Set();
|
|
352
|
+
for (const asset of compilation.getAssets()){
|
|
353
|
+
if (!/\.(html|css)$/i.test(asset.name)) continue;
|
|
354
|
+
if (scanned.has(asset.name)) continue;
|
|
355
|
+
scanned.add(asset.name);
|
|
356
|
+
let source;
|
|
357
|
+
try {
|
|
358
|
+
source = String(asset.source.source());
|
|
359
|
+
} catch {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
for (const ref of collectRootAbsoluteRefs(source))refs.add(ref);
|
|
363
|
+
}
|
|
364
|
+
if (0 === refs.size) return;
|
|
365
|
+
let emitted = 0;
|
|
366
|
+
for (const ref of refs){
|
|
367
|
+
const outputName = ref.replace(/^\/+/, '');
|
|
368
|
+
if (compilation.getAsset(outputName)) continue;
|
|
369
|
+
const sourcePath = resolveRootAbsoluteRef(ref, context, publicDir);
|
|
370
|
+
if (sourcePath) try {
|
|
371
|
+
compilation.emitAsset(outputName, new rspack.sources.RawSource(__rspack_external_fs.readFileSync(sourcePath)));
|
|
372
|
+
compilation.fileDependencies.add(sourcePath);
|
|
373
|
+
emitted++;
|
|
374
|
+
} catch {}
|
|
375
|
+
}
|
|
376
|
+
if (0 === emitted) return;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
296
379
|
class SpecialFoldersPlugin {
|
|
297
380
|
static name = 'plugin-special-folders';
|
|
298
381
|
options;
|
|
@@ -303,6 +386,14 @@ class SpecialFoldersPlugin {
|
|
|
303
386
|
const { manifestPath } = this.options;
|
|
304
387
|
const context = compiler.options.context || __rspack_external_path.dirname(manifestPath);
|
|
305
388
|
const publicDir = __rspack_external_path.join(context, 'public');
|
|
389
|
+
compiler.hooks.thisCompilation.tap(SpecialFoldersPlugin.name, (compilation)=>{
|
|
390
|
+
compilation.hooks.processAssets.tap({
|
|
391
|
+
name: `${SpecialFoldersPlugin.name}:root-absolute-refs`,
|
|
392
|
+
stage: compilation.constructor.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
393
|
+
}, ()=>{
|
|
394
|
+
emitRootAbsoluteRefs(compilation, __rspack_external_path.dirname(manifestPath), publicDir);
|
|
395
|
+
});
|
|
396
|
+
});
|
|
306
397
|
if (__rspack_external_fs.existsSync(publicDir) && __rspack_external_fs.statSync(publicDir).isDirectory()) {
|
|
307
398
|
compiler.hooks.thisCompilation.tap(SpecialFoldersPlugin.name, (compilation)=>{
|
|
308
399
|
compilation.hooks.processAssets.tap({
|
|
@@ -380,36 +471,6 @@ function envInjectedPublicVars(count) {
|
|
|
380
471
|
function envNoMatchingFile(browser, mode, presentFiles, expectedCandidates) {
|
|
381
472
|
return `Found ${presentFiles.map((file)=>pintor.yellow(file)).join(', ')} but none match browser ${pintor.yellow(browser)} (mode ${pintor.yellow(mode)}), so EXTENSION_PUBLIC_* variables read from code will be ${pintor.yellow('undefined')} in this build.\nMatching names, in priority order: ${expectedCandidates.map((file)=>pintor.gray(file)).join(', ')}.\nFamily names apply to every family member — e.g. ${pintor.yellow('.env.chrome')} also matches ${pintor.yellow('chromium')} and ${pintor.yellow('edge')} targets.`;
|
|
382
473
|
}
|
|
383
|
-
function isFromFilepathList(filePath, filepathList) {
|
|
384
|
-
return Object.values(filepathList || {}).some((value)=>value === filePath);
|
|
385
|
-
}
|
|
386
|
-
function getFilename(feature, filePath) {
|
|
387
|
-
const entryExt = __rspack_external_path.extname(filePath);
|
|
388
|
-
let fileOutputpath = feature;
|
|
389
|
-
if ([
|
|
390
|
-
'.js',
|
|
391
|
-
'.jsx',
|
|
392
|
-
'.tsx',
|
|
393
|
-
'.ts',
|
|
394
|
-
'.vue',
|
|
395
|
-
'.svelte'
|
|
396
|
-
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.js');
|
|
397
|
-
if ([
|
|
398
|
-
'.html',
|
|
399
|
-
'.njk',
|
|
400
|
-
'.nunjucks'
|
|
401
|
-
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.html');
|
|
402
|
-
if ([
|
|
403
|
-
'.css',
|
|
404
|
-
'.scss',
|
|
405
|
-
'.sass',
|
|
406
|
-
'.less'
|
|
407
|
-
].includes(entryExt)) fileOutputpath = fileOutputpath.replace(entryExt, '.css');
|
|
408
|
-
return unixify(fileOutputpath || '');
|
|
409
|
-
}
|
|
410
|
-
function unixify(filePath) {
|
|
411
|
-
return filePath.replace(/\\/g, '/');
|
|
412
|
-
}
|
|
413
474
|
function background_background(manifest) {
|
|
414
475
|
return manifest.background && manifest.background.scripts && {
|
|
415
476
|
background: {
|
|
@@ -2159,12 +2220,14 @@ async function buildCssRules(projectPath, mode, usage, opts) {
|
|
|
2159
2220
|
test: /\.(sass|scss)$/,
|
|
2160
2221
|
exclude: /\.module\.(sass|scss)$/,
|
|
2161
2222
|
type: nonModuleType,
|
|
2162
|
-
loader: null
|
|
2223
|
+
loader: null,
|
|
2224
|
+
missingTool: 'sass'
|
|
2163
2225
|
},
|
|
2164
2226
|
{
|
|
2165
2227
|
test: /\.module\.(sass|scss)$/,
|
|
2166
2228
|
type: 'css/module',
|
|
2167
|
-
loader: null
|
|
2229
|
+
loader: null,
|
|
2230
|
+
missingTool: 'sass'
|
|
2168
2231
|
}
|
|
2169
2232
|
],
|
|
2170
2233
|
...useLess ? [
|
|
@@ -2184,16 +2247,18 @@ async function buildCssRules(projectPath, mode, usage, opts) {
|
|
|
2184
2247
|
test: /\.less$/,
|
|
2185
2248
|
exclude: /\.module\.less$/,
|
|
2186
2249
|
type: nonModuleType,
|
|
2187
|
-
loader: null
|
|
2250
|
+
loader: null,
|
|
2251
|
+
missingTool: 'less'
|
|
2188
2252
|
},
|
|
2189
2253
|
{
|
|
2190
2254
|
test: /\.module\.less$/,
|
|
2191
2255
|
type: 'css/module',
|
|
2192
|
-
loader: null
|
|
2256
|
+
loader: null,
|
|
2257
|
+
missingTool: 'less'
|
|
2193
2258
|
}
|
|
2194
2259
|
]
|
|
2195
2260
|
];
|
|
2196
|
-
return Promise.all(fileTypes.map(async ({ test, exclude, type, loader })=>{
|
|
2261
|
+
return Promise.all(fileTypes.map(async ({ test, exclude, type, loader, missingTool })=>{
|
|
2197
2262
|
const use = loader ? await commonStyleLoaders(projectPath, {
|
|
2198
2263
|
mode: mode,
|
|
2199
2264
|
loader,
|
|
@@ -2203,6 +2268,9 @@ async function buildCssRules(projectPath, mode, usage, opts) {
|
|
|
2203
2268
|
}) : await commonStyleLoaders(projectPath, {
|
|
2204
2269
|
mode: mode
|
|
2205
2270
|
});
|
|
2271
|
+
if (missingTool) use.push({
|
|
2272
|
+
loader: resolveDevelopDistFile('preprocessor-passthrough-loader')
|
|
2273
|
+
});
|
|
2206
2274
|
return {
|
|
2207
2275
|
test,
|
|
2208
2276
|
exclude,
|
|
@@ -2302,7 +2370,53 @@ class CssPlugin {
|
|
|
2302
2370
|
console.log(cssConfigsDetected(postcssConfig, tailwindConfig, browserslistSource));
|
|
2303
2371
|
}
|
|
2304
2372
|
}
|
|
2373
|
+
tolerateDeadUrlRefs(compiler) {
|
|
2374
|
+
const manifestDir = __rspack_external_path.dirname(this.manifestPath);
|
|
2375
|
+
const projectPath = compiler.options.context || process.cwd();
|
|
2376
|
+
const roots = [
|
|
2377
|
+
__rspack_external_path.join(projectPath, 'public'),
|
|
2378
|
+
manifestDir
|
|
2379
|
+
];
|
|
2380
|
+
const assetExt = /\.(png|jpe?g|gif|webp|svg|avif|ico|bmp|cur|woff2?|ttf|otf|eot|mp3|mp4|webm|ogg|wav)$/i;
|
|
2381
|
+
let compilation = null;
|
|
2382
|
+
const warned = new Set();
|
|
2383
|
+
if (!compiler.hooks?.thisCompilation?.tap || !compiler.hooks?.normalModuleFactory?.tap) return;
|
|
2384
|
+
compiler.hooks.thisCompilation.tap(`${CssPlugin.name}:dead-url`, (c)=>{
|
|
2385
|
+
compilation = c;
|
|
2386
|
+
warned.clear();
|
|
2387
|
+
});
|
|
2388
|
+
compiler.hooks.normalModuleFactory.tap(`${CssPlugin.name}:dead-url`, (nmf)=>{
|
|
2389
|
+
nmf.hooks.beforeResolve.tap(`${CssPlugin.name}:dead-url`, (data)=>{
|
|
2390
|
+
const issuer = String(data?.contextInfo?.issuer || '').split('?')[0];
|
|
2391
|
+
if (!/\.(css|scss|sass|less)$/i.test(issuer)) return;
|
|
2392
|
+
const raw = String(data?.request || '');
|
|
2393
|
+
const req = raw.split('?')[0].split('#')[0];
|
|
2394
|
+
if (!req || req.startsWith('//') || /^[a-z][a-z0-9+.-]*:/i.test(req)) return;
|
|
2395
|
+
if (req.startsWith('~') || req.startsWith('@')) return;
|
|
2396
|
+
const isRootRef = req.startsWith('/');
|
|
2397
|
+
const isRelativeRef = req.startsWith('./') || req.startsWith('../');
|
|
2398
|
+
const isBareAssetRef = !isRootRef && !isRelativeRef && assetExt.test(req);
|
|
2399
|
+
if (!isRootRef && !isRelativeRef && !isBareAssetRef) return;
|
|
2400
|
+
const issuerDir = data?.context || __rspack_external_path.dirname(issuer);
|
|
2401
|
+
const candidates = isRootRef ? roots.map((root)=>__rspack_external_path.join(root, req.slice(1))) : [
|
|
2402
|
+
__rspack_external_path.resolve(issuerDir, req),
|
|
2403
|
+
...isBareAssetRef ? roots.map((root)=>__rspack_external_path.join(root, req)) : []
|
|
2404
|
+
];
|
|
2405
|
+
if (candidates.some((candidate)=>__rspack_external_fs.existsSync(candidate))) return;
|
|
2406
|
+
if ('true' === process.env.EXTENSION_STRICT_REFS) return;
|
|
2407
|
+
const key = `${issuer}|${req}`;
|
|
2408
|
+
if (!warned.has(key) && compilation?.warnings) {
|
|
2409
|
+
warned.add(key);
|
|
2410
|
+
const warning = new core_WebpackError(deadCssUrlRef(__rspack_external_path.relative(manifestDir, issuer) || issuer, raw));
|
|
2411
|
+
warning.file = __rspack_external_path.relative(manifestDir, issuer);
|
|
2412
|
+
compilation.warnings.push(warning);
|
|
2413
|
+
}
|
|
2414
|
+
return false;
|
|
2415
|
+
});
|
|
2416
|
+
});
|
|
2417
|
+
}
|
|
2305
2418
|
async apply(compiler) {
|
|
2419
|
+
this.tolerateDeadUrlRefs(compiler);
|
|
2306
2420
|
const mode = compiler.options.mode || 'development';
|
|
2307
2421
|
if ('production' === mode) return void compiler.hooks.beforeRun.tapPromise(CssPlugin.name, ()=>this.configureOptions(compiler));
|
|
2308
2422
|
const configuring = this.configureOptions(compiler);
|
|
@@ -2353,7 +2467,7 @@ class StaticAssetsPlugin {
|
|
|
2353
2467
|
rules: []
|
|
2354
2468
|
};
|
|
2355
2469
|
compiler.options.module.rules = compiler.options.module.rules || [];
|
|
2356
|
-
const filenamePattern = '
|
|
2470
|
+
const filenamePattern = 'assets/[name].[contenthash:8][ext]';
|
|
2357
2471
|
const defaultSvgRule = {
|
|
2358
2472
|
test: /\.svg$/i,
|
|
2359
2473
|
type: 'asset',
|
|
@@ -3872,8 +3986,7 @@ function emitDirectoryAsAssets(compilation, absDir, baseDir) {
|
|
|
3872
3986
|
walk(absDir);
|
|
3873
3987
|
}
|
|
3874
3988
|
function emitFileAsAsset(compilation, absPath) {
|
|
3875
|
-
const
|
|
3876
|
-
const filenamePattern = 'production' === mode ? 'assets/[name].[contenthash:8][ext]' : 'assets/[name][ext]';
|
|
3989
|
+
const filenamePattern = 'assets/[name].[contenthash:8][ext]';
|
|
3877
3990
|
const ext = __rspack_external_path.extname(absPath);
|
|
3878
3991
|
const name = __rspack_external_path.basename(absPath, ext);
|
|
3879
3992
|
const content = __rspack_external_fs.readFileSync(absPath);
|
|
@@ -4306,15 +4419,32 @@ const DEV_CONNECT_SOURCES = [
|
|
|
4306
4419
|
'http://127.0.0.1:*',
|
|
4307
4420
|
'http://localhost:*'
|
|
4308
4421
|
];
|
|
4422
|
+
const LOOPBACK_HOSTS = new Set([
|
|
4423
|
+
'127.0.0.1',
|
|
4424
|
+
'localhost',
|
|
4425
|
+
'[::1]',
|
|
4426
|
+
'::1'
|
|
4427
|
+
]);
|
|
4428
|
+
function devConnectSources() {
|
|
4429
|
+
const sources = [
|
|
4430
|
+
...DEV_CONNECT_SOURCES
|
|
4431
|
+
];
|
|
4432
|
+
const raw = String(process.env.EXTENSION_DEV_SERVER_CONNECTABLE_HOST || '').trim();
|
|
4433
|
+
if (!raw || LOOPBACK_HOSTS.has(raw)) return sources;
|
|
4434
|
+
const host = raw.includes(':') && !raw.startsWith('[') ? `[${raw}]` : raw;
|
|
4435
|
+
sources.push(`ws://${host}:*`, `http://${host}:*`);
|
|
4436
|
+
return sources;
|
|
4437
|
+
}
|
|
4309
4438
|
function loosenConnectSrcForDev(csp) {
|
|
4439
|
+
const devSources = devConnectSources();
|
|
4310
4440
|
const connectSrc = csp.get('connect-src');
|
|
4311
4441
|
const defaultSrc = csp.get('default-src');
|
|
4312
4442
|
if (connectSrc) {
|
|
4313
|
-
for (const source of
|
|
4443
|
+
for (const source of devSources)if (!connectSrc.includes(source)) connectSrc.push(source);
|
|
4314
4444
|
csp.set('connect-src', connectSrc);
|
|
4315
4445
|
} else if (defaultSrc) csp.set('connect-src', [
|
|
4316
4446
|
...defaultSrc,
|
|
4317
|
-
...
|
|
4447
|
+
...devSources
|
|
4318
4448
|
]);
|
|
4319
4449
|
}
|
|
4320
4450
|
function patchV2CSP(manifest) {
|
|
@@ -4779,6 +4909,7 @@ function javaScriptError(errorSourcePath, missingFilePath, opts) {
|
|
|
4779
4909
|
lines.push(`Missing script file in ${pintor.underline(errorSourcePath)}.`);
|
|
4780
4910
|
lines.push(`Update your ${pintor.yellow("<script>")} src to point to a file that exists.`);
|
|
4781
4911
|
if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
|
|
4912
|
+
if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
|
|
4782
4913
|
lines.push('');
|
|
4783
4914
|
lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
|
|
4784
4915
|
return lines.join('\n');
|
|
@@ -4788,6 +4919,7 @@ function cssError(errorSourcePath, missingFilePath, opts) {
|
|
|
4788
4919
|
lines.push(`Missing stylesheet in ${pintor.underline(errorSourcePath)}.`);
|
|
4789
4920
|
lines.push(`Update your ${pintor.yellow('<link>')} href to point to a file that exists.`);
|
|
4790
4921
|
if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
|
|
4922
|
+
if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
|
|
4791
4923
|
lines.push('');
|
|
4792
4924
|
lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
|
|
4793
4925
|
return lines.join('\n');
|
|
@@ -4799,6 +4931,7 @@ function staticAssetError(errorSourcePath, missingFilePath, opts) {
|
|
|
4799
4931
|
const ref = opts?.refLabel || '*' + extname;
|
|
4800
4932
|
lines.push(`Update the ${pintor.yellow(ref)} reference to point to a file that exists.`);
|
|
4801
4933
|
if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
|
|
4934
|
+
if (opts?.deadRefHint) lines.push(`Chrome loads the page anyway and 404s this reference silently — likely dead code. Set ${pintor.yellow('EXTENSION_STRICT_REFS=true')} to make this a build error.`);
|
|
4802
4935
|
lines.push('');
|
|
4803
4936
|
lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(missingFilePath)}`);
|
|
4804
4937
|
return lines.join('\n');
|
|
@@ -5127,6 +5260,7 @@ function warnMissingPublicRootResources(params) {
|
|
|
5127
5260
|
const trimmed = publicRootUrl.replace(/^\//, '');
|
|
5128
5261
|
const publicRootAbs = __rspack_external_path.join(publicRootForResource, trimmed);
|
|
5129
5262
|
const outputRootAssetAbs = __rspack_external_path.join(outputRoot, trimmed);
|
|
5263
|
+
if (resolveRootAbsoluteRef(publicRootUrl, projectRoot, publicRootForResource)) return;
|
|
5130
5264
|
if (!__rspack_external_fs.existsSync(publicRootAbs) && !__rspack_external_fs.existsSync(outputRootAssetAbs)) {
|
|
5131
5265
|
const displayPath = __rspack_external_path.join(outputRoot, trimmed);
|
|
5132
5266
|
reportToCompilation(compilation, compiler, fileNotFound(resource, displayPath, {
|
|
@@ -5140,12 +5274,15 @@ function warnMissingPublicRootResources(params) {
|
|
|
5140
5274
|
}
|
|
5141
5275
|
function checkMissingLocalEntries(params) {
|
|
5142
5276
|
const { compilation, compiler, resource, manifestDir, projectRoot, js, css } = params;
|
|
5277
|
+
const strictRefs = 'true' === process.env.EXTENSION_STRICT_REFS;
|
|
5143
5278
|
const check = (url)=>{
|
|
5144
5279
|
if (!url || isHttpLike(url) || isSpecialScheme(url)) return;
|
|
5145
|
-
if (url.startsWith('/') && !
|
|
5280
|
+
if (url.startsWith('/') && !url.startsWith(projectRoot)) return;
|
|
5146
5281
|
if (!__rspack_external_fs.existsSync(url)) {
|
|
5147
5282
|
const displayFile = __rspack_external_path.relative(manifestDir, resource);
|
|
5148
|
-
reportToCompilation(compilation, compiler, fileNotFound(displayFile, url
|
|
5283
|
+
reportToCompilation(compilation, compiler, fileNotFound(displayFile, url, {
|
|
5284
|
+
deadRefHint: !strictRefs
|
|
5285
|
+
}), strictRefs ? 'error' : 'warning', displayFile);
|
|
5149
5286
|
}
|
|
5150
5287
|
};
|
|
5151
5288
|
js?.forEach(check);
|
|
@@ -5315,12 +5452,15 @@ function isClassicScript(filePath) {
|
|
|
5315
5452
|
}
|
|
5316
5453
|
}
|
|
5317
5454
|
function classicConcatEntry(feature, jsFiles) {
|
|
5455
|
+
const deduped = [
|
|
5456
|
+
...new Set(jsFiles)
|
|
5457
|
+
];
|
|
5318
5458
|
const queryData = encodeURIComponent(JSON.stringify({
|
|
5319
5459
|
feature,
|
|
5320
|
-
js:
|
|
5460
|
+
js: deduped,
|
|
5321
5461
|
css: []
|
|
5322
5462
|
}));
|
|
5323
|
-
return `${
|
|
5463
|
+
return `${deduped[0]}?__extensionjs_classic_concat__=${queryData}`;
|
|
5324
5464
|
}
|
|
5325
5465
|
const WILDCARD_HOSTS = new Set([
|
|
5326
5466
|
'0.0.0.0',
|
|
@@ -5426,8 +5566,6 @@ class AddScriptsAndStylesToCompilation {
|
|
|
5426
5566
|
const htmlEntries = this.includeList || {};
|
|
5427
5567
|
const manifestDir = __rspack_external_path.dirname(this.manifestPath);
|
|
5428
5568
|
const projectRoot = compiler.options.context || manifestDir;
|
|
5429
|
-
const publicDir = __rspack_external_path.join(projectRoot, 'public');
|
|
5430
|
-
const hasPublicDir = __rspack_external_fs.existsSync(publicDir);
|
|
5431
5569
|
const devServerHmrImports = 'development' === compiler.options.mode ? getDevServerHmrImports(compiler) : [];
|
|
5432
5570
|
for (const field of Object.entries(htmlEntries)){
|
|
5433
5571
|
const [feature, resource] = field;
|
|
@@ -5435,9 +5573,10 @@ class AddScriptsAndStylesToCompilation {
|
|
|
5435
5573
|
if (!__rspack_external_fs.existsSync(resource)) continue;
|
|
5436
5574
|
const htmlAssets = getAssetsFromHtml(resource);
|
|
5437
5575
|
const isRemoteUrl = (p)=>/^(https?:)?\/\//i.test(p);
|
|
5438
|
-
const looksLikePublicRootUrl = (p)=>p.startsWith('/public/') || p.startsWith('/') && !p.startsWith(projectRoot)
|
|
5439
|
-
const
|
|
5440
|
-
const
|
|
5576
|
+
const looksLikePublicRootUrl = (p)=>p.startsWith('/public/') || p.startsWith('/') && !p.startsWith(projectRoot);
|
|
5577
|
+
const isMissingLocalFile = (p)=>__rspack_external_path.isAbsolute(p) && !__rspack_external_fs.existsSync(p);
|
|
5578
|
+
const jsAssets = (htmlAssets?.js || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
|
|
5579
|
+
const cssAssets = (htmlAssets?.css || []).filter((asset)=>!looksLikePublicRootUrl(asset) && !isRemoteUrl(asset) && !isMissingLocalFile(asset));
|
|
5441
5580
|
const moduleJsAssets = new Set(htmlAssets?.moduleJs || []);
|
|
5442
5581
|
const concatenateClassic = jsAssets.length > 1 && jsAssets.every((asset)=>!moduleJsAssets.has(asset) && /\.(js|cjs)$/i.test(asset) && isClassicScript(asset));
|
|
5443
5582
|
const jsImports = concatenateClassic ? [
|
|
@@ -5935,7 +6074,8 @@ const isScriptsFolderFeature = (feature)=>feature.startsWith("scripts/");
|
|
|
5935
6074
|
const isBackgroundScriptsFeature = (feature)=>"background/scripts" === feature;
|
|
5936
6075
|
function createSequentialEntryModule(feature, scriptImports) {
|
|
5937
6076
|
const jsFiles = scriptImports;
|
|
5938
|
-
const
|
|
6077
|
+
const concatEligible = (f)=>/\.(js|cjs|ts)$/i.test(f);
|
|
6078
|
+
const concatenateClassic = jsFiles.length > 1 && jsFiles.every((f)=>concatEligible(f) && isClassicScript(f));
|
|
5939
6079
|
if (concatenateClassic) return classicConcatEntry(feature, jsFiles);
|
|
5940
6080
|
const source = [
|
|
5941
6081
|
`/* extension.js sequential entry: ${feature} */`,
|
|
@@ -7873,6 +8013,16 @@ const BRIDGE_PRODUCER_SOURCE = `;(function () {
|
|
|
7873
8013
|
return;
|
|
7874
8014
|
}
|
|
7875
8015
|
|
|
8016
|
+
// Delivery ack for the broker: proves this SW's message pump actually
|
|
8017
|
+
// processed the frame — a successful socket WRITE proves nothing when
|
|
8018
|
+
// the worker is wedged-but-connected (bug 27). The broker latches a
|
|
8019
|
+
// content-scripts reload until this ack and replays it to the next
|
|
8020
|
+
// producer hello, so an edit that landed on a dead pump still converges.
|
|
8021
|
+
// Sent on receipt (not after reinjection): the scripting-unavailable
|
|
8022
|
+
// fallback restarts the whole extension, and an unacked latch would
|
|
8023
|
+
// replay into the fresh SW and restart it a second time.
|
|
8024
|
+
send({type: "reload-ack", reloadType: kind, label: label});
|
|
8025
|
+
|
|
7876
8026
|
announceReloadInTabs(announced);
|
|
7877
8027
|
performDevReload(kind, function () {
|
|
7878
8028
|
// Only the content-scripts path confirms from here (reinjection ran to
|
|
@@ -7984,31 +8134,56 @@ const BRIDGE_PRODUCER_SOURCE = `;(function () {
|
|
|
7984
8134
|
|
|
7985
8135
|
// Multi-context console forwarding: other contexts (content scripts, surface
|
|
7986
8136
|
// pages) can't reliably open ws://127.0.0.1 (page CSP / connect-src), so they
|
|
7987
|
-
// relay console
|
|
7988
|
-
//
|
|
8137
|
+
// relay console to this SW, which owns the WS. The relay travels a NAMED
|
|
8138
|
+
// runtime.Port — never runtime.sendMessage — because port traffic is
|
|
8139
|
+
// invisible to the extension's own onMessage listeners. With sendMessage, an
|
|
8140
|
+
// extension whose SW echoes every message back to its tabs (wild newtube:
|
|
8141
|
+
// onMessage → tabs.sendMessage(msg) to all tabs) turned each relayed log
|
|
8142
|
+
// into a new tab message, whose subject-side console.log became another
|
|
8143
|
+
// relayed envelope — a self-sustaining dev-only message storm (25k rows/10min
|
|
8144
|
+
// observed) that starved the extension system and wedged Chromium's DevTools
|
|
8145
|
+
// endpoint (family B). We enrich with the real tabId/url from the port sender.
|
|
8146
|
+
function shipRelayedLog(ev, sender) {
|
|
8147
|
+
try {
|
|
8148
|
+
send({
|
|
8149
|
+
type: "log",
|
|
8150
|
+
event: {
|
|
8151
|
+
v: 1,
|
|
8152
|
+
id: nowId(),
|
|
8153
|
+
timestamp: Date.now(),
|
|
8154
|
+
level: ev.level || "log",
|
|
8155
|
+
context: ev.context || "content",
|
|
8156
|
+
messageParts: Array.isArray(ev.messageParts) ? ev.messageParts : [],
|
|
8157
|
+
url: ev.url || (sender ? sender.url : undefined),
|
|
8158
|
+
tabId: sender && sender.tab ? sender.tab.id : undefined,
|
|
8159
|
+
frameId: sender ? sender.frameId : undefined,
|
|
8160
|
+
runId: INSTANCE_ID
|
|
8161
|
+
}
|
|
8162
|
+
});
|
|
8163
|
+
} catch (e) {}
|
|
8164
|
+
}
|
|
8165
|
+
try {
|
|
8166
|
+
var rtPort = g.chrome;
|
|
8167
|
+
if (rtPort && rtPort.runtime && rtPort.runtime.onConnect) {
|
|
8168
|
+
rtPort.runtime.onConnect.addListener(function (port) {
|
|
8169
|
+
if (!port || port.name !== "__extjs-bridge-log__") return;
|
|
8170
|
+
try {
|
|
8171
|
+
port.onMessage.addListener(function (msg) {
|
|
8172
|
+
if (!msg || !msg.__extjsBridgeLog) return;
|
|
8173
|
+
shipRelayedLog(msg.__extjsBridgeLog, port.sender);
|
|
8174
|
+
});
|
|
8175
|
+
} catch (e) {}
|
|
8176
|
+
});
|
|
8177
|
+
}
|
|
8178
|
+
} catch (e) {}
|
|
8179
|
+
// Legacy sendMessage path: kept for any surface still relaying the old way
|
|
8180
|
+
// (harmless one-predicate listener; new relays never use it).
|
|
7989
8181
|
try {
|
|
7990
8182
|
var rt = g.chrome;
|
|
7991
8183
|
if (rt && rt.runtime && rt.runtime.onMessage) {
|
|
7992
8184
|
rt.runtime.onMessage.addListener(function (msg, sender) {
|
|
7993
8185
|
if (!msg || !msg.__extjsBridgeLog) return;
|
|
7994
|
-
|
|
7995
|
-
try {
|
|
7996
|
-
send({
|
|
7997
|
-
type: "log",
|
|
7998
|
-
event: {
|
|
7999
|
-
v: 1,
|
|
8000
|
-
id: nowId(),
|
|
8001
|
-
timestamp: Date.now(),
|
|
8002
|
-
level: ev.level || "log",
|
|
8003
|
-
context: ev.context || "content",
|
|
8004
|
-
messageParts: Array.isArray(ev.messageParts) ? ev.messageParts : [],
|
|
8005
|
-
url: ev.url || (sender ? sender.url : undefined),
|
|
8006
|
-
tabId: sender && sender.tab ? sender.tab.id : undefined,
|
|
8007
|
-
frameId: sender ? sender.frameId : undefined,
|
|
8008
|
-
runId: INSTANCE_ID
|
|
8009
|
-
}
|
|
8010
|
-
});
|
|
8011
|
-
} catch (e) {}
|
|
8186
|
+
shipRelayedLog(msg.__extjsBridgeLog, sender);
|
|
8012
8187
|
// No async response.
|
|
8013
8188
|
});
|
|
8014
8189
|
}
|
|
@@ -8071,7 +8246,8 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
|
|
|
8071
8246
|
|
|
8072
8247
|
var CONTEXT = "__EXTJS_CONTEXT__";
|
|
8073
8248
|
var chrome = g.chrome;
|
|
8074
|
-
if (!chrome || !chrome.runtime
|
|
8249
|
+
if (!chrome || !chrome.runtime) return;
|
|
8250
|
+
var canRelay = typeof chrome.runtime.connect === "function";
|
|
8075
8251
|
|
|
8076
8252
|
g.__extjsBridgeRelayInstalled = true;
|
|
8077
8253
|
var consoleRef = g.console || {};
|
|
@@ -8093,14 +8269,39 @@ const BRIDGE_RELAY_SOURCE = `;(function () {
|
|
|
8093
8269
|
|
|
8094
8270
|
function here() { try { return g.location ? g.location.href : undefined; } catch (e) { return undefined; } }
|
|
8095
8271
|
|
|
8272
|
+
// Lazy named port to the SW producer. Connecting wakes an idle SW like
|
|
8273
|
+
// sendMessage does, but port frames never reach the extension's own
|
|
8274
|
+
// onMessage listeners (see the loop note above). Reconnect on demand: the
|
|
8275
|
+
// SW idling out (or reloading) disconnects the port; the next log redials.
|
|
8276
|
+
var logPort = null;
|
|
8277
|
+
function getLogPort() {
|
|
8278
|
+
if (!canRelay) return null;
|
|
8279
|
+
if (logPort) return logPort;
|
|
8280
|
+
try {
|
|
8281
|
+
logPort = chrome.runtime.connect({name: "__extjs-bridge-log__"});
|
|
8282
|
+
logPort.onDisconnect.addListener(function () {
|
|
8283
|
+
try { void chrome.runtime.lastError; } catch (e) {}
|
|
8284
|
+
logPort = null;
|
|
8285
|
+
});
|
|
8286
|
+
} catch (e) { logPort = null; }
|
|
8287
|
+
return logPort;
|
|
8288
|
+
}
|
|
8289
|
+
|
|
8096
8290
|
LEVELS.forEach(function (level) {
|
|
8097
8291
|
var orig = typeof consoleRef[level] === "function" ? consoleRef[level].bind(consoleRef) : function () {};
|
|
8098
8292
|
consoleRef[level] = function () {
|
|
8099
8293
|
try {
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8294
|
+
var p = getLogPort();
|
|
8295
|
+
if (p) {
|
|
8296
|
+
try {
|
|
8297
|
+
p.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}});
|
|
8298
|
+
} catch (e) {
|
|
8299
|
+
// stale port (SW restarted): drop it and redial once
|
|
8300
|
+
logPort = null;
|
|
8301
|
+
var p2 = getLogPort();
|
|
8302
|
+
if (p2) { try { p2.postMessage({__extjsBridgeLog: {level: level, context: CONTEXT, messageParts: sanitize([].slice.call(arguments)), url: here()}}); } catch (e2) {} }
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8104
8305
|
} catch (e) {}
|
|
8105
8306
|
return orig.apply(consoleRef, arguments);
|
|
8106
8307
|
};
|
|
@@ -10524,6 +10725,26 @@ function webpackConfig(projectStructure, devOptions) {
|
|
|
10524
10725
|
'node_modules',
|
|
10525
10726
|
__rspack_external_path.join(process.cwd(), 'node_modules')
|
|
10526
10727
|
],
|
|
10728
|
+
roots: [
|
|
10729
|
+
__rspack_external_path.join(packageJsonDir, 'public'),
|
|
10730
|
+
__rspack_external_path.dirname(manifestPath)
|
|
10731
|
+
],
|
|
10732
|
+
extensionAlias: {
|
|
10733
|
+
'.js': [
|
|
10734
|
+
'.ts',
|
|
10735
|
+
'.tsx',
|
|
10736
|
+
'.js',
|
|
10737
|
+
'.jsx'
|
|
10738
|
+
],
|
|
10739
|
+
'.mjs': [
|
|
10740
|
+
'.mts',
|
|
10741
|
+
'.mjs'
|
|
10742
|
+
],
|
|
10743
|
+
'.cjs': [
|
|
10744
|
+
'.cts',
|
|
10745
|
+
'.cjs'
|
|
10746
|
+
]
|
|
10747
|
+
},
|
|
10527
10748
|
extensions: [
|
|
10528
10749
|
'.js',
|
|
10529
10750
|
'.cjs',
|
|
@@ -10588,6 +10809,7 @@ function webpackConfig(projectStructure, devOptions) {
|
|
|
10588
10809
|
hints: false
|
|
10589
10810
|
},
|
|
10590
10811
|
optimization: {
|
|
10812
|
+
emitOnErrors: false,
|
|
10591
10813
|
minimize: 'production' === devOptions.mode,
|
|
10592
10814
|
sideEffects: true,
|
|
10593
10815
|
usedExports: 'global',
|