@shuvi/toolpack 0.0.1-pre.1
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/lib/babel/plugins/auto-css-modules.d.ts +7 -0
- package/lib/babel/plugins/auto-css-modules.js +24 -0
- package/lib/babel/plugins/jsx-pragma.d.ts +4 -0
- package/lib/babel/plugins/jsx-pragma.js +77 -0
- package/lib/babel/plugins/loadable-plugin.d.ts +24 -0
- package/lib/babel/plugins/loadable-plugin.js +105 -0
- package/lib/babel/plugins/optimize-hook-destructuring.d.ts +4 -0
- package/lib/babel/plugins/optimize-hook-destructuring.js +59 -0
- package/lib/babel/preset.d.ts +14 -0
- package/lib/babel/preset.js +106 -0
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +3 -0
- package/lib/utils/emptyComponent.d.ts +1 -0
- package/lib/utils/emptyComponent.js +7 -0
- package/lib/utils/forkTsCheckerWebpackPlugin.d.ts +4 -0
- package/lib/utils/forkTsCheckerWebpackPlugin.js +9 -0
- package/lib/utils/formatWebpackMessages.d.ts +5 -0
- package/lib/utils/formatWebpackMessages.js +91 -0
- package/lib/utils/hotDevClient/eventsource.d.ts +1 -0
- package/lib/utils/hotDevClient/eventsource.js +63 -0
- package/lib/utils/hotDevClient/index.d.ts +4 -0
- package/lib/utils/hotDevClient/index.js +304 -0
- package/lib/utils/verifyTypeScriptSetup.d.ts +5 -0
- package/lib/utils/verifyTypeScriptSetup.js +229 -0
- package/lib/webpack/config/base.d.ts +16 -0
- package/lib/webpack/config/base.js +236 -0
- package/lib/webpack/config/browser.d.ts +8 -0
- package/lib/webpack/config/browser.js +147 -0
- package/lib/webpack/config/index.d.ts +4 -0
- package/lib/webpack/config/index.js +9 -0
- package/lib/webpack/config/node.d.ts +7 -0
- package/lib/webpack/config/node.js +55 -0
- package/lib/webpack/config/parts/external.d.ts +4 -0
- package/lib/webpack/config/parts/external.js +91 -0
- package/lib/webpack/config/parts/helpers.d.ts +3 -0
- package/lib/webpack/config/parts/helpers.js +48 -0
- package/lib/webpack/config/parts/resolve.d.ts +1 -0
- package/lib/webpack/config/parts/resolve.js +10 -0
- package/lib/webpack/config/parts/style.d.ts +9 -0
- package/lib/webpack/config/parts/style.js +217 -0
- package/lib/webpack/loaders/export-global-loader.d.ts +7 -0
- package/lib/webpack/loaders/export-global-loader.js +26 -0
- package/lib/webpack/loaders/route-component-loader.d.ts +7 -0
- package/lib/webpack/loaders/route-component-loader.js +14 -0
- package/lib/webpack/loaders/shuvi-babel-loader.d.ts +1 -0
- package/lib/webpack/loaders/shuvi-babel-loader.js +60 -0
- package/lib/webpack/plugins/build-manifest-plugin.d.ts +27 -0
- package/lib/webpack/plugins/build-manifest-plugin.js +215 -0
- package/lib/webpack/plugins/chunk-names-plugin.d.ts +4 -0
- package/lib/webpack/plugins/chunk-names-plugin.js +43 -0
- package/lib/webpack/plugins/fix-watching-plugin.d.ts +4 -0
- package/lib/webpack/plugins/fix-watching-plugin.js +23 -0
- package/lib/webpack/plugins/module-replace-plugin/index.d.ts +1 -0
- package/lib/webpack/plugins/module-replace-plugin/index.js +4 -0
- package/lib/webpack/plugins/module-replace-plugin/plugin.d.ts +31 -0
- package/lib/webpack/plugins/module-replace-plugin/plugin.js +177 -0
- package/lib/webpack/plugins/module-replace-plugin/stub-loader.d.ts +1 -0
- package/lib/webpack/plugins/module-replace-plugin/stub-loader.js +34 -0
- package/lib/webpack/plugins/prefer-resolver-plugin.d.ts +10 -0
- package/lib/webpack/plugins/prefer-resolver-plugin.js +47 -0
- package/lib/webpack/plugins/require-cache-hot-reloader-plugin.d.ts +6 -0
- package/lib/webpack/plugins/require-cache-hot-reloader-plugin.js +48 -0
- package/lib/webpack/types.d.ts +40 -0
- package/lib/webpack/types.js +2 -0
- package/package.json +80 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const constants_1 = require("@shuvi/shared/lib/constants");
|
|
7
|
+
const Rule_1 = __importDefault(require("webpack-chain/src/Rule"));
|
|
8
|
+
const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
|
|
9
|
+
const loader_utils_1 = __importDefault(require("loader-utils"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const helpers_1 = require("./helpers");
|
|
12
|
+
function getCSSModuleLocalIdent(context, localIdentName, localName, options) {
|
|
13
|
+
// Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
|
|
14
|
+
const fileNameOrFolder = context.resourcePath.match(/index\.module\.(css|scss|sass)$/)
|
|
15
|
+
? '[folder]'
|
|
16
|
+
: '[name]';
|
|
17
|
+
// Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
|
|
18
|
+
const hash = loader_utils_1.default.getHashDigest(
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
path_1.default.posix.relative(context.rootContext, context.resourcePath) + localName, 'md5', 'base64', 5);
|
|
21
|
+
// Use loaderUtils to find the file or folder name
|
|
22
|
+
const className = loader_utils_1.default.interpolateName(context, fileNameOrFolder + '_' + localName + '__' + hash, options);
|
|
23
|
+
// remove the .module that appears in every classname when based on the file.
|
|
24
|
+
return className.replace('.module_', '_');
|
|
25
|
+
}
|
|
26
|
+
// style files regexes
|
|
27
|
+
const cssRegex = /\.css$/;
|
|
28
|
+
const cssModuleQueryRegex = /cssmodules/;
|
|
29
|
+
const sassRegex = /\.(scss|sass)$/;
|
|
30
|
+
function ssrCssRule({ test, resourceQuery, scss }) {
|
|
31
|
+
const rule = new Rule_1.default();
|
|
32
|
+
rule.test(test);
|
|
33
|
+
if (resourceQuery) {
|
|
34
|
+
rule.resourceQuery(resourceQuery);
|
|
35
|
+
}
|
|
36
|
+
rule
|
|
37
|
+
.use('css-loader')
|
|
38
|
+
.loader(require.resolve('css-loader'))
|
|
39
|
+
.options({
|
|
40
|
+
sourceMap: false,
|
|
41
|
+
importLoaders: scss ? 1 : 0,
|
|
42
|
+
esModule: true,
|
|
43
|
+
modules: {
|
|
44
|
+
getLocalIdent: getCSSModuleLocalIdent,
|
|
45
|
+
exportOnlyLocals: true
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
if (scss) {
|
|
49
|
+
rule.use('sass-loader').loader(require.resolve('sass-loader')).options({
|
|
50
|
+
sourceMap: false
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return rule;
|
|
54
|
+
}
|
|
55
|
+
function cssRule({ publicPath, test, resourceQuery, cssModule, extractCss, sourceMap, scss }) {
|
|
56
|
+
const rule = new Rule_1.default();
|
|
57
|
+
rule.test(test);
|
|
58
|
+
if (resourceQuery) {
|
|
59
|
+
rule.resourceQuery(resourceQuery);
|
|
60
|
+
}
|
|
61
|
+
// A global CSS import always has side effects. Webpack will tree
|
|
62
|
+
// shake the CSS without this option if the issuer claims to have
|
|
63
|
+
// no side-effects.
|
|
64
|
+
// See https://github.com/webpack/webpack/issues/6571
|
|
65
|
+
rule.set('sideEffects', true);
|
|
66
|
+
if (extractCss) {
|
|
67
|
+
rule
|
|
68
|
+
.use('extract-loader')
|
|
69
|
+
.loader(mini_css_extract_plugin_1.default.loader)
|
|
70
|
+
.options(Object.assign({}, (publicPath && helpers_1.shouldUseRelativeAssetPaths(publicPath)
|
|
71
|
+
? {
|
|
72
|
+
// path relative to outdir from the generated css file
|
|
73
|
+
publicPath: '../../'
|
|
74
|
+
}
|
|
75
|
+
: {})));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
rule
|
|
79
|
+
.use('style-loader')
|
|
80
|
+
.loader(require.resolve('style-loader'))
|
|
81
|
+
.options({
|
|
82
|
+
insert: new Function('element', `
|
|
83
|
+
// These elements should always exist. If they do not,
|
|
84
|
+
// this code should fail.
|
|
85
|
+
var anchorElement = document.querySelector("#${constants_1.DEV_STYLE_ANCHOR_ID}");
|
|
86
|
+
var parentNode = anchorElement.parentNode; // Normally <head>
|
|
87
|
+
|
|
88
|
+
// Each style tag should be placed right before our
|
|
89
|
+
// anchor. By inserting before and not after, we do not
|
|
90
|
+
// need to track the last inserted element.
|
|
91
|
+
parentNode.insertBefore(element, anchorElement);
|
|
92
|
+
|
|
93
|
+
window["${constants_1.DEV_STYLE_PREPARE}"] = new Promise(function(resolve) {
|
|
94
|
+
(window.requestAnimationFrame || setTimeout)(function() {
|
|
95
|
+
resolve();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
`),
|
|
99
|
+
esModule: true
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
rule
|
|
103
|
+
.use('css-loader')
|
|
104
|
+
.loader(require.resolve('css-loader'))
|
|
105
|
+
.options(Object.assign({ sourceMap, importLoaders: scss ? 2 : 1, esModule: true }, (cssModule && {
|
|
106
|
+
modules: {
|
|
107
|
+
getLocalIdent: getCSSModuleLocalIdent
|
|
108
|
+
// exportOnlyLocals: true,
|
|
109
|
+
}
|
|
110
|
+
})));
|
|
111
|
+
rule
|
|
112
|
+
.use('postcss-loader')
|
|
113
|
+
.loader(require.resolve('postcss-loader'))
|
|
114
|
+
.options({
|
|
115
|
+
sourceMap,
|
|
116
|
+
postcssOptions: {
|
|
117
|
+
plugins: [
|
|
118
|
+
// Make Flexbox behave like the spec cross-browser.
|
|
119
|
+
require('postcss-flexbugs-fixes'),
|
|
120
|
+
// Run Autoprefixer and compile new CSS features.
|
|
121
|
+
require('postcss-preset-env')({
|
|
122
|
+
autoprefixer: {
|
|
123
|
+
flexbox: 'no-2009'
|
|
124
|
+
},
|
|
125
|
+
stage: 3
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
if (scss) {
|
|
131
|
+
rule.use('sass-loader').loader(require.resolve('sass-loader')).options({
|
|
132
|
+
sourceMap
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return rule;
|
|
136
|
+
}
|
|
137
|
+
function withStyle(chain, { extractCss, sourceMap, ssr, publicPath }) {
|
|
138
|
+
const oneOfs = chain.module.rule('main').oneOfs;
|
|
139
|
+
if (ssr) {
|
|
140
|
+
oneOfs.set('css-module',
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
ssrCssRule({
|
|
143
|
+
test: cssRegex,
|
|
144
|
+
resourceQuery: cssModuleQueryRegex,
|
|
145
|
+
scss: false
|
|
146
|
+
}).after('js'));
|
|
147
|
+
oneOfs.set('scss-module',
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
ssrCssRule({
|
|
150
|
+
test: sassRegex,
|
|
151
|
+
resourceQuery: cssModuleQueryRegex,
|
|
152
|
+
scss: true
|
|
153
|
+
}).after('css-module'));
|
|
154
|
+
const ignoreRule = new Rule_1.default();
|
|
155
|
+
ignoreRule
|
|
156
|
+
.test([cssRegex, sassRegex])
|
|
157
|
+
.use('ignore-loader')
|
|
158
|
+
.loader(require.resolve('ignore-loader'))
|
|
159
|
+
.end()
|
|
160
|
+
.after('scss-module');
|
|
161
|
+
// @ts-ignore
|
|
162
|
+
oneOfs.set('ignore', ignoreRule);
|
|
163
|
+
return chain;
|
|
164
|
+
}
|
|
165
|
+
if (extractCss) {
|
|
166
|
+
chain.plugin('mini-css-extract-plugin').use(mini_css_extract_plugin_1.default, [
|
|
167
|
+
{
|
|
168
|
+
filename: 'static/css/[contenthash:8].css',
|
|
169
|
+
chunkFilename: 'static/css/[contenthash:8].chunk.css'
|
|
170
|
+
}
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
oneOfs.set('css-module',
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
cssRule({
|
|
176
|
+
test: cssRegex,
|
|
177
|
+
resourceQuery: cssModuleQueryRegex,
|
|
178
|
+
cssModule: true,
|
|
179
|
+
scss: false,
|
|
180
|
+
extractCss,
|
|
181
|
+
sourceMap,
|
|
182
|
+
publicPath
|
|
183
|
+
}).after('js'));
|
|
184
|
+
oneOfs.set('css',
|
|
185
|
+
// @ts-ignore
|
|
186
|
+
cssRule({
|
|
187
|
+
test: cssRegex,
|
|
188
|
+
cssModule: false,
|
|
189
|
+
scss: false,
|
|
190
|
+
extractCss,
|
|
191
|
+
sourceMap,
|
|
192
|
+
publicPath
|
|
193
|
+
}).after('css-module'));
|
|
194
|
+
oneOfs.set('scss-module',
|
|
195
|
+
// @ts-ignore
|
|
196
|
+
cssRule({
|
|
197
|
+
test: sassRegex,
|
|
198
|
+
resourceQuery: cssModuleQueryRegex,
|
|
199
|
+
cssModule: true,
|
|
200
|
+
scss: true,
|
|
201
|
+
extractCss,
|
|
202
|
+
sourceMap,
|
|
203
|
+
publicPath
|
|
204
|
+
}).after('css'));
|
|
205
|
+
oneOfs.set('scss',
|
|
206
|
+
// @ts-ignore
|
|
207
|
+
cssRule({
|
|
208
|
+
test: sassRegex,
|
|
209
|
+
cssModule: false,
|
|
210
|
+
scss: true,
|
|
211
|
+
extractCss,
|
|
212
|
+
sourceMap,
|
|
213
|
+
publicPath
|
|
214
|
+
}).after('scss-module'));
|
|
215
|
+
return chain;
|
|
216
|
+
}
|
|
217
|
+
exports.withStyle = withStyle;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const loader_utils_1 = __importDefault(require("loader-utils"));
|
|
7
|
+
const nextClientPagesLoader = function () {
|
|
8
|
+
const { absolutePath, exportName, globalName } = loader_utils_1.default.getOptions(this);
|
|
9
|
+
const stringifyGlobalName = JSON.stringify(globalName);
|
|
10
|
+
const stringifyAbsolutePath = loader_utils_1.default.stringifyRequest(this, absolutePath);
|
|
11
|
+
const stringifyName = JSON.stringify(exportName);
|
|
12
|
+
return `
|
|
13
|
+
var mod = require(${stringifyAbsolutePath})
|
|
14
|
+
(window[${stringifyGlobalName}] = window[${stringifyGlobalName}] || {})[${stringifyName}] = mod.default || mod
|
|
15
|
+
|
|
16
|
+
if(module.hot) {
|
|
17
|
+
module.hot.accept(${stringifyAbsolutePath}, function() {
|
|
18
|
+
if(!${stringifyGlobalName} in window) return
|
|
19
|
+
|
|
20
|
+
var updatedMod = require(${stringifyAbsolutePath})
|
|
21
|
+
window[${stringifyGlobalName}] = updatedMod.default || updatedMod
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
};
|
|
26
|
+
exports.default = nextClientPagesLoader;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const loader_utils_1 = __importDefault(require("loader-utils"));
|
|
7
|
+
const routeComponentLoader = function () {
|
|
8
|
+
const { componentAbsolutePath } = loader_utils_1.default.getOptions(this);
|
|
9
|
+
const stringifyRequest = loader_utils_1.default.stringifyRequest(this, `${componentAbsolutePath}?__shuvi-route`);
|
|
10
|
+
return `
|
|
11
|
+
const = require(${stringifyRequest})
|
|
12
|
+
`.trim();
|
|
13
|
+
};
|
|
14
|
+
exports.default = routeComponentLoader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const babel_loader_1 = __importDefault(require("babel-loader"));
|
|
7
|
+
const preset_1 = __importDefault(require("../../babel/preset"));
|
|
8
|
+
function hasBuiltPreset(presets) {
|
|
9
|
+
return presets.some(preset => preset && preset.value === preset_1.default);
|
|
10
|
+
}
|
|
11
|
+
module.exports = babel_loader_1.default.custom((babel) => {
|
|
12
|
+
const presetItem = babel.createConfigItem(preset_1.default, {
|
|
13
|
+
type: 'preset'
|
|
14
|
+
});
|
|
15
|
+
const configs = new Set();
|
|
16
|
+
return {
|
|
17
|
+
customOptions(opts) {
|
|
18
|
+
const custom = {
|
|
19
|
+
isNode: opts.isNode
|
|
20
|
+
};
|
|
21
|
+
const loader = Object.assign(opts.cacheDirectory
|
|
22
|
+
? {
|
|
23
|
+
cacheCompression: false
|
|
24
|
+
}
|
|
25
|
+
: {
|
|
26
|
+
cacheDirectory: false
|
|
27
|
+
}, opts);
|
|
28
|
+
delete loader.isNode;
|
|
29
|
+
return { loader, custom };
|
|
30
|
+
},
|
|
31
|
+
config(cfg, { source, customOptions: { isNode } }) {
|
|
32
|
+
const options = Object.assign({}, cfg.options);
|
|
33
|
+
if (cfg.hasFilesystemConfig()) {
|
|
34
|
+
for (const file of [cfg.babelrc, cfg.config]) {
|
|
35
|
+
// We only log for client compilation otherwise there will be double output
|
|
36
|
+
if (file && !isNode && !configs.has(file)) {
|
|
37
|
+
configs.add(file);
|
|
38
|
+
console.log(`> Using external babel configuration`);
|
|
39
|
+
console.log(`> Location: "${file}"`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Add built-in preset
|
|
44
|
+
if (!hasBuiltPreset(options.presets)) {
|
|
45
|
+
options.presets = [presetItem, ...options.presets];
|
|
46
|
+
}
|
|
47
|
+
// pass option to babel-preset
|
|
48
|
+
options.caller.isNode = isNode;
|
|
49
|
+
options.plugins = options.plugins || [];
|
|
50
|
+
options.plugins.push([
|
|
51
|
+
require.resolve('babel-plugin-transform-define'),
|
|
52
|
+
{
|
|
53
|
+
'typeof window': isNode ? 'undefined' : 'object'
|
|
54
|
+
},
|
|
55
|
+
'shuvi-transform-define-instance'
|
|
56
|
+
]);
|
|
57
|
+
return options;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Compiler, Compilation, Plugin } from 'webpack';
|
|
2
|
+
interface Options {
|
|
3
|
+
filename: string;
|
|
4
|
+
modules: boolean;
|
|
5
|
+
chunkRequest: boolean;
|
|
6
|
+
}
|
|
7
|
+
export default class BuildManifestPlugin implements Plugin {
|
|
8
|
+
private _options;
|
|
9
|
+
private _manifest;
|
|
10
|
+
constructor(options?: Partial<Options>);
|
|
11
|
+
createAssets(compiler: Compiler, compilation: Compilation): {
|
|
12
|
+
entries: {};
|
|
13
|
+
bundles: {};
|
|
14
|
+
chunkRequest: {};
|
|
15
|
+
loadble: {};
|
|
16
|
+
};
|
|
17
|
+
apply(compiler: Compiler): void;
|
|
18
|
+
private _collectEntries;
|
|
19
|
+
private _collect;
|
|
20
|
+
private _collectChunk;
|
|
21
|
+
private _collectChunkModule;
|
|
22
|
+
private _pushEntries;
|
|
23
|
+
private _pushBundle;
|
|
24
|
+
private _pushChunkRequest;
|
|
25
|
+
private _pushLoadableModules;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const webpack_1 = __importDefault(require("webpack"));
|
|
7
|
+
const Entrypoint_1 = __importDefault(require("webpack/lib/Entrypoint"));
|
|
8
|
+
const { RawSource } = webpack_1.default.sources;
|
|
9
|
+
const defaultOptions = {
|
|
10
|
+
filename: 'build-manifest.json',
|
|
11
|
+
modules: false,
|
|
12
|
+
chunkRequest: false
|
|
13
|
+
};
|
|
14
|
+
function getFileExt(filepath) {
|
|
15
|
+
const match = filepath.match(/\.(\w+)$/);
|
|
16
|
+
if (!match)
|
|
17
|
+
return '';
|
|
18
|
+
return match[1];
|
|
19
|
+
}
|
|
20
|
+
// function findEntrypointName(chunkGroup: any): string[] {
|
|
21
|
+
// const entrypoints: any[] = [];
|
|
22
|
+
// const queue: any[] = [chunkGroup];
|
|
23
|
+
// while (queue.length) {
|
|
24
|
+
// const item = queue.shift();
|
|
25
|
+
// for (const parent of item.getParents()) {
|
|
26
|
+
// if (parent instanceof Entrypoint) {
|
|
27
|
+
// entrypoints.push(parent.name);
|
|
28
|
+
// } else {
|
|
29
|
+
// queue.push(parent);
|
|
30
|
+
// }
|
|
31
|
+
// }
|
|
32
|
+
// }
|
|
33
|
+
// return entrypoints;
|
|
34
|
+
// }
|
|
35
|
+
// This plugin creates a build-manifest.json for all assets that are being output
|
|
36
|
+
// It has a mapping of "entry" filename to real filename. Because the real filename can be hashed in production
|
|
37
|
+
class BuildManifestPlugin {
|
|
38
|
+
constructor(options = {}) {
|
|
39
|
+
this._options = Object.assign(Object.assign({}, defaultOptions), options);
|
|
40
|
+
}
|
|
41
|
+
createAssets(compiler, compilation) {
|
|
42
|
+
const assetMap = (this._manifest = {
|
|
43
|
+
entries: {},
|
|
44
|
+
bundles: {},
|
|
45
|
+
chunkRequest: {},
|
|
46
|
+
loadble: {}
|
|
47
|
+
});
|
|
48
|
+
const chunkRootModulesMap = new Map();
|
|
49
|
+
compilation.chunks.forEach(chunk => {
|
|
50
|
+
const { chunkGraph } = compilation;
|
|
51
|
+
if (chunkGraph) {
|
|
52
|
+
chunkGraph.getChunkRootModules(chunk).forEach(module => {
|
|
53
|
+
const id = chunkGraph.getModuleId(module);
|
|
54
|
+
if (id !== '') {
|
|
55
|
+
chunkRootModulesMap.set(id, true);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
compilation.chunkGroups.forEach(chunkGroup => {
|
|
61
|
+
if (chunkGroup instanceof Entrypoint_1.default) {
|
|
62
|
+
this._collectEntries(chunkGroup);
|
|
63
|
+
}
|
|
64
|
+
this._collect(chunkGroup, compiler, compilation, chunkRootModulesMap);
|
|
65
|
+
});
|
|
66
|
+
this._manifest.loadble = Object.keys(this._manifest.loadble)
|
|
67
|
+
.sort()
|
|
68
|
+
// eslint-disable-next-line no-sequences
|
|
69
|
+
.reduce((a, c) => ((a[c] = this._manifest.loadble[c]), a), {});
|
|
70
|
+
return assetMap;
|
|
71
|
+
}
|
|
72
|
+
apply(compiler) {
|
|
73
|
+
compiler.hooks.make.tap('BuildManifestPlugin', compilation => {
|
|
74
|
+
compilation.hooks.processAssets.tap({
|
|
75
|
+
name: 'BuildManifestPlugin',
|
|
76
|
+
stage: webpack_1.default.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
|
77
|
+
}, assets => {
|
|
78
|
+
assets[this._options.filename] = new RawSource(JSON.stringify(this.createAssets(compiler, compilation), null, 2), true);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
_collectEntries(entrypoint) {
|
|
83
|
+
for (const chunk of entrypoint.chunks) {
|
|
84
|
+
// If there's no name or no files
|
|
85
|
+
if (!chunk.name || !chunk.files) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
for (const file of chunk.files) {
|
|
89
|
+
if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const ext = getFileExt(file);
|
|
93
|
+
this._pushEntries(entrypoint.name, ext, file.replace(/\\/g, '/'));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
_collect(chunkGroup, compiler, compilation, chunkRootModulesMap) {
|
|
98
|
+
const collectModules = this._options.modules;
|
|
99
|
+
chunkGroup.origins.forEach(chunkGroupOrigin => {
|
|
100
|
+
const { request } = chunkGroupOrigin;
|
|
101
|
+
const ctx = { request, compiler, compilation, chunkRootModulesMap };
|
|
102
|
+
chunkGroup.chunks.forEach(chunk => {
|
|
103
|
+
this._collectChunk(chunk, ctx);
|
|
104
|
+
if (collectModules) {
|
|
105
|
+
this._collectChunkModule(chunk, ctx);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
_collectChunk(chunk, { request }) {
|
|
111
|
+
if (!chunk.files) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
for (const file of chunk.files) {
|
|
115
|
+
if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const ext = getFileExt(file);
|
|
119
|
+
const normalizedPath = file.replace(/\\/g, '/');
|
|
120
|
+
// normal chunk
|
|
121
|
+
if (ext === 'js') {
|
|
122
|
+
if (chunk.isOnlyInitial()) {
|
|
123
|
+
this._pushBundle({
|
|
124
|
+
name: chunk.name,
|
|
125
|
+
file: normalizedPath
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
this._pushChunkRequest({
|
|
129
|
+
file: normalizedPath,
|
|
130
|
+
request
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
_collectChunkModule(chunk, { request, compiler, compilation, chunkRootModulesMap }) {
|
|
136
|
+
if (chunk.canBeInitial()) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const context = compiler.options.context;
|
|
140
|
+
chunk.files.forEach((file) => {
|
|
141
|
+
const isJs = file.match(/\.js$/) && file.match(/^static\/chunks\//);
|
|
142
|
+
const isCss = file.match(/\.css$/) && file.match(/^static\/css\//);
|
|
143
|
+
if (isJs || isCss) {
|
|
144
|
+
this._pushLoadableModules(request, file);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const { chunkGraph } = compilation;
|
|
148
|
+
if (chunkGraph) {
|
|
149
|
+
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
|
150
|
+
let id = chunkGraph.getModuleId(module);
|
|
151
|
+
if (!module.type.startsWith('javascript')) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
let name = typeof module.libIdent === 'function'
|
|
155
|
+
? module.libIdent({ context })
|
|
156
|
+
: null;
|
|
157
|
+
if (!name || name.endsWith('.css')) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (chunkRootModulesMap.has(id)) {
|
|
161
|
+
this._pushLoadableModules(request, {
|
|
162
|
+
id,
|
|
163
|
+
name
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
_pushEntries(name, ext, value) {
|
|
170
|
+
const entries = this._manifest.entries;
|
|
171
|
+
if (!entries[name]) {
|
|
172
|
+
entries[name] = {
|
|
173
|
+
js: []
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (!entries[name][ext]) {
|
|
177
|
+
entries[name][ext] = [value];
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
entries[name][ext].push(value);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
_pushBundle({ name, file }) {
|
|
184
|
+
if (name) {
|
|
185
|
+
this._manifest.bundles[name] = file;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
_pushChunkRequest({ file, request }) {
|
|
189
|
+
if (this._options.chunkRequest && request) {
|
|
190
|
+
this._manifest.chunkRequest[file] = request;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
_pushLoadableModules(request, value) {
|
|
194
|
+
const modules = this._manifest.loadble;
|
|
195
|
+
if (!modules[request]) {
|
|
196
|
+
modules[request] = {
|
|
197
|
+
files: [],
|
|
198
|
+
children: []
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (typeof value === 'string') {
|
|
202
|
+
const existed = modules[request].files.some(file => file === value);
|
|
203
|
+
if (!existed) {
|
|
204
|
+
modules[request].files.push(value);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const existed = modules[request].children.some(item => item.id === value.id);
|
|
209
|
+
if (!existed) {
|
|
210
|
+
modules[request].children.push(value);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.default = BuildManifestPlugin;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const webpack_1 = require("webpack");
|
|
4
|
+
// This plugin mirrors webpack 3 `filename` and `chunkfilename` behavior
|
|
5
|
+
// This fixes https://github.com/webpack/webpack/issues/6598
|
|
6
|
+
// This plugin is based on https://github.com/researchgate/webpack/commit/2f28947fa0c63ccbb18f39c0098bd791a2c37090
|
|
7
|
+
class ChunkNamesPlugin {
|
|
8
|
+
apply(compiler) {
|
|
9
|
+
compiler.hooks.compilation.tap('ChunkNamesPlugin', compilation => {
|
|
10
|
+
compilation.hooks.renderManifest.intercept({
|
|
11
|
+
register(tapInfo) {
|
|
12
|
+
if (tapInfo.name === 'JavascriptModulesPlugin') {
|
|
13
|
+
const originalMethod = tapInfo.fn;
|
|
14
|
+
tapInfo.fn = (result, options) => {
|
|
15
|
+
let filenameTemplate;
|
|
16
|
+
const chunk = options.chunk;
|
|
17
|
+
const outputOptions = options.outputOptions;
|
|
18
|
+
// Note: fix Conflict: Multiple assets emit different content to the same filename static/chunks/page-xxxx.js
|
|
19
|
+
if (chunk instanceof webpack_1.HotUpdateChunk) {
|
|
20
|
+
return originalMethod(result, options);
|
|
21
|
+
}
|
|
22
|
+
const chunkGraph = options.chunkGraph;
|
|
23
|
+
const hasEntryModule = chunkGraph.getNumberOfEntryModules(chunk) > 0;
|
|
24
|
+
if (chunk.filenameTemplate) {
|
|
25
|
+
filenameTemplate = chunk.filenameTemplate;
|
|
26
|
+
}
|
|
27
|
+
else if (chunk.hasRuntime() || hasEntryModule) {
|
|
28
|
+
filenameTemplate = outputOptions.filename;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
filenameTemplate = outputOptions.chunkFilename;
|
|
32
|
+
}
|
|
33
|
+
options.chunk.filenameTemplate = filenameTemplate;
|
|
34
|
+
return originalMethod(result, options);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return tapInfo;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.default = ChunkNamesPlugin;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const TIME_FIX = 5000;
|
|
4
|
+
const PLUGIN_NAME = 'fix-watching-plugin';
|
|
5
|
+
class FixWatchingPlugin {
|
|
6
|
+
apply(compiler) {
|
|
7
|
+
let watching;
|
|
8
|
+
let restored = false;
|
|
9
|
+
const aspectWatch = compiler.watch;
|
|
10
|
+
compiler.watch = function (...args) {
|
|
11
|
+
watching = aspectWatch.apply(compiler, args);
|
|
12
|
+
watching.startTime += TIME_FIX;
|
|
13
|
+
return watching;
|
|
14
|
+
};
|
|
15
|
+
compiler.hooks.done.tap(PLUGIN_NAME, stats => {
|
|
16
|
+
if (watching && !restored) {
|
|
17
|
+
stats.compilation.startTime -= TIME_FIX;
|
|
18
|
+
restored = true;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.default = FixWatchingPlugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./plugin";
|