Skip to content

Commit 8701f3e

Browse files
authored
feat: webpack factory (#130)
* fix codecov & update readme * feat: add unittest & fix env factory bug
1 parent 1524f36 commit 8701f3e

File tree

8 files changed

+362
-40
lines changed

8 files changed

+362
-40
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ packages/*/test/**/logs/
2020
packages/*/test/**/run/
2121
packages/*/yarn.lock
2222
package-lock.json
23+
.nyc_output/

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ before_install:
1010
- rm -rf ./examples/
1111
install:
1212
- npm install
13+
- npm install -g codecov
1314
script:
1415
# TODO: Use 'lerna run ci' instead
1516
- npm run ci

packages/beidou-webpack/README-ZH.md

+104-5
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,108 @@ module.exports = {
136136

137137
```
138138

139-
#### FAQ:
140-
使用配置工厂自定义配置项,操作方式如下例
139+
### 常见配置问题
140+
141+
#### 如何新增 rule ?
142+
143+
```js
144+
module.exports = (app, defaultConfig, dev, target) => {
145+
// 获取配置工厂
146+
const factory = app.webpackFactory;
147+
148+
factory.addRule({
149+
test: /.ts/,
150+
exclude: /node_modules/,
151+
use: 'ts-loader',
152+
});
153+
154+
// 在上述变更后重新生产配置
155+
return factory.getConfig();
156+
};
157+
```
158+
159+
#### 如何在已有 rule 上修改?
160+
161+
```js
162+
module.exports = (app, defaultConfig, dev, target) => {
163+
// 获取配置工厂
164+
const factory = app.webpackFactory;
165+
166+
const rule = factory.getRule(/.ts/);
167+
// 或者
168+
// const rule = factory.getRule('.ts');
169+
// const rule = factory.getRule((r) => {
170+
// return r.test.test('.ts');
171+
// });
172+
173+
rule.use = {
174+
loader: 'ts-loader',
175+
options: {
176+
// some options
177+
}
178+
}
179+
180+
// 在上述变更后重新生产配置
181+
return factory.getConfig();
182+
};
183+
```
184+
185+
#### 如何新增 Plugin ?
186+
187+
```js
188+
module.exports = (app, defaultConfig, dev, target) => {
189+
// 获取配置工厂
190+
const factory = app.webpackFactory;
191+
const webpack = factory.webpack;
192+
factory.addPlugin(webpack.DefinePlugin, {
193+
__FOO__: 'bar',
194+
});
195+
196+
// 在上述变更后重新生产配置
197+
return factory.getConfig();
198+
};
199+
```
200+
201+
#### 如何修改已有Plugin配置 ?
202+
203+
```js
204+
module.exports = (app, defaultConfig, dev, target) => {
205+
// 获取配置工厂
206+
const factory = app.webpackFactory;
207+
const plugin = factory.getPlugin('DefinePlugin');
208+
plugin.options = {
209+
__DEV__: false,
210+
}
211+
212+
// 在上述变更后重新生产配置
213+
return factory.getConfig();
214+
};
215+
```
216+
内置所有Plugin和获取方式:
217+
218+
| Plugin | alias |
219+
|:--|:--|
220+
|DefinePlugin| 'DefinePlugin' |
221+
|UglifyJsPlugin| 'UglifyJsPlugin' |
222+
|NamedModulesPlugin| 'NamedModulesPlugin' |
223+
|HotModuleReplacementPlugin| 'HotModuleReplacementPlugin' |
224+
225+
默认仅获取匹配的 **一项**,复杂场景需自行遍历查询
226+
227+
`getPlugin` 返回 PluginConfig 对象:
228+
229+
```
230+
{
231+
class: DefinePlugin, // 构造函数
232+
options: {} // 构造参数
233+
instance: new DefinePlugin({}) // instance 优先,配置后 class 和 options自动失效
234+
}
235+
```
236+
237+
#### 其他使用方式
238+
239+
使用配置工厂自定义配置项:
240+
141241
```js
142242

143243
module.exports = (app, defaultConfig, dev, target) => {
@@ -195,15 +295,15 @@ module.exports = (app, defaultConfig, dev, target) => {
195295
exclude: /node_modules/,
196296
use: {
197297
loader:
198-
app.webpackFactory.useLoader('babel-loader')/** 如有已定义的loader,则使用自定义loader **/ || 'babel-loader',
298+
factory.useLoader('babel-loader')/** 如有已定义的loader,则使用自定义loader **/ || 'babel-loader',
199299
options: {
200300
babelrc: false,
201301
presets: ['preset-typescript'],
202302
},
203303
},
204304
}
205305
// 定义loader的方式
206-
app.webpackFactory.defineLoader({
306+
factory.defineLoader({
207307
'babel-loader',
208308
require.resolve('babel-loader')
209309
})
@@ -222,7 +322,6 @@ module.exports = (app, defaultConfig, dev, target) => {
222322

223323
};
224324

225-
226325
```
227326

228327
#### 数据结构:

packages/beidou-webpack/lib/factory/plugin.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ const is = require('is');
55
class Plugin {
66
constructor(...args) {
77
if (is.function(args[0])) {
8-
this.class = args[0];
8+
[this.class] = args;
99
this.alias = args[0].name;
1010
} else if (is.object(args[0])) {
11-
this.object = args[0];
11+
[this.object] = args;
1212
this.alias = args[0].constructor.name;
1313
} else {
1414
throw new Error(
1515
'Class Plugin constructor error ! '
1616
);
1717
}
1818
if (args[1]) {
19-
this.options = args[1];
19+
[, this.options] = args;
2020
}
2121
if (args[2]) {
22-
this.alias = args[2];
22+
[, , this.alias] = args;
2323
}
2424
}
2525

packages/beidou-webpack/lib/factory/webpack.js

+37-31
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,18 @@ class WebpackFactory extends Factory {
2828
*/
2929
env(env) {
3030
if (!env) {
31-
throw new Error(
32-
'Env param is required!'
33-
);
31+
throw new Error('Env param is required!');
3432
}
3533
const factories = Object.getPrototypeOf(this).__envFactories;
3634
if (factories[env]) {
3735
return factories[env];
3836
} else {
39-
const factory = new WebpackFactory(this.__webpackConfig, this.__plugins, this.__rules);
37+
const factory = new WebpackFactory(
38+
Object.assign({}, this.__webpackConfig),
39+
Object.assign({}, this.__plugins),
40+
[].concat(this.__rules)
41+
);
42+
factory.env = env;
4043
Object.getPrototypeOf(this).__envFactories[env] = factory;
4144
return factory;
4245
}
@@ -90,7 +93,6 @@ class WebpackFactory extends Factory {
9093
return Object.assign({}, this.__webpackConfig);
9194
}
9295

93-
9496
set(key, config) {
9597
this.__webpackConfig[key] = config;
9698
return this;
@@ -131,9 +133,7 @@ class WebpackFactory extends Factory {
131133
this.__plugins[plugin.alias] = plugin;
132134
return this;
133135
} else {
134-
throw new Error(
135-
`${args[0]} the plugin alias not exsit! `
136-
);
136+
throw new Error(`${args[0]} the plugin alias not exsit! `);
137137
}
138138
}
139139
if (args.length === 1 && args[0].constructor === Plugin) {
@@ -151,18 +151,21 @@ class WebpackFactory extends Factory {
151151
if (is.string(params)) {
152152
return this.__plugins[params];
153153
} else if (is.function(params)) {
154-
return params(Object.values(this.__plugins));
154+
for (const p of Object.values(this.__plugins)) {
155+
if (params(p)) {
156+
return p;
157+
}
158+
}
159+
return null;
155160
} else {
156-
throw new Error(
157-
'get plugin param type exception!'
158-
);
161+
throw new Error('get plugin param type exception!');
159162
}
160163
}
161164

162165
setPlugin(...args) {
163166
let pluginObj = {};
164167
if (args.length === 1 && args[0].constructor === Plugin) {
165-
pluginObj = args[0];
168+
[pluginObj] = args;
166169
} else {
167170
pluginObj = new Plugin(...args);
168171
}
@@ -183,9 +186,7 @@ class WebpackFactory extends Factory {
183186
} else if (is.function(filter)) {
184187
return filter(Object.values(definePlugins));
185188
} else {
186-
throw new Error(
187-
'use plugin param type exception!'
188-
);
189+
throw new Error('use plugin param type exception!');
189190
}
190191
}
191192

@@ -197,17 +198,14 @@ class WebpackFactory extends Factory {
197198
this.__plugins = {};
198199
}
199200

200-
201201
addRule(...args) {
202202
if (args.length === 1 && !is.object(args[0])) {
203203
const alias = args[0];
204204
if (this.useRule(alias)) {
205205
this.__rules.push(this.useRule(alias));
206206
return this;
207207
} else {
208-
throw new Error(
209-
`${args[0]} the rule alias not exsit! `
210-
);
208+
throw new Error(`${args[0]} the rule alias not exsit! `);
211209
}
212210
}
213211

@@ -223,28 +221,36 @@ class WebpackFactory extends Factory {
223221

224222
getRule(params) {
225223
if (is.string(params)) {
226-
return this.__rules.find(v => v.options.test.test(params) === true);
224+
return this.__rules.find(
225+
v => v.alias === params || v.options.test.test(params) === true
226+
);
227227
} else if (is.function(params)) {
228-
return params(this.__rules);
228+
for (const rule of this.__rules) {
229+
if (params(rule)) {
230+
return rule;
231+
}
232+
}
233+
return null;
229234
} else if (is.regexp(params)) {
230-
return this.__rules.find(v => v.options.test.toString() === params.toString());
231-
} else {
232-
throw new Error(
233-
'get rule param type exception!'
235+
return this.__rules.find(
236+
v => v.options.test.toString() === params.toString()
234237
);
238+
} else {
239+
throw new Error('get rule param type exception!');
235240
}
236241
}
237242

238-
239243
setRule(...args) {
240244
let ruleObj = {};
241245
if (args.length === 1 && args[0].constructor === Rule) {
242-
ruleObj = args[0];
246+
[ruleObj] = args;
243247
} else {
244248
ruleObj = new Rule(...args);
245249
}
246250

247-
let exsitRule = this.__rules.find(v => v.alias.toString() === ruleObj.alias.toString());
251+
let exsitRule = this.__rules.find(
252+
v => v.alias.toString() === ruleObj.alias.toString()
253+
);
248254
if (exsitRule) {
249255
exsitRule = ruleObj;
250256
} else {
@@ -290,9 +296,9 @@ class WebpackFactory extends Factory {
290296
this.__rules = [];
291297
}
292298

293-
294299
defineLoader(name, resolve) {
295-
Object.getPrototypeOf(this).__defineloaders[name] = resolve || require.resolve(name);
300+
Object.getPrototypeOf(this).__defineloaders[name] =
301+
resolve || require.resolve(name);
296302
return this;
297303
}
298304

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const Plugin = require('../../../lib/factory/plugin');
5+
describe('test/lib/factory/plugin.test.js', () => {
6+
it('init plugin error', () => {
7+
assert.throws(
8+
function () {
9+
new Plugin()
10+
},
11+
Error
12+
);
13+
})
14+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const Rule = require('../../../lib/factory/rule');
5+
describe('test/lib/factory/rule.test.js', () => {
6+
it('init rule error', () => {
7+
assert.throws(
8+
function () {
9+
new Rule()
10+
},
11+
Error
12+
);
13+
})
14+
15+
it('init rule error', () => {
16+
const ruleObj = new Rule({
17+
test:'js'
18+
})
19+
assert(ruleObj,'init rule error');
20+
assert(ruleObj.init().test === 'js','get rule options error')
21+
})
22+
})

0 commit comments

Comments
 (0)