@nuxt/webpack-builder 3.0.0-rc.4 → 3.0.0-rc.7

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 (2) hide show
  1. package/dist/index.mjs +163 -106
  2. package/package.json +20 -17
package/dist/index.mjs CHANGED
@@ -2,66 +2,74 @@ import pify from 'pify';
2
2
  import webpack from 'webpack';
3
3
  import webpackDevMiddleware from 'webpack-dev-middleware';
4
4
  import webpackHotMiddleware from 'webpack-hot-middleware';
5
- import { joinURL } from 'ufo';
5
+ import { parseURL, joinURL } from 'ufo';
6
6
  import { useNuxt, logger, requireModule } from '@nuxt/kit';
7
+ import { pathToFileURL } from 'node:url';
7
8
  import { createUnplugin } from 'unplugin';
8
- import escapeRE from 'escape-string-regexp';
9
+ import { isAbsolute, relative, join, resolve, normalize, dirname } from 'pathe';
10
+ import { walk } from 'estree-walker';
9
11
  import MagicString from 'magic-string';
10
- import { join, resolve, normalize, dirname, isAbsolute } from 'pathe';
12
+ import { hash } from 'ohash';
11
13
  import { createFsFromVolume, Volume } from 'memfs';
12
14
  import VirtualModulesPlugin from 'webpack-virtual-modules';
13
15
  import querystring from 'node:querystring';
14
16
  import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
15
- import { cloneDeep, defaults, merge, uniq } from 'lodash-es';
17
+ import { cloneDeep, defaults as defaults$1, merge, uniq } from 'lodash-es';
16
18
  import TimeFixPlugin from 'time-fix-plugin';
17
19
  import WebpackBar from 'webpackbar';
18
20
  import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin';
21
+ import escapeRegExp from 'escape-string-regexp';
19
22
  import esbuildLoader from 'esbuild-loader';
20
23
  import MiniCssExtractPlugin from 'mini-css-extract-plugin';
21
24
  import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
22
25
  import { createCommonJS } from 'mlly';
23
26
  import VueLoaderPlugin from 'vue-loader/dist/pluginWebpack5.js';
24
- import hash from 'hash-sum';
27
+ import { normalizeWebpackManifest } from 'vue-bundle-renderer';
28
+ import hash$1 from 'hash-sum';
25
29
  import fse from 'fs-extra';
26
30
  import ForkTSCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
27
31
 
28
- const VITE_ASSET_RE = /^export default ["'](__VITE_ASSET.*)["']$/;
29
- const DynamicBasePlugin = createUnplugin(function(options = {}) {
32
+ const keyedFunctions = [
33
+ "useState",
34
+ "useFetch",
35
+ "useAsyncData",
36
+ "useLazyAsyncData",
37
+ "useLazyFetch"
38
+ ];
39
+ const KEYED_FUNCTIONS_RE = new RegExp(`(${keyedFunctions.join("|")})`);
40
+ const composableKeysPlugin = createUnplugin((options = {}) => {
30
41
  return {
31
- name: "nuxt:dynamic-base-path",
32
- resolveId(id) {
33
- if (id.startsWith("/__NUXT_BASE__")) {
34
- return id.replace("/__NUXT_BASE__", "");
35
- }
36
- if (id === "#internal/nitro") {
37
- return "#internal/nitro";
38
- }
39
- return null;
40
- },
42
+ name: "nuxt:composable-keys",
41
43
  enforce: "post",
42
44
  transform(code, id) {
43
- const s = new MagicString(code);
44
- if (options.globalPublicPath && id.includes("paths.mjs") && code.includes("const appConfig = ")) {
45
- s.append(`${options.globalPublicPath} = buildAssetsURL();
46
- `);
47
- }
48
- const assetId = code.match(VITE_ASSET_RE);
49
- if (assetId) {
50
- s.overwrite(0, code.length, [
51
- "import { buildAssetsURL } from '#build/paths.mjs';",
52
- `export default buildAssetsURL("${assetId[1]}".replace("/__NUXT_BASE__", ""));`
53
- ].join("\n"));
45
+ const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
46
+ if (!pathname.match(/\.(m?[jt]sx?|vue)/)) {
47
+ return;
54
48
  }
55
- if (!id.includes("paths.mjs") && code.includes("NUXT_BASE") && !code.includes("import { publicAssetsURL as __publicAssetsURL }")) {
56
- s.prepend("import { publicAssetsURL as __publicAssetsURL } from '#build/paths.mjs';\n");
49
+ if (!KEYED_FUNCTIONS_RE.test(code)) {
50
+ return;
57
51
  }
58
- if (id === "vite/preload-helper") {
59
- s.prepend("import { buildAssetsURL } from '#build/paths.mjs';\n");
60
- s.replace(/const base = ['"]\/__NUXT_BASE__\/['"]/, "const base = buildAssetsURL()");
61
- }
62
- s.replace(/from *['"]\/__NUXT_BASE__(\/[^'"]*)['"]/g, 'from "$1"');
63
- const delimiterRE = /(?<!(const base = |from *))((?<!\\)`([^`]*)\/__NUXT_BASE__\/([^`]*)(?<!\\)`|(?<!\\)'([^\n']*)\/__NUXT_BASE__\/([^\n']*)(?<!\\)'|(?<!\\)"([^\n"]*)\/__NUXT_BASE__\/([^\n"]*)(?<!\\)")/g;
64
- s.replace(delimiterRE, (r) => "`" + r.replace(/\/__NUXT_BASE__\//g, "${__publicAssetsURL()}").slice(1, -1) + "`");
52
+ const { 0: script = code, index: codeIndex = 0 } = code.match(/(?<=<script[^>]*>)[\S\s.]*?(?=<\/script>)/) || [];
53
+ const s = new MagicString(code);
54
+ let count = 0;
55
+ const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id;
56
+ walk(this.parse(script, {
57
+ sourceType: "module",
58
+ ecmaVersion: "latest"
59
+ }), {
60
+ enter(node) {
61
+ if (node.type !== "CallExpression" || node.callee.type !== "Identifier") {
62
+ return;
63
+ }
64
+ if (keyedFunctions.includes(node.callee.name) && node.arguments.length < 4) {
65
+ const end = node.end;
66
+ s.appendLeft(
67
+ codeIndex + end - 1,
68
+ (node.arguments.length ? ", " : "") + "'$" + hash(`${relativeID}-${++count}`) + "'"
69
+ );
70
+ }
71
+ }
72
+ });
65
73
  if (s.hasChanged()) {
66
74
  return {
67
75
  code: s.toString(),
@@ -72,6 +80,30 @@ const DynamicBasePlugin = createUnplugin(function(options = {}) {
72
80
  };
73
81
  });
74
82
 
83
+ const defaults = {
84
+ globalPublicPath: "__webpack_public_path__",
85
+ sourcemap: true
86
+ };
87
+ const DynamicBasePlugin = createUnplugin((options = {}) => {
88
+ options = { ...defaults, ...options };
89
+ return {
90
+ name: "nuxt:dynamic-base-path",
91
+ enforce: "post",
92
+ transform(code, id) {
93
+ if (!id.includes("paths.mjs") || !code.includes("const appConfig = ")) {
94
+ return;
95
+ }
96
+ const s = new MagicString(code);
97
+ s.append(`${options.globalPublicPath} = buildAssetsURL();
98
+ `);
99
+ return {
100
+ code: s.toString(),
101
+ map: options.sourcemap && s.generateMap({ source: id, includeContent: true })
102
+ };
103
+ }
104
+ };
105
+ });
106
+
75
107
  function createMFS() {
76
108
  const fs = createFsFromVolume(new Volume());
77
109
  const _fs = { ...fs };
@@ -145,7 +177,11 @@ function getWebpackConfig(ctx) {
145
177
  const loaders = [];
146
178
  const { extend } = options.build;
147
179
  if (typeof extend === "function") {
148
- const extendedConfig = extend.call(builder, config, { loaders, ...ctx }) || config;
180
+ const extendedConfig = extend.call(
181
+ builder,
182
+ config,
183
+ { loaders, ...ctx }
184
+ ) || config;
149
185
  const pragma = /@|#/;
150
186
  const { devtool } = extendedConfig;
151
187
  if (typeof devtool === "string" && pragma.test(devtool)) {
@@ -158,34 +194,38 @@ function getWebpackConfig(ctx) {
158
194
  }
159
195
 
160
196
  function assets(ctx) {
161
- ctx.config.module.rules.push({
162
- test: /\.(png|jpe?g|gif|svg|webp)$/i,
163
- use: [{
164
- loader: "url-loader",
165
- options: {
166
- ...ctx.options.webpack.loaders.imgUrl,
167
- name: fileName(ctx, "img")
168
- }
169
- }]
170
- }, {
171
- test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
172
- use: [{
173
- loader: "url-loader",
174
- options: {
175
- ...ctx.options.webpack.loaders.fontUrl,
176
- name: fileName(ctx, "font")
177
- }
178
- }]
179
- }, {
180
- test: /\.(webm|mp4|ogv)$/i,
181
- use: [{
182
- loader: "file-loader",
183
- options: {
184
- ...ctx.options.webpack.loaders.file,
185
- name: fileName(ctx, "video")
186
- }
187
- }]
188
- });
197
+ ctx.config.module.rules.push(
198
+ {
199
+ test: /\.(png|jpe?g|gif|svg|webp)$/i,
200
+ use: [{
201
+ loader: "url-loader",
202
+ options: {
203
+ ...ctx.options.webpack.loaders.imgUrl,
204
+ name: fileName(ctx, "img")
205
+ }
206
+ }]
207
+ },
208
+ {
209
+ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
210
+ use: [{
211
+ loader: "url-loader",
212
+ options: {
213
+ ...ctx.options.webpack.loaders.fontUrl,
214
+ name: fileName(ctx, "font")
215
+ }
216
+ }]
217
+ },
218
+ {
219
+ test: /\.(webm|mp4|ogv)$/i,
220
+ use: [{
221
+ loader: "file-loader",
222
+ options: {
223
+ ...ctx.options.webpack.loaders.file,
224
+ name: fileName(ctx, "video")
225
+ }
226
+ }]
227
+ }
228
+ );
189
229
  }
190
230
 
191
231
  class WarningIgnorePlugin {
@@ -237,11 +277,13 @@ function basePlugins(ctx) {
237
277
  config.plugins.push(new WarningIgnorePlugin(getWarningIgnoreFilter(ctx)));
238
278
  config.plugins.push(new webpack.DefinePlugin(getEnv(ctx)));
239
279
  if (ctx.isServer || ctx.isDev && !options.build.quiet && options.webpack.friendlyErrors) {
240
- ctx.config.plugins.push(new FriendlyErrorsWebpackPlugin({
241
- clearConsole: false,
242
- reporter: "consola",
243
- logLevel: "ERROR"
244
- }));
280
+ ctx.config.plugins.push(
281
+ new FriendlyErrorsWebpackPlugin({
282
+ clearConsole: false,
283
+ reporter: "consola",
284
+ logLevel: "ERROR"
285
+ })
286
+ );
245
287
  }
246
288
  if (nuxt.options.webpack.profile) {
247
289
  const colors = {
@@ -309,14 +351,15 @@ function baseTranspile(ctx) {
309
351
  const { options } = ctx;
310
352
  const transpile = [
311
353
  /\.vue\.js/i,
312
- /consola\/src/
354
+ /consola\/src/,
355
+ /vue-demi/
313
356
  ];
314
357
  for (let pattern of options.build.transpile) {
315
358
  if (typeof pattern === "function") {
316
359
  pattern = pattern(ctx);
317
360
  }
318
361
  if (typeof pattern === "string") {
319
- transpile.push(new RegExp(escapeRE(normalize(pattern))));
362
+ transpile.push(new RegExp(escapeRegExp(normalize(pattern))));
320
363
  } else if (pattern instanceof RegExp) {
321
364
  transpile.push(pattern);
322
365
  }
@@ -332,7 +375,7 @@ function getCache(ctx) {
332
375
  function getOutput(ctx) {
333
376
  const { options } = ctx;
334
377
  return {
335
- path: resolve(options.buildDir, "dist", ctx.isServer ? "server" : "client"),
378
+ path: resolve(options.buildDir, "dist", ctx.isServer ? "server" : joinURL("client", options.app.buildAssetsDir)),
336
379
  filename: fileName(ctx, "app"),
337
380
  chunkFilename: fileName(ctx, "chunk"),
338
381
  publicPath: joinURL(options.app.baseURL, options.app.buildAssetsDir)
@@ -374,31 +417,34 @@ function esbuild(ctx) {
374
417
  const { config } = ctx;
375
418
  const target = ctx.isServer ? "es2019" : "chrome85";
376
419
  config.optimization.minimizer.push(new esbuildLoader.ESBuildMinifyPlugin());
377
- config.module.rules.push({
378
- test: /\.m?[jt]s$/i,
379
- loader: "esbuild-loader",
380
- exclude: (file) => {
381
- file = file.split("node_modules", 2)[1];
382
- if (!file) {
383
- return false;
420
+ config.module.rules.push(
421
+ {
422
+ test: /\.m?[jt]s$/i,
423
+ loader: "esbuild-loader",
424
+ exclude: (file) => {
425
+ file = file.split("node_modules", 2)[1];
426
+ if (!file) {
427
+ return false;
428
+ }
429
+ return !ctx.transpile.some((module) => module.test(file));
430
+ },
431
+ resolve: {
432
+ fullySpecified: false
433
+ },
434
+ options: {
435
+ loader: "ts",
436
+ target
384
437
  }
385
- return !ctx.transpile.some((module) => module.test(file));
386
- },
387
- resolve: {
388
- fullySpecified: false
389
438
  },
390
- options: {
391
- loader: "ts",
392
- target
393
- }
394
- }, {
395
- test: /\.m?[jt]sx$/,
396
- loader: "esbuild-loader",
397
- options: {
398
- loader: "tsx",
399
- target
439
+ {
440
+ test: /\.m?[jt]sx$/,
441
+ loader: "esbuild-loader",
442
+ options: {
443
+ loader: "tsx",
444
+ target
445
+ }
400
446
  }
401
- });
447
+ );
402
448
  }
403
449
 
404
450
  function pug(ctx) {
@@ -489,7 +535,7 @@ const getPostcssConfig = (nuxt) => {
489
535
  let postcssOptions = cloneDeep(nuxt.options.postcss);
490
536
  if (isPureObject(postcssOptions)) {
491
537
  if (Array.isArray(postcssOptions.plugins)) {
492
- defaults(postcssOptions, defaultConfig());
538
+ defaults$1(postcssOptions, defaultConfig());
493
539
  } else {
494
540
  postcssOptions = merge({}, defaultConfig(), postcssOptions);
495
541
  loadPlugins(postcssOptions);
@@ -604,7 +650,9 @@ const validate = (compiler) => {
604
650
  logger.warn('webpack config `target` should be "node".');
605
651
  }
606
652
  if (!compiler.options.externals) {
607
- logger.info("It is recommended to externalize dependencies in the server build for better build performance.");
653
+ logger.info(
654
+ "It is recommended to externalize dependencies in the server build for better build performance."
655
+ );
608
656
  }
609
657
  };
610
658
  const isJSRegExp = /\.[cm]?js(\?[^.]+)?$/;
@@ -627,7 +675,7 @@ class VueSSRClientPlugin {
627
675
  const asyncFiles = allFiles.filter((file) => isJS(file) || isCSS(file)).filter((file) => !initialFiles.includes(file)).filter((file) => !isHotUpdate(file));
628
676
  const assetsMapping = {};
629
677
  stats.assets.filter(({ name }) => isJS(name)).filter(({ name }) => !isHotUpdate(name)).forEach(({ name, chunkNames }) => {
630
- const componentHash = hash(chunkNames.join("|"));
678
+ const componentHash = hash$1(chunkNames.join("|"));
631
679
  if (!assetsMapping[componentHash]) {
632
680
  assetsMapping[componentHash] = [];
633
681
  }
@@ -664,10 +712,10 @@ class VueSSRClientPlugin {
664
712
  }
665
713
  }
666
714
  const files = Array.from(filesSet);
667
- manifest.modules[hash(id)] = files;
715
+ manifest.modules[hash$1(id)] = files;
668
716
  if (Array.isArray(m.modules)) {
669
717
  for (const concatenatedModule of m.modules) {
670
- const id2 = hash(concatenatedModule.identifier.replace(/\s\w+$/, ""));
718
+ const id2 = hash$1(concatenatedModule.identifier.replace(/\s\w+$/, ""));
671
719
  if (!manifest.modules[id2]) {
672
720
  manifest.modules[id2] = files;
673
721
  }
@@ -680,7 +728,7 @@ class VueSSRClientPlugin {
680
728
  });
681
729
  }
682
730
  });
683
- const src = JSON.stringify(manifest, null, 2);
731
+ const src = JSON.stringify(normalizeWebpackManifest(manifest), null, 2);
684
732
  await fse.mkdirp(dirname(this.options.filename));
685
733
  await fse.writeFile(this.options.filename, src);
686
734
  const mjsSrc = "export default " + src;
@@ -710,11 +758,15 @@ class VueSSRServerPlugin {
710
758
  }
711
759
  const entryAssets = entryInfo.assets.filter((asset) => isJS(asset.name));
712
760
  if (entryAssets.length > 1) {
713
- throw new Error("Server-side bundle should have one single entry file. Avoid using CommonsChunkPlugin in the server config.");
761
+ throw new Error(
762
+ "Server-side bundle should have one single entry file. Avoid using CommonsChunkPlugin in the server config."
763
+ );
714
764
  }
715
765
  const [entry] = entryAssets;
716
766
  if (!entry || typeof entry.name !== "string") {
717
- throw new Error(`Entry "${entryName}" not found. Did you specify the correct entry option?`);
767
+ throw new Error(
768
+ `Entry "${entryName}" not found. Did you specify the correct entry option?`
769
+ );
718
770
  }
719
771
  const bundle = {
720
772
  entry: entry.name,
@@ -834,7 +886,9 @@ function clientHMR(ctx) {
834
886
  };
835
887
  const hotMiddlewareClientOptionsStr = querystring.stringify(hotMiddlewareClientOptions);
836
888
  const app = config.entry.app;
837
- app.unshift(`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`);
889
+ app.unshift(
890
+ `webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`
891
+ );
838
892
  config.plugins.push(new webpack.HotModuleReplacementPlugin());
839
893
  }
840
894
  function clientOptimization(_ctx) {
@@ -967,8 +1021,11 @@ async function bundle(nuxt) {
967
1021
  const mfs = nuxt.options.dev ? createMFS() : null;
968
1022
  const compilers = webpackConfigs.map((config) => {
969
1023
  config.plugins.push(DynamicBasePlugin.webpack({
1024
+ sourcemap: nuxt.options.sourcemap
1025
+ }));
1026
+ config.plugins.push(composableKeysPlugin.webpack({
970
1027
  sourcemap: nuxt.options.sourcemap,
971
- globalPublicPath: "__webpack_public_path__"
1028
+ rootDir: nuxt.options.rootDir
972
1029
  }));
973
1030
  const compiler = webpack(config);
974
1031
  if (nuxt.options.dev) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/webpack-builder",
3
- "version": "3.0.0-rc.4",
3
+ "version": "3.0.0-rc.7",
4
4
  "repository": "nuxt/framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -16,45 +16,48 @@
16
16
  "prepack": "unbuild"
17
17
  },
18
18
  "dependencies": {
19
- "@babel/core": "^7.18.5",
19
+ "@babel/core": "^7.18.10",
20
20
  "@nuxt/friendly-errors-webpack-plugin": "^2.5.2",
21
- "@nuxt/kit": "^3.0.0-rc.4",
22
- "autoprefixer": "^10.4.7",
21
+ "@nuxt/kit": "3.0.0-rc.7",
22
+ "autoprefixer": "^10.4.8",
23
23
  "css-loader": "^6.7.1",
24
24
  "css-minimizer-webpack-plugin": "^4.0.0",
25
- "cssnano": "^5.1.11",
25
+ "cssnano": "^5.1.12",
26
26
  "esbuild-loader": "^2.19.0",
27
27
  "escape-string-regexp": "^5.0.0",
28
+ "estree-walker": "^3.0.1",
28
29
  "file-loader": "^6.2.0",
29
- "fork-ts-checker-webpack-plugin": "^7.2.11",
30
+ "fork-ts-checker-webpack-plugin": "^7.2.13",
30
31
  "fs-extra": "^10.1.0",
31
32
  "hash-sum": "^2.0.0",
32
33
  "lodash-es": "^4.17.21",
33
34
  "magic-string": "^0.26.2",
34
- "memfs": "^3.4.4",
35
- "mini-css-extract-plugin": "^2.6.0",
36
- "mlly": "^0.5.2",
37
- "pathe": "^0.3.0",
35
+ "memfs": "^3.4.7",
36
+ "mini-css-extract-plugin": "^2.6.1",
37
+ "mlly": "^0.5.10",
38
+ "ohash": "^0.1.5",
39
+ "pathe": "^0.3.4",
38
40
  "pify": "^6.0.0",
39
- "postcss": "^8.4.14",
41
+ "postcss": "^8.4.16",
40
42
  "postcss-import": "^14.1.0",
41
- "postcss-loader": "^7.0.0",
43
+ "postcss-loader": "^7.0.1",
42
44
  "postcss-url": "^10.1.3",
43
45
  "style-resources-loader": "^1.5.0",
44
46
  "time-fix-plugin": "^2.0.7",
45
- "ufo": "^0.8.4",
46
- "unplugin": "^0.7.0",
47
+ "ufo": "^0.8.5",
48
+ "unplugin": "^0.9.0",
47
49
  "url-loader": "^4.1.1",
50
+ "vue-bundle-renderer": "^0.4.1",
48
51
  "vue-loader": "^17.0.0",
49
- "webpack": "^5.73.0",
52
+ "webpack": "^5.74.0",
50
53
  "webpack-bundle-analyzer": "^4.5.0",
51
54
  "webpack-dev-middleware": "^5.3.3",
52
55
  "webpack-hot-middleware": "^2.25.1",
53
- "webpack-virtual-modules": "^0.4.3",
56
+ "webpack-virtual-modules": "^0.4.4",
54
57
  "webpackbar": "^5.0.2"
55
58
  },
56
59
  "devDependencies": {
57
- "@nuxt/schema": "^3.0.0-rc.4",
60
+ "@nuxt/schema": "3.0.0-rc.7",
58
61
  "@types/pify": "^5.0.1",
59
62
  "@types/webpack-bundle-analyzer": "^4.4.1",
60
63
  "@types/webpack-dev-middleware": "^5.0.2",