Skip to content

Commit ee6391b

Browse files
committed
feat: support webpack config optimize
1 parent 6d2c700 commit ee6391b

File tree

15 files changed

+535
-15
lines changed

15 files changed

+535
-15
lines changed

packages/beidou-view-rax/config/webpack.config.js

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const RaxWebpackPlugin = require('rax-webpack-plugin');
66

77
module.exports = (app, defaultConfig, dev) => {
88
const { universal } = app.config.isomorphic;
9-
109
const module = {
1110
rules: [
1211
{

packages/beidou-webpack/agent.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ module.exports = (agent) => {
1515
const config = agent.config.webpack;
1616

1717
debug('create webpack server with config: %O', config);
18-
const webpackConfig = helper.getWebpackConfig(agent, config);
19-
18+
const factory = helper.getWebpackConfig(agent, config);
19+
const webpackConfig = factory.getConf();
2020
debug('Webpack config: %O', webpackConfig);
21-
2221
// const webpackServer = http.createServer(agent.callback());
2322

2423
const port = webpackConfig.devServer.port || 0;
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
'use strict';
22

3-
const webpack = require('webpack');
43
const helper = require('../utils');
54

65
module.exports = (app, target = 'browser') => {
76
helper.injectPlugin(app);
87
const config = app.config.webpack;
9-
const webpackConfig = helper.getWebpackConfig(app, config, target);
10-
11-
const compiler = webpack(webpackConfig);
8+
const factory = helper.getWebpackConfig(app, config, target);
9+
const compiler = factory.webpack();
1210
return compiler;
1311
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
'use strict';
2+
3+
const is = require('is');
4+
const webpack = require('webpack');
5+
6+
class Factory {
7+
constructor() {
8+
this._webpackConf = {};
9+
this.webpackFn = webpack;
10+
}
11+
12+
setWebpack(fn) {
13+
this.webpackFn = fn;
14+
}
15+
16+
getWebPack() {
17+
return this.webpackFn;
18+
}
19+
}
20+
21+
class ConfFactory extends Factory {
22+
constructor(env) {
23+
super();
24+
if (env) {
25+
this._env = env;
26+
}
27+
}
28+
29+
init(options, appDev) {
30+
Object.getPrototypeOf(this)._webpackConf = options || {};
31+
Object.getPrototypeOf(this).__sys_env = appDev;
32+
}
33+
34+
webpack() {
35+
return this.webpackFn(this.getConf());
36+
}
37+
38+
append(options) {
39+
if (this._env && this.__sys_env !== this._env) return this;
40+
const config = Object.assign(this.getConf(), options);
41+
this.reset(config);
42+
return this;
43+
}
44+
45+
46+
setEnv(env) {
47+
this._env = env;
48+
return this;
49+
}
50+
51+
env(env) {
52+
return new ConfFactory(env || this._env);
53+
}
54+
55+
resetEnv() {
56+
delete this._env;
57+
return this;
58+
}
59+
60+
getEnv() {
61+
return this._env;
62+
}
63+
64+
getConf() {
65+
return Object.getPrototypeOf(this)._webpackConf;
66+
}
67+
68+
69+
set(key, config) {
70+
if (!this._env || this.__sys_env === this._env) { Object.getPrototypeOf(this)._webpackConf[key] = config; }
71+
return this;
72+
}
73+
74+
reset(config) {
75+
if (!this._env || this.__sys_env === this._env) { Object.getPrototypeOf(this)._webpackConf = config; }
76+
return this;
77+
}
78+
79+
get(key, filter) {
80+
const keyData = this.getConf()[key];
81+
if (!keyData && filter) {
82+
throw new Error(
83+
`webpack don't exist the key , ${key} value is undefined!`
84+
);
85+
}
86+
if (!filter) {
87+
return keyData;
88+
}
89+
if (is.function(filter)) {
90+
return filter(keyData);
91+
}
92+
if (is.array(keyData)) {
93+
for (const v of keyData) {
94+
if (is.object(v)) {
95+
if (v.constructor.name === filter) return v;
96+
} else if (v === filter) return v;
97+
}
98+
} else if (is.string(keyData)) {
99+
if (is.regexp(filter)) {
100+
if (filter.test(keyData) === true) {
101+
return keyData;
102+
} else {
103+
return null;
104+
}
105+
}
106+
}
107+
}
108+
109+
getPlugin(filter) {
110+
const { plugins } = this.getConf();
111+
if (is.undefined(plugins)) {
112+
throw new Error(
113+
'webpack plugins don`t exist'
114+
);
115+
}
116+
if (!is.array(plugins)) {
117+
throw new Error(
118+
'webpack plugins is wrong , please check'
119+
);
120+
}
121+
if (is.function(filter)) {
122+
return filter(plugins);
123+
} else if (is.string(filter)) {
124+
for (const plugin of plugins) {
125+
if (plugin.constructor.name === filter) {
126+
return plugin;
127+
}
128+
}
129+
}
130+
return null;
131+
}
132+
133+
setPlugin(filter, config) {
134+
if (this._env && this.__sys_env !== this._env) return this;
135+
let { plugins } = this.getConf();
136+
if (is.undefined(plugins)) {
137+
throw new Error(
138+
'webpack plugins don`t exist'
139+
);
140+
}
141+
if (!is.array(plugins)) {
142+
throw new Error(
143+
'webpack plugins is wrong , please check'
144+
);
145+
}
146+
if (is.function(filter)) {
147+
filter(plugins);
148+
} else if (is.string(filter)) {
149+
plugins = plugins.map((val) => {
150+
if (val.constructor.name === filter) {
151+
return config;
152+
} else {
153+
return val;
154+
}
155+
});
156+
this.set('plugins', plugins);
157+
}
158+
159+
return this;
160+
}
161+
162+
addPlugin(plugin) {
163+
if (this._env && this.__sys_env !== this._env) return this;
164+
let { plugins } = this.getConf();
165+
if (!plugins || !is.array(plugins)) {
166+
plugins = [];
167+
}
168+
if (is.array(plugin)) {
169+
plugins = plugins.concat(plugin);
170+
} else {
171+
plugins.push(plugin);
172+
}
173+
this.set('plugins', plugins);
174+
return this;
175+
}
176+
177+
getRule(filter) {
178+
const { mod } = this.getConf();
179+
if (!mod) {
180+
throw new Error(
181+
'webpack module don`t exist'
182+
);
183+
}
184+
const { rules } = mod;
185+
if (!is.array(rules)) {
186+
return null;
187+
}
188+
if (is.function(filter)) {
189+
return filter(rules);
190+
} else if (is.regexp(filter)) {
191+
for (const row of rules) {
192+
if (filter.test(row.test.toString()) === true) {
193+
return row;
194+
}
195+
}
196+
} else if (is.string(filter)) {
197+
for (const row of rules) {
198+
if (row.test(filter) === true) {
199+
return row;
200+
}
201+
}
202+
}
203+
return null;
204+
}
205+
206+
addRule(rule) {
207+
if (this._env && this.__sys_env !== this._env) return this;
208+
let { module: mod } = this.getConf();
209+
if (!mod) {
210+
mod = { rules: [] };
211+
}
212+
if (!is.array(mod.rules)) {
213+
mod.rules = [];
214+
}
215+
if (is.array(rule)) {
216+
mod.rules = mod.rules.concat(rule);
217+
} else {
218+
mod.rules.push(rule);
219+
}
220+
this.set('module', mod);
221+
return this;
222+
}
223+
224+
getLoader(filter) {
225+
const { mod } = this.getConf();
226+
if (!mod) {
227+
throw new Error(
228+
'webpack module don`t exist'
229+
);
230+
}
231+
const { rules } = mod;
232+
if (!is.array(rules)) {
233+
return null;
234+
}
235+
if (is.regexp(filter)) {
236+
for (const row of rules) {
237+
if (row.use && row.user.loader) {
238+
if (filter.test(row.user.loader) === true) {
239+
return row.user.loader;
240+
}
241+
}
242+
}
243+
} else if (is.string(filter)) {
244+
for (const row of rules) {
245+
if (row.use && row.user.loader) {
246+
if (filter === row.user.loader) {
247+
return row.user.loader;
248+
}
249+
}
250+
}
251+
}
252+
return null;
253+
}
254+
}
255+
256+
module.exports = ConfFactory;

packages/beidou-webpack/lib/utils/index.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const _ = require('lodash');
1212
const debug = require('debug')('beidou:webpack');
1313
const IsomorphicPlugin = require('../plugin/isomorphic');
1414
const entryLoader = require('../loader/entry-loader');
15+
const WPFactory = require('../factory/Webpack');
16+
const is = require('is');
1517

1618
const symbol = Symbol.for('webpackServer');
1719

@@ -81,7 +83,7 @@ const getWebpackConfig = (app, options = {}, target = 'browser') => {
8183
const loadFile = app.loader.loadFile.bind(app.loader);
8284
const isDev = app.config.env !== 'prod';
8385
let webpackConfig = null;
84-
86+
app.webpackFactory = new WPFactory(app.config.env);
8587
const defaultConfigPath = path.join(
8688
__dirname,
8789
`../../config/webpack/webpack.${target}.js`
@@ -103,20 +105,23 @@ const getWebpackConfig = (app, options = {}, target = 'browser') => {
103105
debug('entry auto load as below:\n%o', entry);
104106

105107
webpackConfig = loadFile(defaultConfigPath, app, entry, isDev);
106-
108+
app.webpackFactory.init(webpackConfig, app.config.env);
107109
const customConfigPath = getCustomWebpackCfgPath(app);
108110
// custom config exists
109111
if (customConfigPath) {
110112
debug('Custom config found at %s', customConfigPath);
111-
webpackConfig = loadFile(
113+
const loadData = loadFile(
112114
customConfigPath,
113115
app,
114116
webpackConfig,
115117
isDev,
116118
target
117119
);
120+
if (loadData && is.object(loadData)) {
121+
app.webpackFactory.reset(loadData);
122+
}
118123
}
119-
124+
webpackConfig = app.webpackFactory.getConf();
120125
// make sure devServer is provided
121126
if (!webpackConfig.devServer) {
122127
webpackConfig.devServer = {
@@ -142,8 +147,7 @@ const getWebpackConfig = (app, options = {}, target = 'browser') => {
142147
if (!devServer.publicPath) {
143148
devServer.publicPath = webpackConfig.output.publicPath || '/build';
144149
}
145-
146-
return webpackConfig;
150+
return app.webpackFactory;
147151
};
148152

149153
const injectPlugin = (app) => {

packages/beidou-webpack/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"style-loader": "^0.19.0",
5050
"url-loader": "^0.6.2",
5151
"webpack": "^3.10.0",
52-
"webpack-dev-server": "^2.10.1"
52+
"webpack-dev-server": "^2.10.1",
53+
"is": "^3.2.1"
5354
},
5455
"devDependencies": {
5556
"chai": "^4.0.2",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import classNames from 'classnames/bind';
3+
import style from './index.scss';
4+
5+
const cx = classNames.bind(style);
6+
7+
export default class Index extends React.Component {
8+
constructor() {
9+
super();
10+
this.state = {};
11+
}
12+
13+
componentWillMount() {
14+
this.setState({
15+
desc: 'css modules',
16+
});
17+
}
18+
19+
render() {
20+
return (
21+
<div className={cx('page')}>
22+
<h3>
23+
This is example page, back to <a href="/">index page</a>
24+
</h3>
25+
<p>{this.state.desc}</p>
26+
</div>
27+
);
28+
}
29+
}

0 commit comments

Comments
 (0)