@nuxt/webpack-builder 3.5.1 → 3.5.3

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.mjs +133 -9
  3. package/package.json +18 -17
package/README.md CHANGED
@@ -115,7 +115,7 @@ Follow the docs to [Set Up Your Local Development Environment](https://nuxt.com/
115
115
 
116
116
  ## Nuxt 2
117
117
 
118
- You can find the code for Nuxt 2 on the [`2.x` branch](https://github.com/nuxt/nuxt/tree/2.x) and the documentation at [nuxtjs.org](https://nuxtjs.org).
118
+ You can find the code for Nuxt 2 on the [`2.x` branch](https://github.com/nuxt/nuxt/tree/2.x) and the documentation at [v2.nuxt.com](https://v2.nuxt.com).
119
119
 
120
120
  ## Follow us
121
121
 
package/dist/index.mjs CHANGED
@@ -13,6 +13,7 @@ import MagicString from 'magic-string';
13
13
  import { hash } from 'ohash';
14
14
  import escapeRE from 'escape-string-regexp';
15
15
  import { findStaticImports, parseStaticImport, createCommonJS } from 'mlly';
16
+ import 'node:fs';
16
17
  import { createFsFromVolume, Volume } from 'memfs';
17
18
  import VirtualModulesPlugin from 'webpack-virtual-modules';
18
19
  import querystring from 'node:querystring';
@@ -31,7 +32,18 @@ import { normalizeWebpackManifest } from 'vue-bundle-renderer';
31
32
  import hash$1 from 'hash-sum';
32
33
  import fse from 'fs-extra';
33
34
 
35
+ function matchWithStringOrRegex(value, matcher) {
36
+ if (typeof matcher === "string") {
37
+ return value === matcher;
38
+ } else if (matcher instanceof RegExp) {
39
+ return matcher.test(value);
40
+ }
41
+ return false;
42
+ }
43
+
34
44
  const stringTypes = ["Literal", "TemplateLiteral"];
45
+ const NUXT_LIB_RE = /node_modules\/nuxt3?\//;
46
+ const SUPPORTED_EXT_RE = /\.(m?[jt]sx?|vue)/;
35
47
  const composableKeysPlugin = createUnplugin((options) => {
36
48
  const composableMeta = Object.fromEntries(options.composables.map(({ name, ...meta }) => [name, meta]));
37
49
  const maxLength = Math.max(...options.composables.map(({ argumentLength }) => argumentLength));
@@ -42,7 +54,7 @@ const composableKeysPlugin = createUnplugin((options) => {
42
54
  enforce: "post",
43
55
  transformInclude(id) {
44
56
  const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
45
- return !pathname.match(/node_modules\/nuxt3?\//) && pathname.match(/\.(m?[jt]sx?|vue)/) && parseQuery(search).type !== "style" && !parseQuery(search).macro;
57
+ return !NUXT_LIB_RE.test(pathname) && SUPPORTED_EXT_RE.test(pathname) && parseQuery(search).type !== "style" && !parseQuery(search).macro;
46
58
  },
47
59
  transform(code, id) {
48
60
  if (!KEYED_FUNCTIONS_RE.test(code)) {
@@ -53,11 +65,37 @@ const composableKeysPlugin = createUnplugin((options) => {
53
65
  let imports;
54
66
  let count = 0;
55
67
  const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id;
56
- walk(this.parse(script, {
68
+ const { pathname: relativePathname } = parseURL(relativeID);
69
+ const ast = this.parse(script, {
57
70
  sourceType: "module",
58
71
  ecmaVersion: "latest"
59
- }), {
72
+ });
73
+ let scopeTracker = new ScopeTracker();
74
+ const varCollector = new ScopedVarsCollector();
75
+ walk(ast, {
76
+ enter(_node) {
77
+ if (_node.type === "BlockStatement") {
78
+ scopeTracker.enterScope();
79
+ varCollector.refresh(scopeTracker.curScopeKey);
80
+ } else if (_node.type === "FunctionDeclaration" && _node.id) {
81
+ varCollector.addVar(_node.id.name);
82
+ } else if (_node.type === "VariableDeclarator") {
83
+ varCollector.collect(_node.id);
84
+ }
85
+ },
86
+ leave(_node) {
87
+ if (_node.type === "BlockStatement") {
88
+ scopeTracker.leaveScope();
89
+ varCollector.refresh(scopeTracker.curScopeKey);
90
+ }
91
+ }
92
+ });
93
+ scopeTracker = new ScopeTracker();
94
+ walk(ast, {
60
95
  enter(_node) {
96
+ if (_node.type === "BlockStatement") {
97
+ scopeTracker.enterScope();
98
+ }
61
99
  if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") {
62
100
  return;
63
101
  }
@@ -66,11 +104,20 @@ const composableKeysPlugin = createUnplugin((options) => {
66
104
  if (!name || !keyedFunctions.has(name) || node.arguments.length >= maxLength) {
67
105
  return;
68
106
  }
69
- imports = imports || detectImportNames(script);
107
+ imports = imports || detectImportNames(script, composableMeta);
70
108
  if (imports.has(name)) {
71
109
  return;
72
110
  }
73
111
  const meta = composableMeta[name];
112
+ if (varCollector.hasVar(scopeTracker.curScopeKey, name)) {
113
+ let skip = true;
114
+ if (meta.source) {
115
+ skip = !matchWithStringOrRegex(relativePathname, meta.source);
116
+ }
117
+ if (skip) {
118
+ return;
119
+ }
120
+ }
74
121
  if (node.arguments.length >= meta.argumentLength) {
75
122
  return;
76
123
  }
@@ -98,6 +145,11 @@ const composableKeysPlugin = createUnplugin((options) => {
98
145
  codeIndex + node.end - 1,
99
146
  (node.arguments.length && !endsWithComma ? ", " : "") + "'$" + hash(`${relativeID}-${++count}`) + "'"
100
147
  );
148
+ },
149
+ leave(_node) {
150
+ if (_node.type === "BlockStatement") {
151
+ scopeTracker.leaveScope();
152
+ }
101
153
  }
102
154
  });
103
155
  if (s.hasChanged()) {
@@ -109,23 +161,94 @@ const composableKeysPlugin = createUnplugin((options) => {
109
161
  }
110
162
  };
111
163
  });
164
+ class ScopeTracker {
165
+ constructor() {
166
+ this.scopeIndexStack = [0];
167
+ this.curScopeKey = "0";
168
+ }
169
+ getKey() {
170
+ return this.scopeIndexStack.slice(0, -1).join("-");
171
+ }
172
+ enterScope() {
173
+ this.scopeIndexStack.push(0);
174
+ this.curScopeKey = this.getKey();
175
+ }
176
+ leaveScope() {
177
+ this.scopeIndexStack.pop();
178
+ this.curScopeKey = this.getKey();
179
+ this.scopeIndexStack[this.scopeIndexStack.length - 1]++;
180
+ }
181
+ }
182
+ class ScopedVarsCollector {
183
+ constructor() {
184
+ this.all = /* @__PURE__ */ new Map();
185
+ this.curScopeKey = "0";
186
+ }
187
+ refresh(scopeKey) {
188
+ this.curScopeKey = scopeKey;
189
+ }
190
+ addVar(name) {
191
+ let vars = this.all.get(this.curScopeKey);
192
+ if (!vars) {
193
+ vars = /* @__PURE__ */ new Set();
194
+ this.all.set(this.curScopeKey, vars);
195
+ }
196
+ vars.add(name);
197
+ }
198
+ hasVar(scopeKey, name) {
199
+ const indices = scopeKey.split("-").map(Number);
200
+ for (let i = indices.length; i > 0; i--) {
201
+ if (this.all.get(indices.slice(0, i).join("-"))?.has(name)) {
202
+ return true;
203
+ }
204
+ }
205
+ return false;
206
+ }
207
+ collect(n) {
208
+ const t = n.type;
209
+ if (t === "Identifier") {
210
+ this.addVar(n.name);
211
+ } else if (t === "RestElement") {
212
+ this.collect(n.argument);
213
+ } else if (t === "AssignmentPattern") {
214
+ this.collect(n.left);
215
+ } else if (t === "ArrayPattern") {
216
+ n.elements.forEach((e) => e && this.collect(e));
217
+ } else if (t === "ObjectPattern") {
218
+ n.properties.forEach((p) => {
219
+ if (p.type === "RestElement") {
220
+ this.collect(p);
221
+ } else {
222
+ this.collect(p.value);
223
+ }
224
+ });
225
+ }
226
+ }
227
+ }
112
228
  const NUXT_IMPORT_RE = /nuxt|#app|#imports/;
113
- function detectImportNames(code) {
229
+ function detectImportNames(code, composableMeta) {
114
230
  const imports = findStaticImports(code);
115
231
  const names = /* @__PURE__ */ new Set();
116
232
  for (const i of imports) {
233
+ let addName = function(name) {
234
+ const source = composableMeta[name]?.source;
235
+ if (source && matchWithStringOrRegex(i.specifier, source)) {
236
+ return;
237
+ }
238
+ names.add(namedImports[name]);
239
+ };
117
240
  if (NUXT_IMPORT_RE.test(i.specifier)) {
118
241
  continue;
119
242
  }
120
243
  const { namedImports, defaultImport, namespacedImport } = parseStaticImport(i);
121
244
  for (const name in namedImports || {}) {
122
- names.add(namedImports[name]);
245
+ addName(namedImports[name]);
123
246
  }
124
247
  if (defaultImport) {
125
- names.add(defaultImport);
248
+ addName(defaultImport);
126
249
  }
127
250
  if (namespacedImport) {
128
- names.add(namespacedImport);
251
+ addName(namespacedImport);
129
252
  }
130
253
  }
131
254
  return names;
@@ -826,6 +949,7 @@ class VueSSRClientPlugin {
826
949
  }
827
950
  }
828
951
 
952
+ const JS_MAP_RE = /\.js\.map$/;
829
953
  class VueSSRServerPlugin {
830
954
  constructor(options = {}) {
831
955
  this.options = Object.assign({
@@ -870,7 +994,7 @@ class VueSSRServerPlugin {
870
994
  } else {
871
995
  bundle.files[asset.name] = asset.name;
872
996
  }
873
- } else if (asset.name.match(/\.js\.map$/)) {
997
+ } else if (JS_MAP_RE.test(asset.name)) {
874
998
  bundle.maps[asset.name.replace(/\.map$/, "")] = asset.name;
875
999
  } else {
876
1000
  delete assets[asset.name];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/webpack-builder",
3
- "version": "3.5.1",
3
+ "version": "3.5.3",
4
4
  "repository": "nuxt/nuxt",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,7 @@
18
18
  "dependencies": {
19
19
  "@nuxt/friendly-errors-webpack-plugin": "^2.5.2",
20
20
  "autoprefixer": "^10.4.14",
21
- "css-loader": "^6.7.4",
21
+ "css-loader": "^6.8.1",
22
22
  "css-minimizer-webpack-plugin": "^5.0.0",
23
23
  "cssnano": "^6.0.1",
24
24
  "esbuild-loader": "^3.0.1",
@@ -31,15 +31,15 @@
31
31
  "hash-sum": "^2.0.0",
32
32
  "lodash-es": "^4.17.21",
33
33
  "magic-string": "^0.30.0",
34
- "memfs": "^3.5.1",
34
+ "memfs": "^3.5.2",
35
35
  "mini-css-extract-plugin": "^2.7.6",
36
- "mlly": "^1.2.1",
36
+ "mlly": "^1.3.0",
37
37
  "ohash": "^1.1.2",
38
- "pathe": "^1.1.0",
38
+ "pathe": "^1.1.1",
39
39
  "pify": "^6.1.0",
40
- "postcss": "^8.4.23",
40
+ "postcss": "^8.4.24",
41
41
  "postcss-import": "^15.1.0",
42
- "postcss-loader": "^7.3.0",
42
+ "postcss-loader": "^7.3.2",
43
43
  "postcss-url": "^10.1.3",
44
44
  "std-env": "^3.3.3",
45
45
  "time-fix-plugin": "^2.0.7",
@@ -47,24 +47,25 @@
47
47
  "unplugin": "^1.3.1",
48
48
  "url-loader": "^4.1.1",
49
49
  "vue-bundle-renderer": "^1.0.3",
50
- "vue-loader": "^17.1.1",
51
- "webpack": "^5.83.1",
52
- "webpack-bundle-analyzer": "^4.8.0",
50
+ "vue-loader": "^17.2.2",
51
+ "webpack": "^5.85.1",
52
+ "webpack-bundle-analyzer": "^4.9.0",
53
53
  "webpack-dev-middleware": "^6.1.1",
54
54
  "webpack-hot-middleware": "^2.25.3",
55
55
  "webpack-virtual-modules": "^0.5.0",
56
56
  "webpackbar": "^5.0.2",
57
- "@nuxt/kit": "3.5.1"
57
+ "@nuxt/kit": "3.5.3"
58
58
  },
59
59
  "devDependencies": {
60
- "@types/lodash-es": "^4.17.7",
61
- "@types/pify": "^5.0.1",
62
- "@types/webpack-bundle-analyzer": "^4.6.0",
63
- "@types/webpack-hot-middleware": "^2.25.6",
64
- "@types/webpack-virtual-modules": "^0.1.1",
60
+ "@types/fs-extra": "11.0.1",
61
+ "@types/lodash-es": "4.17.7",
62
+ "@types/pify": "5.0.1",
63
+ "@types/webpack-bundle-analyzer": "4.6.0",
64
+ "@types/webpack-hot-middleware": "2.25.6",
65
+ "@types/webpack-virtual-modules": "0.1.1",
65
66
  "unbuild": "latest",
66
67
  "vue": "3.3.4",
67
- "@nuxt/schema": "3.5.1"
68
+ "@nuxt/schema": "3.5.3"
68
69
  },
69
70
  "peerDependencies": {
70
71
  "vue": "^3.3.4"