Skip to content

Commit 62c3fd3

Browse files
committed
feat: add plugin hook 'createChainWebpackConfigInstance'
1 parent a08b9bc commit 62c3fd3

File tree

6 files changed

+142
-117
lines changed

6 files changed

+142
-117
lines changed

src/extends/enhance/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ module.exports = function WebpackAdapter(api, opts) {
2121
logger.throw('please call after "onInitWillDone" !');
2222
}
2323

24-
const webpackChainConfig = new Config();
24+
// 可通过外部初始化一个已存在的 webpackChain 实例
25+
const webpackChainConfig = api.applyPluginHooks('createChainWebpackConfigInstance', new Config(), options);
26+
2527
const selfConfig = api.selfConfig || {};
2628
const originalConfig = selfConfig.originalConfig || {};
2729
const _originalWebpackConfig = _.cloneDeep(originalConfig.webpack || {});

src/extends/enhance/methods.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
module.exports = (api, opts) => {
44

5+
api.registerMethod('createChainWebpackConfigInstance', {
6+
type: api.API_TYPE.MODIFY,
7+
description: '在 webpack 配置开始前提供一个 webpack-chain 实例.(用于内部特殊场景)',
8+
});
9+
510
api.registerMethod('modifyChainWebpackConfig', {
611
type: api.API_TYPE.MODIFY,
712
description: '合并之后提供 webpack-chain 进行再次修改事件',

src/extends/unified/app.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'use strict';
2+
3+
module.exports = function unifiedExtend(api, opts) {
4+
5+
api.assertVersion('>=0.3.0');
6+
7+
const { tryRequire } = require('@micro-app/shared-utils');
8+
9+
const CHUNK_NAME = 'runtime';
10+
const CHUNK_VENDORS_NAME = 'chunk-vendors';
11+
const CHUNK_COMMON_NAME = 'chunk-common';
12+
13+
function chunkConfig(webpackChain) {
14+
15+
webpackChain.optimization.runtimeChunk({ name: CHUNK_NAME });
16+
webpackChain.optimization.usedExports(true);
17+
18+
// code splitting
19+
webpackChain
20+
.optimization.splitChunks({
21+
cacheGroups: {
22+
vendors: {
23+
name: CHUNK_VENDORS_NAME,
24+
test: /[\\/]node_modules[\\/]/,
25+
priority: -10,
26+
chunks: 'initial',
27+
},
28+
common: {
29+
name: CHUNK_COMMON_NAME,
30+
minChunks: 2,
31+
priority: -20,
32+
chunks: 'initial',
33+
reuseExistingChunk: true,
34+
},
35+
},
36+
});
37+
}
38+
39+
api.modifyChainWebpackConfig(webpackChain => {
40+
41+
const options = api.config || {};
42+
43+
const entry = options.entry || {};
44+
// entry
45+
Object.keys(entry).forEach(key => {
46+
webpackChain.entry(key).merge(entry[key]);
47+
});
48+
49+
// chunk
50+
// code splitting
51+
if (process.env.NODE_ENV !== 'test') {
52+
chunkConfig(webpackChain);
53+
}
54+
55+
const isProd = api.mode === 'production';
56+
57+
// load html
58+
const multiPageConfig = options.pages;
59+
const pages = Object.keys(multiPageConfig);
60+
if (pages.length > 0) {
61+
const HTMLPlugin = tryRequire('html-webpack-plugin');
62+
if (HTMLPlugin) {
63+
pages.forEach((name, index) => {
64+
const htmlOpts = multiPageConfig[name];
65+
const pname = index ? `html-${name}-${index}` : `html-${name}`;
66+
67+
if (!htmlOpts.chunks) {
68+
htmlOpts.chunks = [ name ];
69+
}
70+
71+
if (htmlOpts.chunks && Array.isArray(htmlOpts.chunks)) {
72+
[ CHUNK_COMMON_NAME, CHUNK_VENDORS_NAME, CHUNK_NAME ].forEach(key => {
73+
if (!htmlOpts.chunks.includes(key)) {
74+
htmlOpts.chunks.unshift(key);
75+
}
76+
});
77+
}
78+
79+
if (isProd) { // 暂时不定义,外部自行配置
80+
Object.assign(htmlOpts, {
81+
minify: {
82+
removeComments: true,
83+
collapseWhitespace: true,
84+
removeAttributeQuotes: true,
85+
collapseBooleanAttributes: true,
86+
removeScriptTypeAttributes: true,
87+
// more options:
88+
// https://github.com/kangax/html-minifier#options-quick-reference
89+
},
90+
});
91+
}
92+
93+
webpackChain
94+
.plugin(pname)
95+
.use(HTMLPlugin, [ htmlOpts ]);
96+
});
97+
} else {
98+
api.logger.warn('[webpack]', 'Not Found "html-webpack-plugin"');
99+
}
100+
}
101+
102+
// node
103+
if (webpackChain.get('target') === 'web') {
104+
webpackChain.node
105+
.merge({
106+
// prevent webpack from injecting useless setImmediate polyfill because Vue
107+
// source contains it (although only uses it if it's native).
108+
setImmediate: false,
109+
// process is injected via DefinePlugin, although some 3rd party
110+
// libraries may require a mock to work properly (#934)
111+
process: 'mock',
112+
// prevent webpack from injecting mocks to Node native modules
113+
// that does not make sense for the client
114+
dgram: 'empty',
115+
fs: 'empty',
116+
net: 'empty',
117+
tls: 'empty',
118+
child_process: 'empty',
119+
});
120+
}
121+
122+
return webpackChain;
123+
});
124+
};
125+
126+
module.exports.configuration = {
127+
description: 'webpack 通用应用配置',
128+
};

src/extends/unified/base.js

Lines changed: 1 addition & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@ module.exports = function unifiedExtend(api, opts) {
44

55
api.assertVersion('>=0.3.0');
66

7-
const { tryRequire } = require('@micro-app/shared-utils');
87
const { getAssetPath, isWebpack4 } = require('./utils');
98

10-
const CHUNK_NAME = 'runtime';
11-
const CHUNK_VENDORS_NAME = 'chunk-vendors';
12-
const CHUNK_COMMON_NAME = 'chunk-common';
13-
149
// 通用基础配置
1510
function baseConfig(webpackChain) {
1611
const options = api.config || {};
@@ -41,44 +36,12 @@ module.exports = function unifiedExtend(api, opts) {
4136
return webpackChain;
4237
}
4338

44-
function chunkConfig(webpackChain) {
45-
46-
webpackChain.optimization.runtimeChunk({ name: CHUNK_NAME });
47-
webpackChain.optimization.usedExports(true);
48-
49-
// code splitting
50-
webpackChain
51-
.optimization.splitChunks({
52-
cacheGroups: {
53-
vendors: {
54-
name: CHUNK_VENDORS_NAME,
55-
test: /[\\/]node_modules[\\/]/,
56-
priority: -10,
57-
chunks: 'initial',
58-
},
59-
common: {
60-
name: CHUNK_COMMON_NAME,
61-
minChunks: 2,
62-
priority: -20,
63-
chunks: 'initial',
64-
reuseExistingChunk: true,
65-
},
66-
},
67-
});
68-
}
69-
7039
api.modifyChainWebpackConfig(webpackChain => {
7140

7241
webpackChain = baseConfig(webpackChain);
7342

7443
const options = api.config || {};
7544

76-
const entry = options.entry || {};
77-
// entry
78-
Object.keys(entry).forEach(key => {
79-
webpackChain.entry(key).merge(entry[key]);
80-
});
81-
8245
// reset, 兼容
8346
options.outputDir = webpackChain.output.get('path') || options.outputDir || 'dist';
8447
options.publicPath = webpackChain.output.get('publicPath') || options.publicPath || '/';
@@ -111,84 +74,10 @@ module.exports = function unifiedExtend(api, opts) {
11174
.merge(alias)
11275
.end();
11376

114-
115-
// chunk
116-
// code splitting
117-
if (process.env.NODE_ENV !== 'test') {
118-
chunkConfig(webpackChain);
119-
}
120-
121-
const isProd = api.mode === 'production';
122-
123-
// load html
124-
const multiPageConfig = options.pages;
125-
const pages = Object.keys(multiPageConfig);
126-
if (pages.length > 0) {
127-
const HTMLPlugin = tryRequire('html-webpack-plugin');
128-
if (HTMLPlugin) {
129-
pages.forEach((name, index) => {
130-
const htmlOpts = multiPageConfig[name];
131-
const pname = index ? `html-${name}-${index}` : `html-${name}`;
132-
133-
if (!htmlOpts.chunks) {
134-
htmlOpts.chunks = [ name ];
135-
}
136-
137-
if (htmlOpts.chunks && Array.isArray(htmlOpts.chunks)) {
138-
[ CHUNK_COMMON_NAME, CHUNK_VENDORS_NAME, CHUNK_NAME ].forEach(key => {
139-
if (!htmlOpts.chunks.includes(key)) {
140-
htmlOpts.chunks.unshift(key);
141-
}
142-
});
143-
}
144-
145-
if (isProd) { // 暂时不定义,外部自行配置
146-
Object.assign(htmlOpts, {
147-
minify: {
148-
removeComments: true,
149-
collapseWhitespace: true,
150-
removeAttributeQuotes: true,
151-
collapseBooleanAttributes: true,
152-
removeScriptTypeAttributes: true,
153-
// more options:
154-
// https://github.com/kangax/html-minifier#options-quick-reference
155-
},
156-
});
157-
}
158-
159-
webpackChain
160-
.plugin(pname)
161-
.use(HTMLPlugin, [ htmlOpts ]);
162-
});
163-
} else {
164-
api.logger.warn('[webpack]', 'Not Found "html-webpack-plugin"');
165-
}
166-
}
167-
168-
// node
169-
if (webpackChain.get('target') === 'web') {
170-
webpackChain.node
171-
.merge({
172-
// prevent webpack from injecting useless setImmediate polyfill because Vue
173-
// source contains it (although only uses it if it's native).
174-
setImmediate: false,
175-
// process is injected via DefinePlugin, although some 3rd party
176-
// libraries may require a mock to work properly (#934)
177-
process: 'mock',
178-
// prevent webpack from injecting mocks to Node native modules
179-
// that does not make sense for the client
180-
dgram: 'empty',
181-
fs: 'empty',
182-
net: 'empty',
183-
tls: 'empty',
184-
child_process: 'empty',
185-
});
186-
}
187-
18877
return webpackChain;
18978
});
19079
};
19180

19281
module.exports.configuration = {
193-
description: 'webpack 配置与基础配置参数统一',
82+
description: 'webpack 通用基础配置',
19483
};

src/extends/unified/prod.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ module.exports = function unifiedExtend(api, opts) {
5757
// copy static
5858
const staticPaths = (options.staticPaths || []).filter(item => fs.existsSync(item));
5959
if (staticPaths.length) {
60-
const COPYPlugin = tryRequire('copy-webpack-plugin');
61-
if (COPYPlugin) {
60+
const CopyWebpackPlugin = tryRequire('copy-webpack-plugin');
61+
if (CopyWebpackPlugin) {
6262
webpackChain
6363
.plugin('copy')
64-
.use(COPYPlugin, [ staticPaths.map(publicDir => {
64+
.use(CopyWebpackPlugin, [ staticPaths.map(publicDir => {
6565
return {
6666
from: publicDir,
67-
// to: options.outputDir,
67+
// to: options.outputDir, // 自动使用 webpack 配置
6868
toType: 'dir',
6969
ignore: publicCopyIgnore,
7070
};

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const extendConfigs = [
44
'webpack',
55
'enhance',
66
'unified/base',
7+
'unified/app',
78
'unified/css',
89
'unified/rules',
910
'unified/babel',

0 commit comments

Comments
 (0)