@nuxt/webpack-builder 0.10.0 → 3.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +1051 -0
- package/package.json +69 -2
- package/index.js +0 -1
package/README.md
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
# Nuxt Webpack Builder
|
|
2
|
+
|
|
3
|
+
> The [Webpack](https://webpack.js.org) bundler for Nuxt 3
|
|
4
|
+
|
|
5
|
+
Learn more about this package: <https://v3.nuxtjs.org>
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1051 @@
|
|
|
1
|
+
import pify from 'pify';
|
|
2
|
+
import webpack from 'webpack';
|
|
3
|
+
import webpackDevMiddleware from 'webpack-dev-middleware';
|
|
4
|
+
import webpackHotMiddleware from 'webpack-hot-middleware';
|
|
5
|
+
import { joinURL } from 'ufo';
|
|
6
|
+
import { useNuxt, logger, requireModule } from '@nuxt/kit';
|
|
7
|
+
import { createUnplugin } from 'unplugin';
|
|
8
|
+
import 'escape-string-regexp';
|
|
9
|
+
import MagicString from 'magic-string';
|
|
10
|
+
import { join, resolve, dirname, isAbsolute } from 'pathe';
|
|
11
|
+
import { createFsFromVolume, Volume } from 'memfs';
|
|
12
|
+
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
|
13
|
+
import querystring from 'node:querystring';
|
|
14
|
+
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
|
15
|
+
import { cloneDeep, defaults, merge, uniq } from 'lodash-es';
|
|
16
|
+
import TimeFixPlugin from 'time-fix-plugin';
|
|
17
|
+
import WebpackBar from 'webpackbar';
|
|
18
|
+
import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin';
|
|
19
|
+
import esbuildLoader from 'esbuild-loader';
|
|
20
|
+
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
21
|
+
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
|
22
|
+
import { createCommonJS } from 'mlly';
|
|
23
|
+
import VueLoaderPlugin from 'vue-loader/dist/pluginWebpack5.js';
|
|
24
|
+
import hash from 'hash-sum';
|
|
25
|
+
import fse from 'fs-extra';
|
|
26
|
+
import ForkTSCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
|
27
|
+
|
|
28
|
+
const VITE_ASSET_RE = /^export default ["'](__VITE_ASSET.*)["']$/;
|
|
29
|
+
const DynamicBasePlugin = createUnplugin(function(options = {}) {
|
|
30
|
+
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
|
+
},
|
|
41
|
+
enforce: "post",
|
|
42
|
+
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"));
|
|
54
|
+
}
|
|
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");
|
|
57
|
+
}
|
|
58
|
+
if (id === "vite/preload-helper") {
|
|
59
|
+
s.prepend("import { buildAssetsDir } from '#build/paths.mjs';\n");
|
|
60
|
+
s.replace(/const base = ['"]\/__NUXT_BASE__\/['"]/, "const base = buildAssetsDir()");
|
|
61
|
+
}
|
|
62
|
+
s.replace(/from *['"]\/__NUXT_BASE__(\/[^'"]*)['"]/g, 'from "$1"');
|
|
63
|
+
for (const delimiter of ["`", "'", '"']) {
|
|
64
|
+
const delimiterRE = new RegExp(`(?<!(const base = |from *))${delimiter}([^${delimiter}]*)\\/__NUXT_BASE__\\/([^${delimiter}]*)${delimiter}`, "g");
|
|
65
|
+
s.replace(delimiterRE, (r) => "`" + r.replace(/\/__NUXT_BASE__\//g, "${__publicAssetsURL()}").slice(1, -1) + "`");
|
|
66
|
+
}
|
|
67
|
+
if (s.hasChanged()) {
|
|
68
|
+
return {
|
|
69
|
+
code: s.toString(),
|
|
70
|
+
map: s.generateMap({ source: id, includeContent: true })
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
function createMFS() {
|
|
78
|
+
const fs = createFsFromVolume(new Volume());
|
|
79
|
+
const _fs = { ...fs };
|
|
80
|
+
_fs.join = join;
|
|
81
|
+
_fs.exists = (p) => Promise.resolve(_fs.existsSync(p));
|
|
82
|
+
_fs.readFile = pify(_fs.readFile);
|
|
83
|
+
return _fs;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function registerVirtualModules() {
|
|
87
|
+
const nuxt = useNuxt();
|
|
88
|
+
const virtualModules = new VirtualModulesPlugin(nuxt.vfs);
|
|
89
|
+
const writeFiles = () => {
|
|
90
|
+
for (const filePath in nuxt.vfs) {
|
|
91
|
+
virtualModules.writeModule(filePath, nuxt.vfs[filePath]);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
nuxt.hook("build:compile", ({ compiler }) => {
|
|
95
|
+
if (compiler.name === "server") {
|
|
96
|
+
writeFiles();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
nuxt.hook("app:templatesGenerated", writeFiles);
|
|
100
|
+
nuxt.hook("webpack:config", (configs) => configs.forEach((config) => {
|
|
101
|
+
config.plugins.push(virtualModules);
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function createWebpackConfigContext(nuxt) {
|
|
106
|
+
return {
|
|
107
|
+
nuxt,
|
|
108
|
+
options: nuxt.options,
|
|
109
|
+
config: {},
|
|
110
|
+
name: "base",
|
|
111
|
+
isDev: nuxt.options.dev,
|
|
112
|
+
isServer: false,
|
|
113
|
+
isClient: false,
|
|
114
|
+
alias: {},
|
|
115
|
+
transpile: []
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function applyPresets(ctx, presets) {
|
|
119
|
+
if (!Array.isArray(presets)) {
|
|
120
|
+
presets = [presets];
|
|
121
|
+
}
|
|
122
|
+
for (const preset of presets) {
|
|
123
|
+
if (Array.isArray(preset)) {
|
|
124
|
+
preset[0](ctx, preset[1]);
|
|
125
|
+
} else {
|
|
126
|
+
preset(ctx);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function fileName(ctx, key) {
|
|
131
|
+
const { options } = ctx;
|
|
132
|
+
let fileName2 = options.webpack.filenames[key];
|
|
133
|
+
if (typeof fileName2 === "function") {
|
|
134
|
+
fileName2 = fileName2(ctx);
|
|
135
|
+
}
|
|
136
|
+
if (typeof fileName2 === "string" && options.dev) {
|
|
137
|
+
const hash = /\[(chunkhash|contenthash|hash)(?::(\d+))?]/.exec(fileName2);
|
|
138
|
+
if (hash) {
|
|
139
|
+
logger.warn(`Notice: Please do not use ${hash[1]} in dev mode to prevent memory leak`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return fileName2;
|
|
143
|
+
}
|
|
144
|
+
function getWebpackConfig(ctx) {
|
|
145
|
+
const { options, config } = ctx;
|
|
146
|
+
const builder = {};
|
|
147
|
+
const loaders = [];
|
|
148
|
+
const { extend } = options.build;
|
|
149
|
+
if (typeof extend === "function") {
|
|
150
|
+
const extendedConfig = extend.call(builder, config, { loaders, ...ctx }) || config;
|
|
151
|
+
const pragma = /@|#/;
|
|
152
|
+
const { devtool } = extendedConfig;
|
|
153
|
+
if (typeof devtool === "string" && pragma.test(devtool)) {
|
|
154
|
+
extendedConfig.devtool = devtool.replace(pragma, "");
|
|
155
|
+
logger.warn(`devtool has been normalized to ${extendedConfig.devtool} as webpack documented value`);
|
|
156
|
+
}
|
|
157
|
+
return extendedConfig;
|
|
158
|
+
}
|
|
159
|
+
return cloneDeep(config);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function assets(ctx) {
|
|
163
|
+
ctx.config.module.rules.push({
|
|
164
|
+
test: /\.(png|jpe?g|gif|svg|webp)$/i,
|
|
165
|
+
use: [{
|
|
166
|
+
loader: "url-loader",
|
|
167
|
+
options: {
|
|
168
|
+
...ctx.options.webpack.loaders.imgUrl,
|
|
169
|
+
name: fileName(ctx, "img")
|
|
170
|
+
}
|
|
171
|
+
}]
|
|
172
|
+
}, {
|
|
173
|
+
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
|
|
174
|
+
use: [{
|
|
175
|
+
loader: "url-loader",
|
|
176
|
+
options: {
|
|
177
|
+
...ctx.options.webpack.loaders.fontUrl,
|
|
178
|
+
name: fileName(ctx, "font")
|
|
179
|
+
}
|
|
180
|
+
}]
|
|
181
|
+
}, {
|
|
182
|
+
test: /\.(webm|mp4|ogv)$/i,
|
|
183
|
+
use: [{
|
|
184
|
+
loader: "file-loader",
|
|
185
|
+
options: {
|
|
186
|
+
...ctx.options.webpack.loaders.file,
|
|
187
|
+
name: fileName(ctx, "video")
|
|
188
|
+
}
|
|
189
|
+
}]
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
class WarningIgnorePlugin {
|
|
194
|
+
constructor(filter) {
|
|
195
|
+
this.filter = filter;
|
|
196
|
+
}
|
|
197
|
+
apply(compiler) {
|
|
198
|
+
compiler.hooks.done.tap("warnfix-plugin", (stats) => {
|
|
199
|
+
stats.compilation.warnings = stats.compilation.warnings.filter(this.filter);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function base(ctx) {
|
|
205
|
+
applyPresets(ctx, [
|
|
206
|
+
baseAlias,
|
|
207
|
+
baseConfig,
|
|
208
|
+
basePlugins,
|
|
209
|
+
baseResolve
|
|
210
|
+
]);
|
|
211
|
+
}
|
|
212
|
+
function baseConfig(ctx) {
|
|
213
|
+
const { options } = ctx;
|
|
214
|
+
ctx.config = {
|
|
215
|
+
name: ctx.name,
|
|
216
|
+
entry: { app: [resolve(options.appDir, options.experimental.asyncEntry ? "entry.async" : "entry")] },
|
|
217
|
+
module: { rules: [] },
|
|
218
|
+
plugins: [],
|
|
219
|
+
externals: [],
|
|
220
|
+
optimization: {
|
|
221
|
+
...options.webpack.optimization,
|
|
222
|
+
minimizer: []
|
|
223
|
+
},
|
|
224
|
+
experiments: {},
|
|
225
|
+
mode: ctx.isDev ? "development" : "production",
|
|
226
|
+
cache: getCache(ctx),
|
|
227
|
+
output: getOutput(ctx),
|
|
228
|
+
stats: "none",
|
|
229
|
+
...ctx.config
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function basePlugins(ctx) {
|
|
233
|
+
const { config, options, nuxt } = ctx;
|
|
234
|
+
if (options.dev) {
|
|
235
|
+
config.plugins.push(new TimeFixPlugin());
|
|
236
|
+
}
|
|
237
|
+
config.plugins.push(...options.webpack.plugins || []);
|
|
238
|
+
config.plugins.push(new WarningIgnorePlugin(getWarningIgnoreFilter(ctx)));
|
|
239
|
+
config.plugins.push(new webpack.DefinePlugin(getEnv(ctx)));
|
|
240
|
+
if (ctx.isServer || ctx.isDev && !options.build.quiet && options.webpack.friendlyErrors) {
|
|
241
|
+
ctx.config.plugins.push(new FriendlyErrorsWebpackPlugin({
|
|
242
|
+
clearConsole: false,
|
|
243
|
+
reporter: "consola",
|
|
244
|
+
logLevel: "ERROR"
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
if (nuxt.options.webpack.profile) {
|
|
248
|
+
const colors = {
|
|
249
|
+
client: "green",
|
|
250
|
+
server: "orange",
|
|
251
|
+
modern: "blue"
|
|
252
|
+
};
|
|
253
|
+
config.plugins.push(new WebpackBar({
|
|
254
|
+
name: ctx.name,
|
|
255
|
+
color: colors[ctx.name],
|
|
256
|
+
reporters: ["stats"],
|
|
257
|
+
stats: !ctx.isDev,
|
|
258
|
+
reporter: {
|
|
259
|
+
change: (_, { shortPath }) => {
|
|
260
|
+
if (!ctx.isServer) {
|
|
261
|
+
nuxt.callHook("bundler:change", shortPath);
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
done: ({ state }) => {
|
|
265
|
+
if (state.hasErrors) {
|
|
266
|
+
nuxt.callHook("bundler:error");
|
|
267
|
+
} else {
|
|
268
|
+
logger.success(`${state.name} ${state.message}`);
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
allDone: () => {
|
|
272
|
+
nuxt.callHook("bundler:done");
|
|
273
|
+
},
|
|
274
|
+
progress({ statesArray }) {
|
|
275
|
+
nuxt.callHook("bundler:progress", statesArray);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function baseAlias(ctx) {
|
|
282
|
+
const { options } = ctx;
|
|
283
|
+
ctx.alias = {
|
|
284
|
+
"#app": options.appDir,
|
|
285
|
+
"#build/plugins": resolve(options.buildDir, "plugins", ctx.isClient ? "client" : "server"),
|
|
286
|
+
"#build": options.buildDir,
|
|
287
|
+
...options.alias,
|
|
288
|
+
...ctx.alias
|
|
289
|
+
};
|
|
290
|
+
if (ctx.isClient) {
|
|
291
|
+
ctx.alias["#internal/nitro"] = resolve(ctx.nuxt.options.buildDir, "nitro.client.mjs");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function baseResolve(ctx) {
|
|
295
|
+
const { options, config } = ctx;
|
|
296
|
+
const webpackModulesDir = ["node_modules"].concat(options.modulesDir);
|
|
297
|
+
config.resolve = {
|
|
298
|
+
extensions: [".wasm", ".mjs", ".js", ".ts", ".json", ".vue", ".jsx", ".tsx"],
|
|
299
|
+
alias: ctx.alias,
|
|
300
|
+
modules: webpackModulesDir,
|
|
301
|
+
fullySpecified: false,
|
|
302
|
+
...config.resolve
|
|
303
|
+
};
|
|
304
|
+
config.resolveLoader = {
|
|
305
|
+
modules: webpackModulesDir,
|
|
306
|
+
...config.resolveLoader
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function getCache(ctx) {
|
|
310
|
+
const { options } = ctx;
|
|
311
|
+
if (!options.dev) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function getOutput(ctx) {
|
|
316
|
+
const { options } = ctx;
|
|
317
|
+
return {
|
|
318
|
+
path: resolve(options.buildDir, "dist", ctx.isServer ? "server" : "client"),
|
|
319
|
+
filename: fileName(ctx, "app"),
|
|
320
|
+
chunkFilename: fileName(ctx, "chunk"),
|
|
321
|
+
publicPath: joinURL(options.app.baseURL, options.app.buildAssetsDir)
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function getWarningIgnoreFilter(ctx) {
|
|
325
|
+
const { options } = ctx;
|
|
326
|
+
const filters = [
|
|
327
|
+
(warn) => warn.name === "ModuleDependencyWarning" && warn.message.includes("export 'default'") && warn.message.includes("nuxt_plugin_"),
|
|
328
|
+
...options.webpack.warningIgnoreFilters || []
|
|
329
|
+
];
|
|
330
|
+
return (warn) => !filters.some((ignoreFilter) => ignoreFilter(warn));
|
|
331
|
+
}
|
|
332
|
+
function getEnv(ctx) {
|
|
333
|
+
const { options } = ctx;
|
|
334
|
+
const _env = {
|
|
335
|
+
"process.env.NODE_ENV": JSON.stringify(ctx.config.mode),
|
|
336
|
+
"process.mode": JSON.stringify(ctx.config.mode),
|
|
337
|
+
"process.dev": options.dev,
|
|
338
|
+
"process.static": options.target === "static",
|
|
339
|
+
"process.target": JSON.stringify(options.target),
|
|
340
|
+
"process.env.VUE_ENV": JSON.stringify(ctx.name),
|
|
341
|
+
"process.browser": ctx.isClient,
|
|
342
|
+
"process.client": ctx.isClient,
|
|
343
|
+
"process.server": ctx.isServer
|
|
344
|
+
};
|
|
345
|
+
if (options.webpack.aggressiveCodeRemoval) {
|
|
346
|
+
_env["typeof process"] = JSON.stringify(ctx.isServer ? "object" : "undefined");
|
|
347
|
+
_env["typeof window"] = _env["typeof document"] = JSON.stringify(!ctx.isServer ? "object" : "undefined");
|
|
348
|
+
}
|
|
349
|
+
Object.entries(options.env).forEach(([key, value]) => {
|
|
350
|
+
const isNative = ["boolean", "number"].includes(typeof value);
|
|
351
|
+
_env["process.env." + key] = isNative ? value : JSON.stringify(value);
|
|
352
|
+
});
|
|
353
|
+
return _env;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function esbuild(ctx) {
|
|
357
|
+
const { config } = ctx;
|
|
358
|
+
const target = ctx.isServer ? "es2019" : "chrome85";
|
|
359
|
+
config.optimization.minimizer.push(new esbuildLoader.ESBuildMinifyPlugin());
|
|
360
|
+
config.module.rules.push({
|
|
361
|
+
test: /\.m?[jt]s$/i,
|
|
362
|
+
loader: "esbuild-loader",
|
|
363
|
+
exclude: (file) => {
|
|
364
|
+
file = file.split("node_modules", 2)[1];
|
|
365
|
+
if (!file) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
return !ctx.transpile.some((module) => module.test(file));
|
|
369
|
+
},
|
|
370
|
+
resolve: {
|
|
371
|
+
fullySpecified: false
|
|
372
|
+
},
|
|
373
|
+
options: {
|
|
374
|
+
loader: "ts",
|
|
375
|
+
target
|
|
376
|
+
}
|
|
377
|
+
}, {
|
|
378
|
+
test: /\.m?[jt]sx$/,
|
|
379
|
+
loader: "esbuild-loader",
|
|
380
|
+
options: {
|
|
381
|
+
loader: "tsx",
|
|
382
|
+
target
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function pug(ctx) {
|
|
388
|
+
ctx.config.module.rules.push({
|
|
389
|
+
test: /\.pug$/i,
|
|
390
|
+
oneOf: [
|
|
391
|
+
{
|
|
392
|
+
resourceQuery: /^\?vue/i,
|
|
393
|
+
use: [{
|
|
394
|
+
loader: "pug-plain-loader",
|
|
395
|
+
options: ctx.options.webpack.loaders.pugPlain
|
|
396
|
+
}]
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
use: [
|
|
400
|
+
"raw-loader",
|
|
401
|
+
{
|
|
402
|
+
loader: "pug-plain-loader",
|
|
403
|
+
options: ctx.options.webpack.loaders.pugPlain
|
|
404
|
+
}
|
|
405
|
+
]
|
|
406
|
+
}
|
|
407
|
+
]
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const isPureObject = (obj) => obj !== null && !Array.isArray(obj) && typeof obj === "object";
|
|
412
|
+
const orderPresets = {
|
|
413
|
+
cssnanoLast(names) {
|
|
414
|
+
const nanoIndex = names.indexOf("cssnano");
|
|
415
|
+
if (nanoIndex !== names.length - 1) {
|
|
416
|
+
names.push(names.splice(nanoIndex, 1)[0]);
|
|
417
|
+
}
|
|
418
|
+
return names;
|
|
419
|
+
},
|
|
420
|
+
autoprefixerLast(names) {
|
|
421
|
+
const nanoIndex = names.indexOf("autoprefixer");
|
|
422
|
+
if (nanoIndex !== names.length - 1) {
|
|
423
|
+
names.push(names.splice(nanoIndex, 1)[0]);
|
|
424
|
+
}
|
|
425
|
+
return names;
|
|
426
|
+
},
|
|
427
|
+
autoprefixerAndCssnanoLast(names) {
|
|
428
|
+
return orderPresets.cssnanoLast(orderPresets.autoprefixerLast(names));
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
const getPostcssConfig = (nuxt) => {
|
|
432
|
+
function defaultConfig() {
|
|
433
|
+
return {
|
|
434
|
+
sourceMap: nuxt.options.webpack.cssSourceMap,
|
|
435
|
+
plugins: nuxt.options.postcss.plugins,
|
|
436
|
+
order: "autoprefixerAndCssnanoLast"
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
function sortPlugins({ plugins, order }) {
|
|
440
|
+
const names = Object.keys(plugins);
|
|
441
|
+
if (typeof order === "string") {
|
|
442
|
+
order = orderPresets[order];
|
|
443
|
+
}
|
|
444
|
+
return typeof order === "function" ? order(names, orderPresets) : order || names;
|
|
445
|
+
}
|
|
446
|
+
function loadPlugins(config) {
|
|
447
|
+
if (!isPureObject(config.plugins)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const cjs = createCommonJS(import.meta.url);
|
|
451
|
+
config.plugins = sortPlugins(config).map((pluginName) => {
|
|
452
|
+
const pluginFn = requireModule(pluginName, { paths: [cjs.__dirname] });
|
|
453
|
+
const pluginOptions = config.plugins[pluginName];
|
|
454
|
+
if (!pluginOptions || typeof pluginFn !== "function") {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
return pluginFn(pluginOptions);
|
|
458
|
+
}).filter(Boolean);
|
|
459
|
+
}
|
|
460
|
+
if (!nuxt.options.webpack.postcss || !nuxt.options.postcss) {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
const configFile = nuxt.options.postcss?.config;
|
|
464
|
+
if (configFile) {
|
|
465
|
+
return {
|
|
466
|
+
postcssOptions: {
|
|
467
|
+
config: configFile
|
|
468
|
+
},
|
|
469
|
+
sourceMap: nuxt.options.webpack.cssSourceMap
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
let postcssOptions = cloneDeep(nuxt.options.postcss);
|
|
473
|
+
if (isPureObject(postcssOptions)) {
|
|
474
|
+
if (Array.isArray(postcssOptions.plugins)) {
|
|
475
|
+
defaults(postcssOptions, defaultConfig());
|
|
476
|
+
} else {
|
|
477
|
+
postcssOptions = merge({}, defaultConfig(), postcssOptions);
|
|
478
|
+
loadPlugins(postcssOptions);
|
|
479
|
+
}
|
|
480
|
+
delete nuxt.options.webpack.postcss.order;
|
|
481
|
+
return {
|
|
482
|
+
sourceMap: nuxt.options.webpack.cssSourceMap,
|
|
483
|
+
...nuxt.options.webpack.postcss,
|
|
484
|
+
postcssOptions
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
function style(ctx) {
|
|
490
|
+
applyPresets(ctx, [
|
|
491
|
+
loaders,
|
|
492
|
+
extractCSS,
|
|
493
|
+
minimizer
|
|
494
|
+
]);
|
|
495
|
+
}
|
|
496
|
+
function minimizer(ctx) {
|
|
497
|
+
const { options, config } = ctx;
|
|
498
|
+
if (options.webpack.optimizeCSS && Array.isArray(config.optimization.minimizer)) {
|
|
499
|
+
config.optimization.minimizer.push(new CssMinimizerPlugin({
|
|
500
|
+
...options.webpack.optimizeCSS
|
|
501
|
+
}));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function extractCSS(ctx) {
|
|
505
|
+
const { options, config } = ctx;
|
|
506
|
+
if (options.webpack.extractCSS) {
|
|
507
|
+
config.plugins.push(new MiniCssExtractPlugin({
|
|
508
|
+
filename: fileName(ctx, "css"),
|
|
509
|
+
chunkFilename: fileName(ctx, "css"),
|
|
510
|
+
...options.webpack.extractCSS
|
|
511
|
+
}));
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function loaders(ctx) {
|
|
515
|
+
const { config, options } = ctx;
|
|
516
|
+
config.module.rules.push(createdStyleRule("css", /\.css$/i, null, ctx));
|
|
517
|
+
config.module.rules.push(createdStyleRule("postcss", /\.p(ost)?css$/i, null, ctx));
|
|
518
|
+
const lessLoader = { loader: "less-loader", options: options.webpack.loaders.less };
|
|
519
|
+
config.module.rules.push(createdStyleRule("less", /\.less$/i, lessLoader, ctx));
|
|
520
|
+
const sassLoader = { loader: "sass-loader", options: options.webpack.loaders.sass };
|
|
521
|
+
config.module.rules.push(createdStyleRule("sass", /\.sass$/i, sassLoader, ctx));
|
|
522
|
+
const scssLoader = { loader: "sass-loader", options: options.webpack.loaders.scss };
|
|
523
|
+
config.module.rules.push(createdStyleRule("scss", /\.scss$/i, scssLoader, ctx));
|
|
524
|
+
const stylusLoader = { loader: "stylus-loader", options: options.webpack.loaders.stylus };
|
|
525
|
+
config.module.rules.push(createdStyleRule("stylus", /\.styl(us)?$/i, stylusLoader, ctx));
|
|
526
|
+
}
|
|
527
|
+
function createdStyleRule(lang, test, processorLoader, ctx) {
|
|
528
|
+
const { options } = ctx;
|
|
529
|
+
const styleLoaders = [
|
|
530
|
+
createPostcssLoadersRule(ctx),
|
|
531
|
+
processorLoader
|
|
532
|
+
].filter(Boolean);
|
|
533
|
+
options.webpack.loaders.css.importLoaders = options.webpack.loaders.cssModules.importLoaders = styleLoaders.length;
|
|
534
|
+
const cssLoaders = createCssLoadersRule(ctx, options.webpack.loaders.css);
|
|
535
|
+
const cssModuleLoaders = createCssLoadersRule(ctx, options.webpack.loaders.cssModules);
|
|
536
|
+
return {
|
|
537
|
+
test,
|
|
538
|
+
oneOf: [
|
|
539
|
+
{
|
|
540
|
+
resourceQuery: /module/,
|
|
541
|
+
use: cssModuleLoaders.concat(styleLoaders)
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
use: cssLoaders.concat(styleLoaders)
|
|
545
|
+
}
|
|
546
|
+
]
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function createCssLoadersRule(ctx, cssLoaderOptions) {
|
|
550
|
+
const { options } = ctx;
|
|
551
|
+
const cssLoader = { loader: "css-loader", options: cssLoaderOptions };
|
|
552
|
+
if (options.webpack.extractCSS) {
|
|
553
|
+
if (ctx.isServer) {
|
|
554
|
+
if (cssLoader.options.modules) {
|
|
555
|
+
cssLoader.options.modules.exportOnlyLocals = cssLoader.options.modules.exportOnlyLocals ?? true;
|
|
556
|
+
}
|
|
557
|
+
return [cssLoader];
|
|
558
|
+
}
|
|
559
|
+
return [
|
|
560
|
+
{
|
|
561
|
+
loader: MiniCssExtractPlugin.loader
|
|
562
|
+
},
|
|
563
|
+
cssLoader
|
|
564
|
+
];
|
|
565
|
+
}
|
|
566
|
+
return [
|
|
567
|
+
{
|
|
568
|
+
loader: "vue-style-loader",
|
|
569
|
+
options: options.webpack.loaders.vueStyle
|
|
570
|
+
},
|
|
571
|
+
cssLoader
|
|
572
|
+
];
|
|
573
|
+
}
|
|
574
|
+
function createPostcssLoadersRule(ctx) {
|
|
575
|
+
const { options, nuxt } = ctx;
|
|
576
|
+
if (!options.postcss) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
const config = getPostcssConfig(nuxt);
|
|
580
|
+
if (!config) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
return {
|
|
584
|
+
loader: "postcss-loader",
|
|
585
|
+
options: config
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
const validate = (compiler) => {
|
|
590
|
+
if (compiler.options.target !== "node") {
|
|
591
|
+
logger.warn('webpack config `target` should be "node".');
|
|
592
|
+
}
|
|
593
|
+
if (!compiler.options.externals) {
|
|
594
|
+
logger.info("It is recommended to externalize dependencies in the server build for better build performance.");
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
const isJSRegExp = /\.[cm]?js(\?[^.]+)?$/;
|
|
598
|
+
const isJS = (file) => isJSRegExp.test(file);
|
|
599
|
+
const extractQueryPartJS = (file) => isJSRegExp.exec(file)[1];
|
|
600
|
+
const isCSS = (file) => /\.css(\?[^.]+)?$/.test(file);
|
|
601
|
+
const isHotUpdate = (file) => file.includes("hot-update");
|
|
602
|
+
|
|
603
|
+
class VueSSRClientPlugin {
|
|
604
|
+
constructor(options = {}) {
|
|
605
|
+
this.options = Object.assign({
|
|
606
|
+
filename: null
|
|
607
|
+
}, options);
|
|
608
|
+
}
|
|
609
|
+
apply(compiler) {
|
|
610
|
+
compiler.hooks.afterEmit.tap("VueSSRClientPlugin", async (compilation) => {
|
|
611
|
+
const stats = compilation.getStats().toJson();
|
|
612
|
+
const allFiles = uniq(stats.assets.map((a) => a.name)).filter((file) => !isHotUpdate(file));
|
|
613
|
+
const initialFiles = uniq(Object.keys(stats.entrypoints).map((name) => stats.entrypoints[name].assets).reduce((files, entryAssets) => files.concat(entryAssets.map((entryAsset) => entryAsset.name)), []).filter((file) => isJS(file) || isCSS(file))).filter((file) => !isHotUpdate(file));
|
|
614
|
+
const asyncFiles = allFiles.filter((file) => isJS(file) || isCSS(file)).filter((file) => !initialFiles.includes(file)).filter((file) => !isHotUpdate(file));
|
|
615
|
+
const assetsMapping = {};
|
|
616
|
+
stats.assets.filter(({ name }) => isJS(name)).filter(({ name }) => !isHotUpdate(name)).forEach(({ name, chunkNames }) => {
|
|
617
|
+
const componentHash = hash(chunkNames.join("|"));
|
|
618
|
+
if (!assetsMapping[componentHash]) {
|
|
619
|
+
assetsMapping[componentHash] = [];
|
|
620
|
+
}
|
|
621
|
+
assetsMapping[componentHash].push(name);
|
|
622
|
+
});
|
|
623
|
+
const manifest = {
|
|
624
|
+
publicPath: stats.publicPath,
|
|
625
|
+
all: allFiles,
|
|
626
|
+
initial: initialFiles,
|
|
627
|
+
async: asyncFiles,
|
|
628
|
+
modules: {},
|
|
629
|
+
assetsMapping
|
|
630
|
+
};
|
|
631
|
+
const { entrypoints, namedChunkGroups } = stats;
|
|
632
|
+
const assetModules = stats.modules.filter((m) => m.assets.length);
|
|
633
|
+
const fileToIndex = (file) => manifest.all.indexOf(file);
|
|
634
|
+
stats.modules.forEach((m) => {
|
|
635
|
+
if (m.chunks.length === 1) {
|
|
636
|
+
const [cid] = m.chunks;
|
|
637
|
+
const chunk = stats.chunks.find((c) => c.id === cid);
|
|
638
|
+
if (!chunk || !chunk.files) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const id = m.identifier.replace(/\s\w+$/, "");
|
|
642
|
+
const filesSet = new Set(chunk.files.map(fileToIndex).filter((i) => i !== -1));
|
|
643
|
+
for (const chunkName of chunk.names) {
|
|
644
|
+
if (!entrypoints[chunkName]) {
|
|
645
|
+
const chunkGroup = namedChunkGroups[chunkName];
|
|
646
|
+
if (chunkGroup) {
|
|
647
|
+
for (const asset of chunkGroup.assets) {
|
|
648
|
+
filesSet.add(fileToIndex(asset.name));
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const files = Array.from(filesSet);
|
|
654
|
+
manifest.modules[hash(id)] = files;
|
|
655
|
+
if (Array.isArray(m.modules)) {
|
|
656
|
+
for (const concatenatedModule of m.modules) {
|
|
657
|
+
const id2 = hash(concatenatedModule.identifier.replace(/\s\w+$/, ""));
|
|
658
|
+
if (!manifest.modules[id2]) {
|
|
659
|
+
manifest.modules[id2] = files;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
assetModules.forEach((m2) => {
|
|
664
|
+
if (m2.chunks.includes(cid)) {
|
|
665
|
+
files.push.apply(files, m2.assets.map(fileToIndex));
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
const src = JSON.stringify(manifest, null, 2);
|
|
671
|
+
await fse.mkdirp(dirname(this.options.filename));
|
|
672
|
+
await fse.writeFile(this.options.filename, src);
|
|
673
|
+
const mjsSrc = "export default " + src;
|
|
674
|
+
await fse.writeFile(this.options.filename.replace(".json", ".mjs"), mjsSrc);
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
class VueSSRServerPlugin {
|
|
680
|
+
constructor(options = {}) {
|
|
681
|
+
this.options = Object.assign({
|
|
682
|
+
filename: null
|
|
683
|
+
}, options);
|
|
684
|
+
}
|
|
685
|
+
apply(compiler) {
|
|
686
|
+
validate(compiler);
|
|
687
|
+
compiler.hooks.make.tap("VueSSRServerPlugin", (compilation) => {
|
|
688
|
+
compilation.hooks.processAssets.tapAsync({
|
|
689
|
+
name: "VueSSRServerPlugin",
|
|
690
|
+
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
|
|
691
|
+
}, (assets, cb) => {
|
|
692
|
+
const stats = compilation.getStats().toJson();
|
|
693
|
+
const [entryName] = Object.keys(stats.entrypoints);
|
|
694
|
+
const entryInfo = stats.entrypoints[entryName];
|
|
695
|
+
if (!entryInfo) {
|
|
696
|
+
return cb();
|
|
697
|
+
}
|
|
698
|
+
const entryAssets = entryInfo.assets.filter((asset) => isJS(asset.name));
|
|
699
|
+
if (entryAssets.length > 1) {
|
|
700
|
+
throw new Error("Server-side bundle should have one single entry file. Avoid using CommonsChunkPlugin in the server config.");
|
|
701
|
+
}
|
|
702
|
+
const [entry] = entryAssets;
|
|
703
|
+
if (!entry || typeof entry.name !== "string") {
|
|
704
|
+
throw new Error(`Entry "${entryName}" not found. Did you specify the correct entry option?`);
|
|
705
|
+
}
|
|
706
|
+
const bundle = {
|
|
707
|
+
entry: entry.name,
|
|
708
|
+
files: {},
|
|
709
|
+
maps: {}
|
|
710
|
+
};
|
|
711
|
+
stats.assets.forEach((asset) => {
|
|
712
|
+
if (isJS(asset.name)) {
|
|
713
|
+
const queryPart = extractQueryPartJS(asset.name);
|
|
714
|
+
if (queryPart !== void 0) {
|
|
715
|
+
bundle.files[asset.name] = asset.name.replace(queryPart, "");
|
|
716
|
+
} else {
|
|
717
|
+
bundle.files[asset.name] = asset.name;
|
|
718
|
+
}
|
|
719
|
+
} else if (asset.name.match(/\.js\.map$/)) {
|
|
720
|
+
bundle.maps[asset.name.replace(/\.map$/, "")] = asset.name;
|
|
721
|
+
} else {
|
|
722
|
+
delete assets[asset.name];
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
const src = JSON.stringify(bundle, null, 2);
|
|
726
|
+
assets[this.options.filename] = {
|
|
727
|
+
source: () => src,
|
|
728
|
+
size: () => src.length
|
|
729
|
+
};
|
|
730
|
+
const mjsSrc = "export default " + src;
|
|
731
|
+
assets[this.options.filename.replace(".json", ".mjs")] = {
|
|
732
|
+
source: () => mjsSrc,
|
|
733
|
+
map: () => null,
|
|
734
|
+
size: () => mjsSrc.length
|
|
735
|
+
};
|
|
736
|
+
cb();
|
|
737
|
+
});
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function vue(ctx) {
|
|
743
|
+
const { options, config } = ctx;
|
|
744
|
+
config.plugins.push(new (VueLoaderPlugin.default || VueLoaderPlugin)());
|
|
745
|
+
config.module.rules.push({
|
|
746
|
+
test: /\.vue$/i,
|
|
747
|
+
loader: "vue-loader",
|
|
748
|
+
options: {
|
|
749
|
+
reactivityTransform: ctx.nuxt.options.experimental.reactivityTransform,
|
|
750
|
+
...options.webpack.loaders.vue
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
if (ctx.isClient) {
|
|
754
|
+
config.plugins.push(new VueSSRClientPlugin({
|
|
755
|
+
filename: resolve(options.buildDir, "dist/server", `${ctx.name}.manifest.json`)
|
|
756
|
+
}));
|
|
757
|
+
} else {
|
|
758
|
+
config.plugins.push(new VueSSRServerPlugin({
|
|
759
|
+
filename: `${ctx.name}.manifest.json`
|
|
760
|
+
}));
|
|
761
|
+
}
|
|
762
|
+
config.plugins.push(new webpack.DefinePlugin({
|
|
763
|
+
__VUE_OPTIONS_API__: "true",
|
|
764
|
+
__VUE_PROD_DEVTOOLS__: "false"
|
|
765
|
+
}));
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function nuxt(ctx) {
|
|
769
|
+
applyPresets(ctx, [
|
|
770
|
+
base,
|
|
771
|
+
assets,
|
|
772
|
+
esbuild,
|
|
773
|
+
pug,
|
|
774
|
+
style,
|
|
775
|
+
vue
|
|
776
|
+
]);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
function client(ctx) {
|
|
780
|
+
ctx.name = "client";
|
|
781
|
+
ctx.isClient = true;
|
|
782
|
+
applyPresets(ctx, [
|
|
783
|
+
nuxt,
|
|
784
|
+
clientPlugins,
|
|
785
|
+
clientOptimization,
|
|
786
|
+
clientDevtool,
|
|
787
|
+
clientPerformance,
|
|
788
|
+
clientHMR
|
|
789
|
+
]);
|
|
790
|
+
}
|
|
791
|
+
function clientDevtool(ctx) {
|
|
792
|
+
if (!ctx.isDev) {
|
|
793
|
+
ctx.config.devtool = false;
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
const scriptPolicy = getCspScriptPolicy(ctx);
|
|
797
|
+
const noUnsafeEval = scriptPolicy && !scriptPolicy.includes("'unsafe-eval'");
|
|
798
|
+
ctx.config.devtool = noUnsafeEval ? "cheap-module-source-map" : "eval-cheap-module-source-map";
|
|
799
|
+
}
|
|
800
|
+
function clientPerformance(ctx) {
|
|
801
|
+
ctx.config.performance = {
|
|
802
|
+
maxEntrypointSize: 1e3 * 1024,
|
|
803
|
+
hints: ctx.isDev ? false : "warning",
|
|
804
|
+
...ctx.config.performance
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
function clientHMR(ctx) {
|
|
808
|
+
const { options, config } = ctx;
|
|
809
|
+
if (!ctx.isDev) {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
const clientOptions = options.webpack.hotMiddleware?.client || {};
|
|
813
|
+
const hotMiddlewareClientOptions = {
|
|
814
|
+
reload: true,
|
|
815
|
+
timeout: 3e4,
|
|
816
|
+
path: joinURL(options.app.baseURL, "__webpack_hmr", ctx.name),
|
|
817
|
+
...clientOptions,
|
|
818
|
+
ansiColors: JSON.stringify(clientOptions.ansiColors || {}),
|
|
819
|
+
overlayStyles: JSON.stringify(clientOptions.overlayStyles || {}),
|
|
820
|
+
name: ctx.name
|
|
821
|
+
};
|
|
822
|
+
const hotMiddlewareClientOptionsStr = querystring.stringify(hotMiddlewareClientOptions);
|
|
823
|
+
const app = config.entry.app;
|
|
824
|
+
app.unshift(`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}`);
|
|
825
|
+
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
|
826
|
+
}
|
|
827
|
+
function clientOptimization(_ctx) {
|
|
828
|
+
}
|
|
829
|
+
function clientPlugins(ctx) {
|
|
830
|
+
const { options, config } = ctx;
|
|
831
|
+
if (!ctx.isDev && ctx.name === "client" && options.webpack.analyze) {
|
|
832
|
+
const statsDir = resolve(options.buildDir, "stats");
|
|
833
|
+
config.plugins.push(new BundleAnalyzerPlugin({
|
|
834
|
+
analyzerMode: "static",
|
|
835
|
+
defaultSizes: "gzip",
|
|
836
|
+
generateStatsFile: true,
|
|
837
|
+
openAnalyzer: !options.build.quiet,
|
|
838
|
+
reportFilename: resolve(statsDir, `${ctx.name}.html`),
|
|
839
|
+
statsFilename: resolve(statsDir, `${ctx.name}.json`),
|
|
840
|
+
...options.webpack.analyze === true ? {} : options.webpack.analyze
|
|
841
|
+
}));
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
function getCspScriptPolicy(ctx) {
|
|
845
|
+
const { csp } = ctx.options.render;
|
|
846
|
+
if (typeof csp === "object") {
|
|
847
|
+
const { policies = {} } = csp;
|
|
848
|
+
return policies["script-src"] || policies["default-src"] || [];
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
function node(ctx) {
|
|
853
|
+
const { config } = ctx;
|
|
854
|
+
config.target = "node";
|
|
855
|
+
config.node = false;
|
|
856
|
+
config.experiments.outputModule = true;
|
|
857
|
+
config.output = {
|
|
858
|
+
...config.output,
|
|
859
|
+
chunkFilename: "[name].mjs",
|
|
860
|
+
chunkFormat: "module",
|
|
861
|
+
chunkLoading: "import",
|
|
862
|
+
module: true,
|
|
863
|
+
environment: {
|
|
864
|
+
module: true,
|
|
865
|
+
arrowFunction: true,
|
|
866
|
+
bigIntLiteral: true,
|
|
867
|
+
const: true,
|
|
868
|
+
destructuring: true,
|
|
869
|
+
dynamicImport: true,
|
|
870
|
+
forOf: true
|
|
871
|
+
},
|
|
872
|
+
library: {
|
|
873
|
+
type: "module"
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
config.performance = {
|
|
877
|
+
...config.performance,
|
|
878
|
+
hints: false,
|
|
879
|
+
maxEntrypointSize: Infinity,
|
|
880
|
+
maxAssetSize: Infinity
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const assetPattern = /\.(css|s[ca]ss|png|jpe?g|gif|svg|woff2?|eot|ttf|otf|webp|webm|mp4|ogv)(\?.*)?$/i;
|
|
885
|
+
function server(ctx) {
|
|
886
|
+
ctx.name = "server";
|
|
887
|
+
ctx.isServer = true;
|
|
888
|
+
applyPresets(ctx, [
|
|
889
|
+
nuxt,
|
|
890
|
+
node,
|
|
891
|
+
serverStandalone,
|
|
892
|
+
serverPreset,
|
|
893
|
+
serverPlugins
|
|
894
|
+
]);
|
|
895
|
+
return getWebpackConfig(ctx);
|
|
896
|
+
}
|
|
897
|
+
function serverPreset(ctx) {
|
|
898
|
+
const { config } = ctx;
|
|
899
|
+
config.output.filename = "server.mjs";
|
|
900
|
+
config.devtool = "cheap-module-source-map";
|
|
901
|
+
config.optimization = {
|
|
902
|
+
splitChunks: false,
|
|
903
|
+
minimize: false
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
function serverStandalone(ctx) {
|
|
907
|
+
const inline = [
|
|
908
|
+
"src/",
|
|
909
|
+
"#app",
|
|
910
|
+
"nuxt",
|
|
911
|
+
"nuxt3",
|
|
912
|
+
"!",
|
|
913
|
+
"-!",
|
|
914
|
+
"~",
|
|
915
|
+
"@/",
|
|
916
|
+
"#",
|
|
917
|
+
...ctx.options.build.transpile
|
|
918
|
+
];
|
|
919
|
+
const external = ["#internal/nitro"];
|
|
920
|
+
if (!Array.isArray(ctx.config.externals)) {
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
ctx.config.externals.push(({ request }, cb) => {
|
|
924
|
+
if (external.includes(request)) {
|
|
925
|
+
return cb(null, true);
|
|
926
|
+
}
|
|
927
|
+
if (request[0] === "." || isAbsolute(request) || inline.find((prefix) => typeof prefix === "string" && request.startsWith(prefix)) || assetPattern.test(request)) {
|
|
928
|
+
return cb(null, false);
|
|
929
|
+
}
|
|
930
|
+
return cb(null, true);
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
function serverPlugins(ctx) {
|
|
934
|
+
const { config, options } = ctx;
|
|
935
|
+
if (options.webpack.serverURLPolyfill) {
|
|
936
|
+
config.plugins.push(new webpack.ProvidePlugin({
|
|
937
|
+
URL: [options.webpack.serverURLPolyfill, "URL"],
|
|
938
|
+
URLSearchParams: [options.webpack.serverURLPolyfill, "URLSearchParams"]
|
|
939
|
+
}));
|
|
940
|
+
}
|
|
941
|
+
if (ctx.nuxt.options.typescript.typeCheck === true || ctx.nuxt.options.typescript.typeCheck === "build" && !ctx.nuxt.options.dev) {
|
|
942
|
+
ctx.config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger }));
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
async function bundle(nuxt) {
|
|
947
|
+
await registerVirtualModules();
|
|
948
|
+
const webpackConfigs = [client, ...nuxt.options.ssr ? [server] : []].map((preset) => {
|
|
949
|
+
const ctx = createWebpackConfigContext(nuxt);
|
|
950
|
+
applyPresets(ctx, preset);
|
|
951
|
+
return getWebpackConfig(ctx);
|
|
952
|
+
});
|
|
953
|
+
await nuxt.callHook("webpack:config", webpackConfigs);
|
|
954
|
+
const mfs = nuxt.options.dev ? createMFS() : null;
|
|
955
|
+
const compilers = webpackConfigs.map((config) => {
|
|
956
|
+
config.plugins.push(DynamicBasePlugin.webpack({
|
|
957
|
+
globalPublicPath: "__webpack_public_path__"
|
|
958
|
+
}));
|
|
959
|
+
const compiler = webpack(config);
|
|
960
|
+
if (nuxt.options.dev) {
|
|
961
|
+
compiler.outputFileSystem = mfs;
|
|
962
|
+
}
|
|
963
|
+
return compiler;
|
|
964
|
+
});
|
|
965
|
+
nuxt.hook("close", async () => {
|
|
966
|
+
for (const compiler of compilers) {
|
|
967
|
+
await new Promise((resolve) => compiler.close(resolve));
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
if (nuxt.options.dev) {
|
|
971
|
+
return Promise.all(compilers.map((c) => compile(c)));
|
|
972
|
+
}
|
|
973
|
+
for (const c of compilers) {
|
|
974
|
+
await compile(c);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
async function createDevMiddleware(compiler) {
|
|
978
|
+
const nuxt = useNuxt();
|
|
979
|
+
logger.debug("Creating webpack middleware...");
|
|
980
|
+
const devMiddleware = pify(webpackDevMiddleware(compiler, {
|
|
981
|
+
publicPath: joinURL(nuxt.options.app.baseURL, nuxt.options.app.buildAssetsDir),
|
|
982
|
+
outputFileSystem: compiler.outputFileSystem,
|
|
983
|
+
stats: "none",
|
|
984
|
+
...nuxt.options.webpack.devMiddleware
|
|
985
|
+
}));
|
|
986
|
+
nuxt.hook("close", () => pify(devMiddleware.close.bind(devMiddleware))());
|
|
987
|
+
const { client: _client, ...hotMiddlewareOptions } = nuxt.options.webpack.hotMiddleware || {};
|
|
988
|
+
const hotMiddleware = pify(webpackHotMiddleware(compiler, {
|
|
989
|
+
log: false,
|
|
990
|
+
heartbeat: 1e4,
|
|
991
|
+
path: joinURL(nuxt.options.app.baseURL, "__webpack_hmr", compiler.options.name),
|
|
992
|
+
...hotMiddlewareOptions
|
|
993
|
+
}));
|
|
994
|
+
await nuxt.callHook("webpack:devMiddleware", devMiddleware);
|
|
995
|
+
await nuxt.callHook("webpack:hotMiddleware", hotMiddleware);
|
|
996
|
+
await nuxt.callHook("server:devMiddleware", async (req, res, next) => {
|
|
997
|
+
for (const mw of [devMiddleware, hotMiddleware]) {
|
|
998
|
+
await mw?.(req, res);
|
|
999
|
+
}
|
|
1000
|
+
next();
|
|
1001
|
+
});
|
|
1002
|
+
return devMiddleware;
|
|
1003
|
+
}
|
|
1004
|
+
async function compile(compiler) {
|
|
1005
|
+
const nuxt = useNuxt();
|
|
1006
|
+
const { name } = compiler.options;
|
|
1007
|
+
await nuxt.callHook("build:compile", { name, compiler });
|
|
1008
|
+
compiler.hooks.done.tap("load-resources", async (stats2) => {
|
|
1009
|
+
await nuxt.callHook("build:compiled", { name, compiler, stats: stats2 });
|
|
1010
|
+
await nuxt.callHook("build:resources", compiler.outputFileSystem);
|
|
1011
|
+
});
|
|
1012
|
+
if (nuxt.options.dev) {
|
|
1013
|
+
const compilersWatching = [];
|
|
1014
|
+
nuxt.hook("close", async () => {
|
|
1015
|
+
await Promise.all(compilersWatching.map((watching) => pify(watching.close.bind(watching))()));
|
|
1016
|
+
});
|
|
1017
|
+
if (name === "client") {
|
|
1018
|
+
return new Promise((resolve, reject) => {
|
|
1019
|
+
compiler.hooks.done.tap("nuxt-dev", () => {
|
|
1020
|
+
resolve(null);
|
|
1021
|
+
});
|
|
1022
|
+
compiler.hooks.failed.tap("nuxt-errorlog", (err) => {
|
|
1023
|
+
reject(err);
|
|
1024
|
+
});
|
|
1025
|
+
createDevMiddleware(compiler).then((devMiddleware) => {
|
|
1026
|
+
compilersWatching.push(devMiddleware.context.watching);
|
|
1027
|
+
});
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
return new Promise((resolve, reject) => {
|
|
1031
|
+
const watching = compiler.watch(nuxt.options.watchers.webpack, (err) => {
|
|
1032
|
+
if (err) {
|
|
1033
|
+
return reject(err);
|
|
1034
|
+
}
|
|
1035
|
+
resolve(null);
|
|
1036
|
+
});
|
|
1037
|
+
compilersWatching.push(watching);
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
const stats = await new Promise((resolve, reject) => compiler.run((err, stats2) => err ? reject(err) : resolve(stats2)));
|
|
1041
|
+
if (stats.hasErrors()) {
|
|
1042
|
+
const error = new Error("Nuxt build error");
|
|
1043
|
+
if (nuxt.options.build.quiet === true) {
|
|
1044
|
+
error.stack = stats.toString("errors-only");
|
|
1045
|
+
}
|
|
1046
|
+
throw error;
|
|
1047
|
+
}
|
|
1048
|
+
await nuxt.callHook("build:resources");
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
export { bundle };
|
package/package.json
CHANGED
|
@@ -1,6 +1,73 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt/webpack-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "3.0.0-rc.0",
|
|
4
|
+
"repository": "nuxt/framework",
|
|
4
5
|
"license": "MIT",
|
|
5
|
-
"
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.mjs",
|
|
10
|
+
"./dist/*": "./dist/*"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"prepack": "unbuild"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@babel/core": "^7.17.9",
|
|
20
|
+
"@nuxt/friendly-errors-webpack-plugin": "^2.5.2",
|
|
21
|
+
"@nuxt/kit": "3.0.0-rc.0",
|
|
22
|
+
"autoprefixer": "^10.4.4",
|
|
23
|
+
"css-loader": "^6.7.1",
|
|
24
|
+
"css-minimizer-webpack-plugin": "^3.4.1",
|
|
25
|
+
"cssnano": "^5.1.7",
|
|
26
|
+
"esbuild-loader": "^2.18.0",
|
|
27
|
+
"escape-string-regexp": "^5.0.0",
|
|
28
|
+
"file-loader": "^6.2.0",
|
|
29
|
+
"fork-ts-checker-webpack-plugin": "^7.2.6",
|
|
30
|
+
"fs-extra": "^10.1.0",
|
|
31
|
+
"hash-sum": "^2.0.0",
|
|
32
|
+
"lodash-es": "^4.17.21",
|
|
33
|
+
"magic-string": "^0.26.1",
|
|
34
|
+
"memfs": "^3.4.1",
|
|
35
|
+
"mini-css-extract-plugin": "^2.6.0",
|
|
36
|
+
"mlly": "^0.5.2",
|
|
37
|
+
"pathe": "^0.2.0",
|
|
38
|
+
"pify": "^5.0.0",
|
|
39
|
+
"postcss": "^8.4.12",
|
|
40
|
+
"postcss-import": "^14.1.0",
|
|
41
|
+
"postcss-loader": "^6.2.1",
|
|
42
|
+
"postcss-url": "^10.1.3",
|
|
43
|
+
"style-resources-loader": "^1.5.0",
|
|
44
|
+
"time-fix-plugin": "^2.0.7",
|
|
45
|
+
"ufo": "^0.8.3",
|
|
46
|
+
"unplugin": "^0.6.2",
|
|
47
|
+
"url-loader": "^4.1.1",
|
|
48
|
+
"vue-loader": "^17.0.0",
|
|
49
|
+
"vue-style-loader": "^4.1.3",
|
|
50
|
+
"webpack": "^5.72.0",
|
|
51
|
+
"webpack-bundle-analyzer": "^4.5.0",
|
|
52
|
+
"webpack-dev-middleware": "^5.3.1",
|
|
53
|
+
"webpack-hot-middleware": "^2.25.1",
|
|
54
|
+
"webpack-virtual-modules": "^0.4.3",
|
|
55
|
+
"webpackbar": "^5.0.2"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@nuxt/schema": "3.0.0-rc.0",
|
|
59
|
+
"@types/pify": "^5.0.1",
|
|
60
|
+
"@types/webpack-bundle-analyzer": "^4.4.1",
|
|
61
|
+
"@types/webpack-dev-middleware": "^5.0.2",
|
|
62
|
+
"@types/webpack-hot-middleware": "^2.25.6",
|
|
63
|
+
"@types/webpack-virtual-modules": "^0",
|
|
64
|
+
"unbuild": "latest",
|
|
65
|
+
"vue": "3.2.33"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"vue": "3.2.33"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0"
|
|
72
|
+
}
|
|
6
73
|
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
throw new Error('This is a placeholder package. Please use `@nuxt/webpack-builder-edge`. Learn more: https://v3.nuxtjs.org')
|