extension-develop 4.1.5 → 4.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/0~rspack-config.mjs +69 -27
  2. package/dist/101.mjs +21 -2
  3. package/dist/494.mjs +18 -0
  4. package/dist/839.mjs +7 -3
  5. package/dist/86.mjs +36 -0
  6. package/dist/bridge.mjs +3 -1
  7. package/dist/dead-css-url-loader.mjs +34 -0
  8. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  9. package/dist/extension-js-devtools/chrome/manifest.json +1 -1
  10. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  11. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  12. package/dist/extension-js-devtools/chrome/pages/welcome.js +4 -8
  13. package/dist/extension-js-devtools/chrome/scripts/logger-client.js +1 -0
  14. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  15. package/dist/extension-js-devtools/chromium/manifest.json +1 -1
  16. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  17. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  18. package/dist/extension-js-devtools/chromium/pages/welcome.js +4 -8
  19. package/dist/extension-js-devtools/chromium/scripts/logger-client.js +1 -0
  20. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  21. package/dist/extension-js-devtools/edge/manifest.json +1 -1
  22. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  23. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  24. package/dist/extension-js-devtools/edge/pages/welcome.js +4 -8
  25. package/dist/extension-js-devtools/edge/scripts/logger-client.js +1 -0
  26. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  27. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  28. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  29. package/dist/extension-js-devtools/firefox/pages/welcome.js +4 -8
  30. package/dist/extension-js-devtools/firefox/scripts/logger-client.js +1 -0
  31. package/dist/feature-scripts-classic-concat-loader.js +85 -13
  32. package/dist/feature-scripts-classic-concat-loader.mjs +85 -13
  33. package/dist/plugin-css/css-lib/build-css-rules.d.ts +1 -0
  34. package/dist/plugin-css/css-lib/dead-url-refs.d.ts +9 -0
  35. package/dist/plugin-css/dead-css-url-loader.d.ts +16 -0
  36. package/dist/plugin-web-extension/feature-scripts/steps/add-content-script-wrapper/classic-concat-loader.d.ts +17 -1
  37. package/dist/plugin-web-extension/feature-scripts/steps/{validate-content-script-syntax.d.ts → validate-emitted-script-syntax.d.ts} +1 -1
  38. package/package.json +1 -1
  39. package/dist/extension-js-devtools/chrome/assets/developer-mode-off.f9a94937.jpeg +0 -0
  40. package/dist/extension-js-devtools/chrome/assets/developer-mode-on.ede80e5b.jpeg +0 -0
  41. package/dist/extension-js-devtools/chrome/assets/local-network-permission.4fae40a7.png +0 -0
  42. package/dist/extension-js-devtools/chromium/assets/developer-mode-off.f9a94937.jpeg +0 -0
  43. package/dist/extension-js-devtools/chromium/assets/developer-mode-on.ede80e5b.jpeg +0 -0
  44. package/dist/extension-js-devtools/chromium/assets/local-network-permission.4fae40a7.png +0 -0
  45. package/dist/extension-js-devtools/edge/assets/developer-mode-off.f9a94937.jpeg +0 -0
  46. package/dist/extension-js-devtools/edge/assets/developer-mode-on.ede80e5b.jpeg +0 -0
  47. package/dist/extension-js-devtools/edge/assets/local-network-permission.4fae40a7.png +0 -0
  48. package/dist/extension-js-devtools/firefox/assets/developer-mode-off.f9a94937.jpeg +0 -0
  49. package/dist/extension-js-devtools/firefox/assets/developer-mode-on.ede80e5b.jpeg +0 -0
  50. package/dist/extension-js-devtools/firefox/assets/local-network-permission.4fae40a7.png +0 -0
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var t={},e={};function r(o){var n=e[o];if(void 0!==n)return n.exports;var i=e[o]={exports:{}};return t[o](i,i.exports,r),i.exports}var o="scripts/logger-client.ts",n="scripts/logger-client.ts",i="bc08ac8f";function a(){var t="";try{var e="object"==typeof globalThis&&globalThis&&(globalThis.browser&&globalThis.browser.runtime||globalThis.chrome&&globalThis.chrome.runtime)||null;e&&e.id&&(t=String(e.id))}catch(t){}return String(n||"")+(t?"@"+t:"")}var c=[];!function(){try{if("u"<typeof document||"function"!=typeof document.querySelectorAll)return;c=Array.from(document.querySelectorAll("#extension-root,[data-extension-root]"))}catch(t){c=[]}}();var u=[],l="object"==typeof globalThis&&globalThis?globalThis.__EXTENSIONJS_DEV_REINJECT__||(globalThis.__EXTENSIONJS_DEV_REINJECT__={}):{},s=[];function f(t){return"function"==typeof t&&s.push(t),t}function g(t,e,r){try{return}catch(t){}}function h(t){try{if("u"<typeof document||"function"!=typeof document.querySelectorAll)return;for(var e=a(),r=Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])')),o=0;o<r.length;o++){var c=r[o];if(c&&"function"==typeof c.getAttribute){var u=String(c.getAttribute("data-extjs-reinject-owner")||"");if(u&&u===e){var l=String(c.getAttribute("data-extjs-reinject-build")||""),s=String(i||"");if(t||!l||!s||l!==s){try{var f=document.documentElement;f&&"function"==typeof f.setAttribute&&(f.setAttribute("data-extjs-debug-stage","cleanup-known-roots"),f.setAttribute("data-extjs-debug-last-removal","cleanup-known-roots"),f.setAttribute("data-extjs-debug-last-removal-key",String(n||"")),f.setAttribute("data-extjs-debug-last-removal-source","cleanup-known-roots"),f.setAttribute("data-extjs-debug-last-removed-node-tag",String(c.tagName||"").toLowerCase()))}catch(t){}try{c.remove()}catch(t){}}}}}}catch(t){}}try{"object"==typeof globalThis&&globalThis&&(globalThis.__EXTENSIONJS_registerCleanup=f,globalThis.registerCleanup=f)}catch(t){}var b=l[n],y=function(t){try{if(!t)return 0;if("function"==typeof t&&"number"==typeof t.__extjsGeneration)return t.__extjsGeneration;if("object"==typeof t){if("number"==typeof t.__extjsGeneration)return t.__extjsGeneration;if("number"==typeof t.generation)return t.generation;if("function"==typeof t.cleanup&&"number"==typeof t.cleanup.__extjsGeneration)return t.cleanup.__extjsGeneration}}catch(t){}return 0}(b);try{try{"u"<typeof document||document.querySelectorAll}catch(t){}}catch(t){}try{var m="function"==typeof b?b:b&&"function"==typeof b.cleanup?b.cleanup:null;"function"==typeof m&&m()}catch(t){}try{h(!b)}catch(t){}function d(){try{var t="";try{"object"==typeof globalThis&&globalThis&&globalThis.browser&&globalThis.browser.runtime&&"function"==typeof globalThis.browser.runtime.getURL?t=String(globalThis.browser.runtime.getURL("/")):"object"==typeof globalThis&&globalThis&&globalThis.chrome&&globalThis.chrome.runtime&&"function"==typeof globalThis.chrome.runtime.getURL&&(t=String(globalThis.chrome.runtime.getURL("/")))}catch(t){}if(!t)try{"object"==typeof document&&document&&document.documentElement&&(t=String(document.documentElement.getAttribute("data-extjs-extension-base")||""))}catch(t){}if(!t)return!1;"/"!==t.charAt(t.length-1)&&(t+="/");try{r.p=t}catch(t){}try{r.b=t}catch(t){}return!0}catch(t){}return!1}try{if(!d()){var p=0,T=function(){try{if(d())return}catch(t){}p++<50&&setTimeout(T,100)};T()}}catch(t){}try{y=(Number(y)||0)+1}catch(t){}try{g(n,Number(y)||0,"executed")}catch(t){}try{!function(){try{if(0!==String(o||"").indexOf("content_scripts/content-")||"u"<typeof document||"function"!=typeof fetch)return;var t=Array.from(new Set((Array.isArray(u)?u:[]).concat([function(t){try{if("object"==typeof globalThis&&globalThis&&globalThis.browser&&globalThis.browser.runtime&&"function"==typeof globalThis.browser.runtime.getURL)return globalThis.browser.runtime.getURL(t);if("object"==typeof globalThis&&globalThis&&globalThis.chrome&&globalThis.chrome.runtime&&"function"==typeof globalThis.chrome.runtime.getURL)return globalThis.chrome.runtime.getURL(t)}catch(t){}try{var e="object"==typeof globalThis&&globalThis&&globalThis.__EXTJS_EXTENSION_BASE__?String(globalThis.__EXTJS_EXTENSION_BASE__):"";if(!e&&"object"==typeof document&&document&&document.documentElement&&(e=String(document.documentElement.getAttribute("data-extjs-extension-base")||"")),!e)return"";return e.replace(/\/+$/,"/")+String(t||"").replace(/^\/+/,"")}catch(t){}return""}(o+".css")]).filter(function(t){return"string"==typeof t&&t.trim().length>0})));if(!t.length)return;var e="",r=null,i=0,l=function(){try{for(var u=a(),s=Array.from(document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root="extension-js-devtools"])')),f=0;f<s.length;f++){var g=s[f];if(g&&g.shadowRoot&&"function"==typeof g.getAttribute){var h=String(g.getAttribute("data-extjs-reinject-owner")||"");if((!h||h===u)&&h&&(h||-1===c.indexOf(g))&&(!(!h&&String(g.getAttribute("data-extjs-reinject-key")||""))||String(g.getAttribute("data-extjs-reinject-key")||"")===String(o||""))){for(var b=g.shadowRoot,y=Array.from(b.querySelectorAll("style")),m=y.some(function(t){return t&&"true"!==t.getAttribute("data-extjs-bundle-css")&&String(t.textContent||"").trim().length>0}),d=null,p=0;p<y.length;p++)if(y[p]&&"true"===y[p].getAttribute("data-extjs-bundle-css")){var T=String(y[p].getAttribute("data-extjs-style-owner")||"");if(!T||T===u){d=y[p];break}}if(m){d&&d.parentNode&&d.parentNode.removeChild(d);return}if("string"==typeof e&&e.trim()){d||((d=document.createElement("style")).setAttribute("data-extjs-bundle-css","true"),d.setAttribute("data-extjs-reinject-key",String(n||"")),b.insertBefore(d,b.firstChild||null)),d.setAttribute("data-extjs-style-owner",u),String(d.textContent||"")!==e&&(d.textContent=e);return}}}}}catch(t){}i++<20&&(!r&&(r||(r=(function e(r){return r>=t.length?Promise.resolve(""):fetch(t[r]).then(function(t){return t&&t.ok?t.text():""}).catch(function(){return""}).then(function(t){return"string"==typeof t&&t.trim().length>0?t:e(r+1)})})(0).then(function(t){e="string"==typeof t?t:"";try{setTimeout(l,0)}catch(t){}return e}).catch(function(){return""}))),setTimeout(l,250))};l()}catch(t){}}()}catch(t){}try{l[n]={cleanup:function(){try{!function(t){try{if(!Array.isArray(t))return;for(var e=t.length-1;e>=0;e--)try{"function"==typeof t[e]&&t[e]()}catch(t){}}catch(t){}}(s)}catch(t){}try{h()}catch(t){}try{g(n,Number(y)||0,"cleaned")}catch(t){}},generation:Number(y)||0,build:i}}catch(t){}})();
@@ -1,6 +1,7 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
2
  import { createRequire } from "node:module";
3
3
  import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
4
+ import * as __rspack_external_node_path_c5b9b54f from "node:path";
4
5
  const requireModule = createRequire(import.meta.url);
5
6
  function transpileClassicTs(file, content) {
6
7
  const { experiments } = requireModule('@rspack/core');
@@ -38,7 +39,10 @@ const NON_CHILD_KEYS = new Set([
38
39
  'loc',
39
40
  'range'
40
41
  ]);
41
- function collectClassicGlobalNames(_file, content) {
42
+ function collectClassicGlobalNames(file, content) {
43
+ return collectClassicTopLevelBindings(file, content).map((binding)=>binding.name);
44
+ }
45
+ function collectClassicTopLevelBindings(_file, content) {
42
46
  const acorn = requireModule('acorn');
43
47
  const ast = acorn.parse(content, {
44
48
  ecmaVersion: 'latest',
@@ -47,24 +51,27 @@ function collectClassicGlobalNames(_file, content) {
47
51
  allowAwaitOutsideFunction: true,
48
52
  allowHashBang: true
49
53
  });
50
- const names = [];
51
- const addBindingNames = (node)=>{
54
+ const bindings = [];
55
+ const addBindingNames = (node, lexical)=>{
52
56
  if (!node || 'string' != typeof node.type) return;
53
57
  switch(node.type){
54
58
  case 'Identifier':
55
- names.push(String(node.name));
59
+ bindings.push({
60
+ name: String(node.name),
61
+ lexical
62
+ });
56
63
  return;
57
64
  case 'ObjectPattern':
58
- for (const prop of node.properties || [])if (prop) addBindingNames('RestElement' === prop.type ? prop.argument : prop.value);
65
+ for (const prop of node.properties || [])if (prop) addBindingNames('RestElement' === prop.type ? prop.argument : prop.value, lexical);
59
66
  return;
60
67
  case 'ArrayPattern':
61
- for (const element of node.elements || [])addBindingNames(element);
68
+ for (const element of node.elements || [])addBindingNames(element, lexical);
62
69
  return;
63
70
  case 'AssignmentPattern':
64
- addBindingNames(node.left);
71
+ addBindingNames(node.left, lexical);
65
72
  return;
66
73
  case 'RestElement':
67
- addBindingNames(node.argument);
74
+ addBindingNames(node.argument, lexical);
68
75
  return;
69
76
  default:
70
77
  return;
@@ -73,11 +80,14 @@ function collectClassicGlobalNames(_file, content) {
73
80
  const visit = (node, topLevel)=>{
74
81
  if (!node || 'string' != typeof node.type) return;
75
82
  if ('VariableDeclaration' === node.type) {
76
- if (topLevel || 'var' === node.kind) for (const declarator of node.declarations || [])addBindingNames(declarator.id);
83
+ if (topLevel || 'var' === node.kind) for (const declarator of node.declarations || [])addBindingNames(declarator.id, 'var' !== node.kind);
77
84
  return;
78
85
  }
79
86
  if ('FunctionDeclaration' === node.type || 'ClassDeclaration' === node.type) {
80
- if (topLevel && node.id) names.push(String(node.id.name));
87
+ if (topLevel && node.id) bindings.push({
88
+ name: String(node.id.name),
89
+ lexical: 'ClassDeclaration' === node.type
90
+ });
81
91
  return;
82
92
  }
83
93
  if (OPAQUE_SCOPES.has(node.type)) return;
@@ -89,7 +99,57 @@ function collectClassicGlobalNames(_file, content) {
89
99
  }
90
100
  };
91
101
  for (const statement of ast.body)visit(statement, true);
92
- return names;
102
+ return bindings;
103
+ }
104
+ function findClassicRedeclarations(perFile) {
105
+ const seen = new Map();
106
+ const collisions = [];
107
+ for (const { file, bindings } of perFile){
108
+ const inThisFile = new Map();
109
+ for (const binding of bindings)if (inThisFile.has(binding.name)) {
110
+ if (binding.lexical) inThisFile.set(binding.name, true);
111
+ } else inThisFile.set(binding.name, binding.lexical);
112
+ for (const [name, lexical] of inThisFile){
113
+ const previous = seen.get(name);
114
+ if (!previous) {
115
+ seen.set(name, {
116
+ files: [
117
+ file
118
+ ],
119
+ lexical
120
+ });
121
+ continue;
122
+ }
123
+ previous.files.push(file);
124
+ if (previous.lexical || lexical) {
125
+ previous.lexical = true;
126
+ if (2 === previous.files.length) collisions.push({
127
+ name,
128
+ files: previous.files
129
+ });
130
+ }
131
+ }
132
+ }
133
+ return collisions.map(({ name, files })=>({
134
+ name,
135
+ files: [
136
+ ...files
137
+ ]
138
+ }));
139
+ }
140
+ function displayPath(file) {
141
+ const relative = __rspack_external_node_path_c5b9b54f.relative(process.cwd(), file);
142
+ const shown = relative && !relative.startsWith('..') ? relative : file;
143
+ return shown.split(__rspack_external_node_path_c5b9b54f.sep).join('/');
144
+ }
145
+ function redeclarationMessage(name, files, feature) {
146
+ const where = feature ? ` of ${feature}` : '';
147
+ return [
148
+ `Two files${where} declare ${name} at the top level, and at least one uses let, const, or class.`,
149
+ ...files.map((file)=>`FILE ${displayPath(file)}`),
150
+ 'The browser evaluates these files in one shared scope, so the second declaration is a SyntaxError and none of the bundle runs.',
151
+ 'Rename one of them, or move the shared value into a single file.'
152
+ ].join('\n');
93
153
  }
94
154
  const BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
95
155
  const CONCAT_UMD_WRAP_OPEN = ';(function (module, exports, define, require) {';
@@ -135,12 +195,18 @@ function classicConcatLoader(_source) {
135
195
  lineMappings.push(null);
136
196
  }
137
197
  const globalNames = [];
198
+ const perFileBindings = [];
138
199
  for(let fileIdx = 0; fileIdx < jsFiles.length; fileIdx++){
139
200
  const file = jsFiles[fileIdx];
140
201
  const raw = __rspack_external_node_fs_5ea92f0c.readFileSync(file, 'utf8');
141
202
  const content = /\.ts$/i.test(file) ? transpileClassicTs(file, raw) : raw;
142
203
  try {
143
- globalNames.push(...collectClassicGlobalNames(file, content));
204
+ const bindings = collectClassicTopLevelBindings(file, content);
205
+ perFileBindings.push({
206
+ file,
207
+ bindings
208
+ });
209
+ globalNames.push(...bindings.map((binding)=>binding.name));
144
210
  } catch {}
145
211
  sources.push(file);
146
212
  sourcesContent.push(raw);
@@ -159,6 +225,12 @@ function classicConcatLoader(_source) {
159
225
  lineMappings.push(null);
160
226
  }
161
227
  }
228
+ for (const { name, files } of findClassicRedeclarations(perFileBindings)){
229
+ const report = new Error(redeclarationMessage(name, files, feature));
230
+ report.file = displayPath(files[0]);
231
+ if (this._compilation?.errors) this._compilation.errors.push(report);
232
+ else this.emitError?.(report);
233
+ }
162
234
  const exposedNames = [
163
235
  ...new Set(globalNames)
164
236
  ].filter((name)=>!EXPOSE_SKIP.has(name) && /^[A-Za-z_$][\w$]*$/.test(name));
@@ -194,4 +266,4 @@ function classicConcatLoader(_source) {
194
266
  this.callback(null, output, sourceMap);
195
267
  }
196
268
  export default classicConcatLoader;
197
- export { collectClassicGlobalNames };
269
+ export { collectClassicGlobalNames, collectClassicTopLevelBindings, findClassicRedeclarations };
@@ -1,6 +1,7 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
2
  import { createRequire } from "node:module";
3
3
  import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
4
+ import * as __rspack_external_node_path_c5b9b54f from "node:path";
4
5
  const requireModule = createRequire(import.meta.url);
5
6
  function transpileClassicTs(file, content) {
6
7
  const { experiments } = requireModule('@rspack/core');
@@ -38,7 +39,10 @@ const NON_CHILD_KEYS = new Set([
38
39
  'loc',
39
40
  'range'
40
41
  ]);
41
- function collectClassicGlobalNames(_file, content) {
42
+ function collectClassicGlobalNames(file, content) {
43
+ return collectClassicTopLevelBindings(file, content).map((binding)=>binding.name);
44
+ }
45
+ function collectClassicTopLevelBindings(_file, content) {
42
46
  const acorn = requireModule('acorn');
43
47
  const ast = acorn.parse(content, {
44
48
  ecmaVersion: 'latest',
@@ -47,24 +51,27 @@ function collectClassicGlobalNames(_file, content) {
47
51
  allowAwaitOutsideFunction: true,
48
52
  allowHashBang: true
49
53
  });
50
- const names = [];
51
- const addBindingNames = (node)=>{
54
+ const bindings = [];
55
+ const addBindingNames = (node, lexical)=>{
52
56
  if (!node || 'string' != typeof node.type) return;
53
57
  switch(node.type){
54
58
  case 'Identifier':
55
- names.push(String(node.name));
59
+ bindings.push({
60
+ name: String(node.name),
61
+ lexical
62
+ });
56
63
  return;
57
64
  case 'ObjectPattern':
58
- for (const prop of node.properties || [])if (prop) addBindingNames('RestElement' === prop.type ? prop.argument : prop.value);
65
+ for (const prop of node.properties || [])if (prop) addBindingNames('RestElement' === prop.type ? prop.argument : prop.value, lexical);
59
66
  return;
60
67
  case 'ArrayPattern':
61
- for (const element of node.elements || [])addBindingNames(element);
68
+ for (const element of node.elements || [])addBindingNames(element, lexical);
62
69
  return;
63
70
  case 'AssignmentPattern':
64
- addBindingNames(node.left);
71
+ addBindingNames(node.left, lexical);
65
72
  return;
66
73
  case 'RestElement':
67
- addBindingNames(node.argument);
74
+ addBindingNames(node.argument, lexical);
68
75
  return;
69
76
  default:
70
77
  return;
@@ -73,11 +80,14 @@ function collectClassicGlobalNames(_file, content) {
73
80
  const visit = (node, topLevel)=>{
74
81
  if (!node || 'string' != typeof node.type) return;
75
82
  if ('VariableDeclaration' === node.type) {
76
- if (topLevel || 'var' === node.kind) for (const declarator of node.declarations || [])addBindingNames(declarator.id);
83
+ if (topLevel || 'var' === node.kind) for (const declarator of node.declarations || [])addBindingNames(declarator.id, 'var' !== node.kind);
77
84
  return;
78
85
  }
79
86
  if ('FunctionDeclaration' === node.type || 'ClassDeclaration' === node.type) {
80
- if (topLevel && node.id) names.push(String(node.id.name));
87
+ if (topLevel && node.id) bindings.push({
88
+ name: String(node.id.name),
89
+ lexical: 'ClassDeclaration' === node.type
90
+ });
81
91
  return;
82
92
  }
83
93
  if (OPAQUE_SCOPES.has(node.type)) return;
@@ -89,7 +99,57 @@ function collectClassicGlobalNames(_file, content) {
89
99
  }
90
100
  };
91
101
  for (const statement of ast.body)visit(statement, true);
92
- return names;
102
+ return bindings;
103
+ }
104
+ function findClassicRedeclarations(perFile) {
105
+ const seen = new Map();
106
+ const collisions = [];
107
+ for (const { file, bindings } of perFile){
108
+ const inThisFile = new Map();
109
+ for (const binding of bindings)if (inThisFile.has(binding.name)) {
110
+ if (binding.lexical) inThisFile.set(binding.name, true);
111
+ } else inThisFile.set(binding.name, binding.lexical);
112
+ for (const [name, lexical] of inThisFile){
113
+ const previous = seen.get(name);
114
+ if (!previous) {
115
+ seen.set(name, {
116
+ files: [
117
+ file
118
+ ],
119
+ lexical
120
+ });
121
+ continue;
122
+ }
123
+ previous.files.push(file);
124
+ if (previous.lexical || lexical) {
125
+ previous.lexical = true;
126
+ if (2 === previous.files.length) collisions.push({
127
+ name,
128
+ files: previous.files
129
+ });
130
+ }
131
+ }
132
+ }
133
+ return collisions.map(({ name, files })=>({
134
+ name,
135
+ files: [
136
+ ...files
137
+ ]
138
+ }));
139
+ }
140
+ function displayPath(file) {
141
+ const relative = __rspack_external_node_path_c5b9b54f.relative(process.cwd(), file);
142
+ const shown = relative && !relative.startsWith('..') ? relative : file;
143
+ return shown.split(__rspack_external_node_path_c5b9b54f.sep).join('/');
144
+ }
145
+ function redeclarationMessage(name, files, feature) {
146
+ const where = feature ? ` of ${feature}` : '';
147
+ return [
148
+ `Two files${where} declare ${name} at the top level, and at least one uses let, const, or class.`,
149
+ ...files.map((file)=>`FILE ${displayPath(file)}`),
150
+ 'The browser evaluates these files in one shared scope, so the second declaration is a SyntaxError and none of the bundle runs.',
151
+ 'Rename one of them, or move the shared value into a single file.'
152
+ ].join('\n');
93
153
  }
94
154
  const BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
95
155
  const CONCAT_UMD_WRAP_OPEN = ';(function (module, exports, define, require) {';
@@ -135,12 +195,18 @@ function classicConcatLoader(_source) {
135
195
  lineMappings.push(null);
136
196
  }
137
197
  const globalNames = [];
198
+ const perFileBindings = [];
138
199
  for(let fileIdx = 0; fileIdx < jsFiles.length; fileIdx++){
139
200
  const file = jsFiles[fileIdx];
140
201
  const raw = __rspack_external_node_fs_5ea92f0c.readFileSync(file, 'utf8');
141
202
  const content = /\.ts$/i.test(file) ? transpileClassicTs(file, raw) : raw;
142
203
  try {
143
- globalNames.push(...collectClassicGlobalNames(file, content));
204
+ const bindings = collectClassicTopLevelBindings(file, content);
205
+ perFileBindings.push({
206
+ file,
207
+ bindings
208
+ });
209
+ globalNames.push(...bindings.map((binding)=>binding.name));
144
210
  } catch {}
145
211
  sources.push(file);
146
212
  sourcesContent.push(raw);
@@ -159,6 +225,12 @@ function classicConcatLoader(_source) {
159
225
  lineMappings.push(null);
160
226
  }
161
227
  }
228
+ for (const { name, files } of findClassicRedeclarations(perFileBindings)){
229
+ const report = new Error(redeclarationMessage(name, files, feature));
230
+ report.file = displayPath(files[0]);
231
+ if (this._compilation?.errors) this._compilation.errors.push(report);
232
+ else this.emitError?.(report);
233
+ }
162
234
  const exposedNames = [
163
235
  ...new Set(globalNames)
164
236
  ].filter((name)=>!EXPOSE_SKIP.has(name) && /^[A-Za-z_$][\w$]*$/.test(name));
@@ -194,4 +266,4 @@ function classicConcatLoader(_source) {
194
266
  this.callback(null, output, sourceMap);
195
267
  }
196
268
  export default classicConcatLoader;
197
- export { collectClassicGlobalNames };
269
+ export { collectClassicGlobalNames, collectClassicTopLevelBindings, findClassicRedeclarations };
@@ -7,6 +7,7 @@ export interface PreprocessorUsage {
7
7
  interface BuildCssRulesOptions {
8
8
  nonModuleType: 'asset/inline' | 'css';
9
9
  issuer: (issuer: string) => boolean;
10
+ manifestPath?: string;
10
11
  }
11
12
  export declare function buildCssRules(projectPath: string, mode: DevOptions['mode'], usage: PreprocessorUsage, opts: BuildCssRulesOptions): Promise<RuleSetRule[]>;
12
13
  export {};
@@ -0,0 +1,9 @@
1
+ export declare function toPosixPath(value: string): string;
2
+ export interface DeadUrlRefContext {
3
+ issuerDir: string;
4
+ roots: string[];
5
+ }
6
+ /** True when the reference names no file under the issuer or any project root. */
7
+ export declare function isDeadCssUrlRef(rawRequest: string, { issuerDir, roots }: DeadUrlRefContext): boolean;
8
+ /** Every url() target in a stylesheet, in source order, duplicates collapsed. */
9
+ export declare function extractCssUrlRefs(source: string): string[];
@@ -0,0 +1,16 @@
1
+ interface CompilationLike {
2
+ warnings?: Error[];
3
+ errors?: Error[];
4
+ }
5
+ interface DeadCssUrlLoaderContext {
6
+ resourcePath: string;
7
+ getOptions(): {
8
+ manifestPath?: string;
9
+ projectPath?: string;
10
+ };
11
+ emitWarning(warning: Error): void;
12
+ emitError(error: Error): void;
13
+ _compilation?: CompilationLike;
14
+ }
15
+ export default function deadCssUrlLoader(this: DeadCssUrlLoaderContext, source: string): string;
16
+ export {};
@@ -1,9 +1,25 @@
1
- export declare function collectClassicGlobalNames(_file: string, content: string): string[];
1
+ export interface ClassicTopLevelBinding {
2
+ name: string;
3
+ lexical: boolean;
4
+ }
5
+ export declare function collectClassicGlobalNames(file: string, content: string): string[];
6
+ export declare function collectClassicTopLevelBindings(_file: string, content: string): ClassicTopLevelBinding[];
2
7
  interface ClassicConcatLoaderContext {
3
8
  resourcePath: string;
4
9
  resourceQuery: string;
5
10
  addDependency(dep: string): void;
6
11
  callback(err: Error | null, content?: string, sourceMap?: unknown): void;
12
+ emitError?(error: Error): void;
13
+ _compilation?: {
14
+ errors?: Error[];
15
+ };
7
16
  }
17
+ export declare function findClassicRedeclarations(perFile: Array<{
18
+ file: string;
19
+ bindings: ClassicTopLevelBinding[];
20
+ }>): Array<{
21
+ name: string;
22
+ files: string[];
23
+ }>;
8
24
  export default function classicConcatLoader(this: ClassicConcatLoaderContext, _source: string): void;
9
25
  export {};
@@ -1,4 +1,4 @@
1
1
  import { type Compiler } from '@rspack/core';
2
- export declare class ValidateContentScriptSyntax {
2
+ export declare class ValidateEmittedScriptSyntax {
3
3
  apply(compiler: Compiler): void;
4
4
  }
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "runtime"
44
44
  ],
45
45
  "name": "extension-develop",
46
- "version": "4.1.5",
46
+ "version": "4.1.6",
47
47
  "description": "Develop, build, preview, and package Extension.js projects.",
48
48
  "author": {
49
49
  "name": "Cezar Augusto",