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