Skip to content

Commit 6eac931

Browse files
authored
Merge pull request #10 from dazjean/custom-webpack-configuration
feat: suport custom configure webpack
2 parents 5e3f58d + 94eaf9f commit 6eac931

File tree

21 files changed

+151
-421
lines changed

21 files changed

+151
-421
lines changed

doc/react/webpackconfig.md

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,66 @@
11

22
# webpack
3+
34
srejs基于webpack@4.0+,Bable@7.0+进行项目编译,默认集成配置项如下
5+
46
## loader
7+
58
- babel-loader
69
- less-loader
710
- css-loader
811
- sass-loader
912
- postcss-loader
1013
- url-loader
1114

12-
## alias
15+
## alias默认别名
1316

1417
```js
1518
alias: {
19+
@: rootDir,
1620
components: rootDir + '/components',
1721
images: rootDir + '/images',
18-
mock: rootDir + '/mock',
19-
skin: rootDir + '/skin',
20-
utils: rootDir + '/utils',
21-
config: rootDir + '/config'
2222
}
2323
```
2424

2525
## DefinePlugin
26+
2627
开发者在js中通过`process.env.NODE_ENV`可以进行环境的区分。
27-
```
28+
29+
```shell
2830
'process.env': NODE_ENV: JSON.stringify(dev ? 'development' : 'production')
2931
```
3032

31-
## devServer
32-
- `port:8080`
33-
- `hot:true`
34-
- `contentBase: ${rootDir}`
33+
# 覆盖或者新增webpack配置
34+
35+
srejs支持自定义webpack配置,在项目根目录下创建webpack.config.js。文件支持导出对象或者函数。
36+
37+
- 函数 【推荐】
38+
函数接受两个参数,第一个为框架内置webpack配置对象;第二个参数可区分ssr和csr模式。
3539

36-
# 自定义webpack
37-
srejs支持自定义webpack中的指定配置项
40+
```js
41+
module.exports = (configureWebpack, type) => {
42+
if (type == 'ssr') {
43+
//服务端渲染配置
44+
} else if (type === 'csr') {
45+
//客户端构建配置
46+
// configureWebpack.module.rules[0].exclude = /\/node_module\/!(antd.*)/;
47+
}
3848

39-
## 支持的配置项
49+
return configureWebpack;
50+
};
4051
```
41-
// webpack.config.js
52+
53+
- 对象
54+
对象配置属性将通过webpack-merge和框架内置属性进行合并。此方法适用于同时设置客户端和服务端渲染模式相同的配置。
55+
56+
```js
4257
module.exports = {
43-
loader: {
44-
js: [],
45-
jsx: [],
46-
css: [],
47-
scss: [],
48-
less: [],
49-
img: []
50-
}, // 新增的loader框架默认loader配置之后执行
51-
externals: {
52-
},
53-
extensions: [],
54-
alias: {
55-
images: path.join(process.cwd() + '/src/images')
56-
},
57-
plugins: []
58-
};
59-
```
58+
// module
59+
module:{
60+
rules:[
61+
// other loader
62+
]
63+
}
64+
}
65+
66+
```

packages/app/webpack.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = (configureWebpack, type) => {
2+
if (type == 'ssr') {
3+
//服务端渲染配置
4+
} else if (type === 'csr') {
5+
//客户端构建配置
6+
// configureWebpack.module.rules[0].exclude = /\/node_module\/!(antd.*)/;
7+
}
8+
9+
return configureWebpack;
10+
};

packages/common/src/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const cacheDir = join(cwd + '/.ssr/cache');
1212
export const outPutDir = join(cwd + '/.ssr/output');
1313
export const serverDir = join(cwd + '/dist/server');
1414
export const clientDir = join(cwd + '/dist/client');
15-
export const webpackConfigPath = join(cwd + './webpack.config.js');
15+
export const webpackConfigPath = join(cwd + '/webpack.config.js');
1616
export const SSRKEY = Symbol('SSR');
1717

1818
const newOptionsPath = path.resolve(cwd, './config/ssr.config.js');

packages/react-webpack/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"terser-webpack-plugin": "^4.2.3",
6969
"url-loader": "^4.1.1",
7070
"webpack": "^4.35.0",
71+
"webpack-merge":"5.8.0",
7172
"webpack-bundle-analyzer": "^4.4.2",
7273
"webpack-dev-server": "^3.7.2",
7374
"webpack-node-externals": "^3.0.0"

packages/react-webpack/src/react/base.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { cwd, clientDir, getCoreConfig, getOptions, isDev } from '@srejs/common'
77
import { loaderRules } from './loader';
88
import { getPlugin } from './plugin';
99
import { getEntry, initEntry } from './entry';
10-
import combine from './combine';
1110

1211
const { prefixCDN } = getCoreConfig();
1312
const rootDir = getOptions('rootDir');
@@ -98,5 +97,5 @@ export function getBaseconfig(page, isServer = false, hotReload = false) {
9897
}
9998
}
10099
};
101-
return combine(config);
100+
return config;
102101
}
Lines changed: 15 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,23 @@
11
import fs from 'fs';
2+
import merger from 'webpack-merge';
23
import { webpackConfigPath } from '@srejs/common';
34

4-
const loaderDefaultArr = [
5-
'.js',
6-
'.jsx',
7-
'.ts',
8-
'.tsx',
9-
'.css',
10-
'.scss',
11-
'.less',
12-
'.png',
13-
'.jpg',
14-
'.jpeg',
15-
'.gif',
16-
'.svg'
17-
];
18-
function isSameLoader(loader1, loader2) {
19-
const loader1Name = typeof loader1 === 'string' ? loader1 : loader1.loader;
20-
const loader2Name = typeof loader2 === 'string' ? loader2 : loader2.loader;
21-
return loader1Name === loader2Name;
22-
}
23-
function mergeLoader(before, item) {
24-
if (item && item.length) {
25-
//如果有则覆盖,没有则添加 双指针:一个beforeIndex指向原有默认配置,一个itemIndex指向用户配置
26-
//1.loader相同 beforeIndex++ && itemIndex++,覆盖
27-
//2.loader不相同 beforeIndex++,添加
28-
const beforeLength = before.use.length,
29-
itemLength = item.length;
30-
let beforeIndex = 0,
31-
itemIndex = 0;
32-
while (beforeIndex < beforeLength && itemIndex < itemLength) {
33-
if (isSameLoader(before.use[beforeIndex], item[itemIndex])) {
34-
before.use[beforeIndex] = item[itemIndex];
35-
beforeIndex++;
36-
itemIndex++;
37-
} else {
38-
beforeIndex++;
39-
}
40-
}
41-
if (itemIndex < itemLength) {
42-
//用户配置
43-
before.use.push(...item.slice(itemIndex));
44-
}
45-
}
46-
}
47-
//loader单独处理
48-
function loaderConfig(userConfigLoader, config) {
49-
//添加loader
50-
let defaultLoader = config.module.rules;
51-
userConfigLoader &&
52-
Object.entries(userConfigLoader).map(([key, item]) => {
53-
switch (key) {
54-
case 'js':
55-
mergeLoader(defaultLoader[0], item);
56-
break;
57-
case 'jsx':
58-
mergeLoader(defaultLoader[1], item);
59-
break;
60-
case 'ts':
61-
mergeLoader(defaultLoader[2], item);
62-
break;
63-
case 'tsx':
64-
mergeLoader(defaultLoader[3], item);
65-
break;
66-
case 'css':
67-
mergeLoader(defaultLoader[4], item);
68-
break;
69-
case 'scss':
70-
mergeLoader(defaultLoader[5], item);
71-
break;
72-
case 'less':
73-
mergeLoader(defaultLoader[6], item);
74-
break;
75-
case 'img':
76-
mergeLoader(defaultLoader[7], item);
77-
break;
78-
case 'other':
79-
//没有默认loader的文件添加
80-
item.length &&
81-
item.map((loader) => {
82-
!loaderDefaultArr.some((loaderDefault) =>
83-
loaderDefault.match(loader.test)
84-
) && defaultLoader.push(loader);
85-
});
86-
break;
87-
default:
88-
}
89-
});
90-
}
91-
module.exports = function (config) {
5+
module.exports = function (config, isServer) {
926
if (!fs.existsSync(webpackConfigPath)) {
937
return config;
948
}
9+
let customConfig = config;
9510
delete require.cache[require.resolve(webpackConfigPath)];
96-
const customConfig = require(webpackConfigPath);
97-
if (!customConfig) return config;
98-
Object.entries(customConfig).map(([key, val]) => {
99-
switch (key) {
100-
case 'loader':
101-
loaderConfig(val, config);
102-
break;
103-
case 'externals':
104-
//添加externals 合并
105-
config.externals = val
106-
? Object.assign(config.externals || {}, val)
107-
: config.externals;
108-
break;
109-
case 'extensions':
110-
//添加extensions 合并去重
111-
config.resolve.extensions =
112-
val && val.length
113-
? Array.from(new Set([...config.resolve.extensions, ...val]))
114-
: config.resolve.extensions;
115-
break;
116-
case 'alias':
117-
//添加alias 覆盖
118-
config.resolve.alias = val || config.resolve.alias;
119-
break;
120-
case 'plugins':
121-
//添加plugin 合并
122-
config.plugins = val ? config.plugins.concat(val) : config.plugins;
123-
break;
124-
default:
125-
//直接覆盖操作
126-
config[key] = val || config[key] || '';
127-
break;
128-
}
129-
});
130-
return config;
11+
const configureWebpack = require(webpackConfigPath);
12+
if (typeof configureWebpack === 'function') {
13+
// apply customConfig
14+
customConfig = Reflect.apply(configureWebpack, config, [config, isServer ? 'ssr' : 'csr']);
15+
}
16+
17+
if (typeof configureWebpack === 'object') {
18+
// webpack-merge
19+
customConfig = merger(config, configureWebpack);
20+
}
21+
22+
return customConfig;
13123
};
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { getBaseconfig } from './base';
2+
import combine from './combine';
23

34
export function getDevConfig(page, isServer, hotReload = false) {
45
let config = getBaseconfig(page, isServer, hotReload);
5-
return config;
6+
return combine(config, false);
67
}

packages/react-webpack/src/react/prod.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getBaseconfig } from './base';
22
import { getPlugin } from './plugin';
3+
import combine from './combine';
34

45
function getProconfig(page, isServer) {
56
let config = getBaseconfig(page);
@@ -9,7 +10,7 @@ function getProconfig(page, isServer) {
910
mode: 'production',
1011
plugins: [...getPlugin(config.entry, isServer)]
1112
});
12-
return buildConfig;
13+
return combine(buildConfig, false);
1314
}
1415

1516
module.exports = {

packages/react-webpack/yarn.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7002,6 +7002,14 @@ webpack-log@^2.0.0:
70027002
ansi-colors "^3.0.0"
70037003
uuid "^3.3.2"
70047004

7005+
webpack-merge@5.8.0:
7006+
version "5.8.0"
7007+
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
7008+
integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
7009+
dependencies:
7010+
clone-deep "^4.0.1"
7011+
wildcard "^2.0.0"
7012+
70057013
webpack-node-externals@^3.0.0:
70067014
version "3.0.0"
70077015
resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz#1a3407c158d547a9feb4229a9e3385b7b60c9917"
@@ -7081,6 +7089,11 @@ which@^1.2.9:
70817089
dependencies:
70827090
isexe "^2.0.0"
70837091

7092+
wildcard@^2.0.0:
7093+
version "2.0.0"
7094+
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
7095+
integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
7096+
70847097
worker-farm@^1.7.0:
70857098
version "1.7.0"
70867099
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"

packages/vue-webpack/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"vue-style-loader": "^4.1.3",
7070
"vue-template-compiler": "^2.6.14",
7171
"webpack": "^4.35.0",
72+
"webpack-merge":"5.8.0",
7273
"webpack-bundle-analyzer": "^4.4.2",
7374
"webpack-dev-server": "^3.7.2",
7475
"webpack-node-externals": "^3.0.0"

0 commit comments

Comments
 (0)