jjb-cmd 2.0.9 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +2 -1
- package/src/new/cmd.init/index.js +1 -102
- package/src/new/cmd.install/config.js +1 -47
- package/src/new/cmd.install/index.js +1 -262
- package/src/new/cmd.install/tools.js +1 -230
- package/src/new/cmd.push/index.js +1 -54
- package/src/new/cmd.reglist/index.js +1 -22
- package/src/new/cmd.rm-rf/index.js +1 -58
- package/src/new/cmd.version/index.js +1 -34
- package/src/old/cli.init.js +1 -26
- package/src/old/cli.install/config.js +1 -206
- package/src/old/cli.install/index.js +1 -340
- package/src/old/cli.install/tools.js +1 -230
- package/src/old/cli.merge.js +1 -80
- package/src/old/cli.pull.js +1 -94
- package/src/old/cli.pull2.js +1 -377
- package/src/old/cli.rm-rf.js +1 -88
- package/src/old/progress-bar.js +1 -23
- package/src/old/util.js +1 -149
- package/.idea/jjb-cmd.iml +0 -12
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/src/old/cli.dva.register.saas.txt +0 -40
- package/src/old/cli.dva.register.spa.txt +0 -22
- package/src/old/cli.dva.router.saas.txt +0 -210
- package/src/old/cli.dva.router.spa.txt +0 -119
- package/src/old/cli.init/jjb.config.json +0 -40
- package/src/old/cli.init/jjb.script/build.js +0 -11
- package/src/old/cli.init/jjb.script/config.js +0 -217
- package/src/old/cli.init/jjb.script/proxy.js +0 -19
- package/src/old/cli.init/jjb.script/server.js +0 -29
- package/src/old/cli.init/jjb.script/utils.js +0 -13
- package/src/old/cli.init/package.json +0 -65
- package/src/old/cli.init/public/index.html +0 -21
- package/src/old/cli.init/src/enumerate/menu/index.js +0 -1
- package/src/old/cli.init/src/enumerate/namespace/index.js +0 -3
- package/src/old/cli.init/src/index.js +0 -24
- package/src/old/cli.init/src/models/main/index.js +0 -31
- package/src/old/cli.init/src/pages/index.js +0 -9
- package/src/old/cli.init/webstorm.config.js +0 -18
package/.idea/jjb-cmd.iml
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<module type="WEB_MODULE" version="4">
|
3
|
-
<component name="NewModuleRootManager">
|
4
|
-
<content url="file://$MODULE_DIR$">
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
8
|
-
</content>
|
9
|
-
<orderEntry type="inheritedJdk" />
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
11
|
-
</component>
|
12
|
-
</module>
|
package/.idea/modules.xml
DELETED
package/.idea/vcs.xml
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @author XiWell
|
3
|
-
* @version 2.0.1
|
4
|
-
* @description 基于QianKun框架的APP注册文件,请勿修改!
|
5
|
-
*/
|
6
|
-
|
7
|
-
import 'moment/locale/zh-cn';
|
8
|
-
import dva from 'dva';
|
9
|
-
import { createBrowserHistory } from 'history';
|
10
|
-
import { unmountComponentAtNode } from 'react-dom';
|
11
|
-
|
12
|
-
/**
|
13
|
-
* @description 注册app
|
14
|
-
* @param selector {string}
|
15
|
-
* @returns {{unmount: Function, mount: Function, bootstrap: Function}}
|
16
|
-
*/
|
17
|
-
export const registerApplication = (selector = '#root') => {
|
18
|
-
try {
|
19
|
-
const app = dva({ history: createBrowserHistory() });
|
20
|
-
require('./models').automaticModels(app);
|
21
|
-
app.router(config => require('./router').AutomaticRouter(config));
|
22
|
-
|
23
|
-
const render = () => app.start(selector);
|
24
|
-
if (!window.__POWERED_BY_QIANKUN__) render();
|
25
|
-
|
26
|
-
return {
|
27
|
-
mount: () => render(),
|
28
|
-
unmount: props => {
|
29
|
-
const { container } = props;
|
30
|
-
const element = container
|
31
|
-
? container.querySelector(selector)
|
32
|
-
: document.querySelector(selector);
|
33
|
-
unmountComponentAtNode(element);
|
34
|
-
},
|
35
|
-
bootstrap: props => props
|
36
|
-
};
|
37
|
-
} catch (e) {
|
38
|
-
console.error('注册APP失败,原因:', e.message);
|
39
|
-
}
|
40
|
-
};
|
@@ -1,22 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @author XiWell
|
3
|
-
* @version 1.0.1
|
4
|
-
* @description 基于QianKun框架的APP注册文件,请勿修改!
|
5
|
-
*/
|
6
|
-
|
7
|
-
import dva from 'dva';
|
8
|
-
import ReactDOM from 'react-dom';
|
9
|
-
import { createBrowserHistory } from 'history';
|
10
|
-
import 'antd/dist/antd.less';
|
11
|
-
|
12
|
-
/**
|
13
|
-
* @description 注册app
|
14
|
-
* @param selector {string}
|
15
|
-
* @returns {{unmount: Function, mount: Function, bootstrap: Function}}
|
16
|
-
*/
|
17
|
-
export const registerApplication = (selector = '#app-root') => {
|
18
|
-
const app = dva({ history: createBrowserHistory() });
|
19
|
-
require('./models').automaticModels(app);
|
20
|
-
app.router(config => require('./router').AutomaticRouter(config));
|
21
|
-
app.start(selector);
|
22
|
-
};
|
@@ -1,210 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @author XiWell
|
3
|
-
* @version 2.0.1
|
4
|
-
* @description 此文件为dva/router自动化文件,无需配置路由,请勿修改!
|
5
|
-
*/
|
6
|
-
|
7
|
-
import React from 'react';
|
8
|
-
import { ConfigProvider } from 'antd';
|
9
|
-
import { BrowserRouter, Route, Switch } from 'dva/router';
|
10
|
-
|
11
|
-
/**
|
12
|
-
* @description 是否匹配页面
|
13
|
-
* @param name {string}
|
14
|
-
* @return {{stat: boolean, param: null}}
|
15
|
-
*/
|
16
|
-
function isParamPage (name) {
|
17
|
-
const result = {
|
18
|
-
stat: false,
|
19
|
-
param: null
|
20
|
-
};
|
21
|
-
if (/^_/.test(name)) {
|
22
|
-
const match = name.replace(/\.js$/, '').split(/_/).filter(item => !!item && item !== 'index');
|
23
|
-
result.stat = match.length !== 0;
|
24
|
-
result.param = match.join('_');
|
25
|
-
}
|
26
|
-
return result;
|
27
|
-
}
|
28
|
-
|
29
|
-
/**
|
30
|
-
* @description 首字母转小写
|
31
|
-
* @param value {string}
|
32
|
-
* @return {string}
|
33
|
-
*/
|
34
|
-
function toLowerCase (value) {
|
35
|
-
return `${value[ 0 ].toLowerCase()}${value.substring(1)}`;
|
36
|
-
}
|
37
|
-
|
38
|
-
/**
|
39
|
-
* @description 获取初始路由集合
|
40
|
-
* @return {{path: string, file: string}[]}
|
41
|
-
*/
|
42
|
-
function getRoutes () {
|
43
|
-
const routes = [];
|
44
|
-
const fileList = require.context('~/pages', true, /\.js$/).keys();
|
45
|
-
for (let i = 0; i < fileList.length; i++) {
|
46
|
-
const route = {};
|
47
|
-
const file = fileList[ i ];
|
48
|
-
const fileSplit = file.split(/\//);
|
49
|
-
const fileName = fileSplit[ fileSplit.length - 1 ];
|
50
|
-
const {
|
51
|
-
stat: fileState,
|
52
|
-
param: fileParam
|
53
|
-
} = isParamPage(fileName);
|
54
|
-
const filePathArray = fileSplit.slice(1, fileSplit.length - 1).map(item => {
|
55
|
-
const {
|
56
|
-
stat,
|
57
|
-
param
|
58
|
-
} = isParamPage(item);
|
59
|
-
return stat
|
60
|
-
? `:${param}`
|
61
|
-
: item;
|
62
|
-
});
|
63
|
-
if (fileState || fileName === 'index.js') {
|
64
|
-
if (filePathArray.length) {
|
65
|
-
const path = filePathArray.map(item => toLowerCase(item)).join('/');
|
66
|
-
route.path = (`/${path}${fileState
|
67
|
-
? `/:${fileParam}`
|
68
|
-
: ''}`);
|
69
|
-
} else {
|
70
|
-
route.path = `/${fileState
|
71
|
-
? `:${fileParam}`
|
72
|
-
: ''}`;
|
73
|
-
}
|
74
|
-
route.file = file;
|
75
|
-
routes.push(route);
|
76
|
-
}
|
77
|
-
}
|
78
|
-
return routes.reverse();
|
79
|
-
}
|
80
|
-
|
81
|
-
/**
|
82
|
-
* @typedef {object} TreeRoutes
|
83
|
-
* @property {string} path
|
84
|
-
* @property {string} file
|
85
|
-
* @property {TreeRoutes[]} children
|
86
|
-
*/
|
87
|
-
|
88
|
-
/**
|
89
|
-
* @description 优化tree
|
90
|
-
* @param tree {TreeRoutes[]}
|
91
|
-
* @return {TreeRoutes[]}
|
92
|
-
*/
|
93
|
-
function optimizationTree (tree = []) {
|
94
|
-
function deep (array = []) {
|
95
|
-
const inner = [];
|
96
|
-
for (let i = 0; i < array.length; i++) {
|
97
|
-
const item = array[ i ];
|
98
|
-
const newItem = {};
|
99
|
-
newItem.children = item.children.length
|
100
|
-
? deep(item.children)
|
101
|
-
: [];
|
102
|
-
newItem.path = item.path;
|
103
|
-
newItem.Component = require(`~/pages${item.file.replace(/^\./, '')}`).default;
|
104
|
-
inner.push(newItem);
|
105
|
-
}
|
106
|
-
return inner;
|
107
|
-
}
|
108
|
-
|
109
|
-
return deep(tree);
|
110
|
-
}
|
111
|
-
|
112
|
-
/**
|
113
|
-
* @description 将初始routes转换为tree结构
|
114
|
-
* @param routes {{path: string, file: string}[]}
|
115
|
-
* @return {TreeRoutes[]}
|
116
|
-
*/
|
117
|
-
function treeRoutes (routes = []) {
|
118
|
-
const dataSource = [];
|
119
|
-
const indexItem = routes.find(item => item.path === '/');
|
120
|
-
for (let i = 0; i < routes.length; i++) {
|
121
|
-
const route = routes[ i ];
|
122
|
-
if (route.path === '/') {
|
123
|
-
continue;
|
124
|
-
}
|
125
|
-
const pathArray = route.path.split('/').slice(1);
|
126
|
-
route.parentFile = pathArray.length === 1
|
127
|
-
? null
|
128
|
-
: routes[ i - 1 ].file;
|
129
|
-
dataSource.push(route);
|
130
|
-
}
|
131
|
-
if (indexItem) {
|
132
|
-
Object.assign(indexItem, { parentFile: null });
|
133
|
-
dataSource.push(indexItem);
|
134
|
-
}
|
135
|
-
let len;
|
136
|
-
for (let i = 0; len = dataSource.length, i < len; i++) {
|
137
|
-
const arrTemp = [];
|
138
|
-
for (let j = 0; j < dataSource.length; j++) {
|
139
|
-
if (dataSource[ i ].file === dataSource[ j ].parentFile) {
|
140
|
-
dataSource[ i ].children = arrTemp;
|
141
|
-
arrTemp.push(dataSource[ j ]);
|
142
|
-
} else {
|
143
|
-
dataSource[ i ].children = arrTemp;
|
144
|
-
}
|
145
|
-
}
|
146
|
-
}
|
147
|
-
const result = [];
|
148
|
-
for (let i = 0; i < dataSource.length; i++) {
|
149
|
-
if (dataSource[ i ].parentFile === null) {
|
150
|
-
result.push(dataSource[ i ]);
|
151
|
-
}
|
152
|
-
}
|
153
|
-
return optimizationTree(result);
|
154
|
-
}
|
155
|
-
|
156
|
-
function RenderRoute (routes = [], inProps = {}) {
|
157
|
-
return (
|
158
|
-
<Switch>
|
159
|
-
{routes.map(({
|
160
|
-
path,
|
161
|
-
children,
|
162
|
-
Component
|
163
|
-
}, index) => (
|
164
|
-
<Route
|
165
|
-
exact={path === '/'}
|
166
|
-
key={index}
|
167
|
-
path={path}
|
168
|
-
render={props => (
|
169
|
-
<Component {...props}>
|
170
|
-
{RenderRoute(children, inProps)}
|
171
|
-
</Component>
|
172
|
-
)}
|
173
|
-
/>
|
174
|
-
))}
|
175
|
-
</Switch>
|
176
|
-
);
|
177
|
-
}
|
178
|
-
|
179
|
-
/**
|
180
|
-
* @description 自动化路由组件
|
181
|
-
* @param app {object}
|
182
|
-
* @param history {history}
|
183
|
-
* @return {JSX.Element}
|
184
|
-
*/
|
185
|
-
export const AutomaticRouter = ({
|
186
|
-
app,
|
187
|
-
history
|
188
|
-
}) => {
|
189
|
-
return (
|
190
|
-
<ConfigProvider locale={require('antd/lib/locale/zh_CN').default}>
|
191
|
-
<BrowserRouter basename={(process.env.app || {}).basename || ''}>
|
192
|
-
<Switch>
|
193
|
-
{(process.env.app || {}).notRouter
|
194
|
-
? (
|
195
|
-
<Route
|
196
|
-
path="*"
|
197
|
-
component={require('~/pages').default}
|
198
|
-
/>
|
199
|
-
)
|
200
|
-
: (
|
201
|
-
RenderRoute(treeRoutes(getRoutes()), {
|
202
|
-
app,
|
203
|
-
history
|
204
|
-
})
|
205
|
-
)}
|
206
|
-
</Switch>
|
207
|
-
</BrowserRouter>
|
208
|
-
</ConfigProvider>
|
209
|
-
);
|
210
|
-
};
|
@@ -1,119 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @author XiWell
|
3
|
-
* @version 1.0.1
|
4
|
-
* @description 此文件为dva/router自动化文件,无需配置路由,请勿修改!
|
5
|
-
*/
|
6
|
-
|
7
|
-
import React from 'react';
|
8
|
-
import { ConfigProvider } from 'antd';
|
9
|
-
import { Route, Router, Switch } from 'dva/router';
|
10
|
-
|
11
|
-
/**
|
12
|
-
* @description react路由扫描器
|
13
|
-
* @param props {{app: object, history: any}}
|
14
|
-
*/
|
15
|
-
function ReactRouterScanner (props) {
|
16
|
-
const paths = require.context('~/pages', true, /\.(jsx|js)$/).keys().filter(item => !item.match(/components/));
|
17
|
-
const symbolByEntry = 'Entry_index.js';
|
18
|
-
const symbolByContainer = 'Container_index.js';
|
19
|
-
|
20
|
-
/**
|
21
|
-
* @description 路由处理
|
22
|
-
* @param path {string}
|
23
|
-
* @return string
|
24
|
-
*/
|
25
|
-
function routeHandle (path) {
|
26
|
-
return `/${path.replace(/\/index.js$/, '').split(/\//).map(a => {
|
27
|
-
a = a.replace(a[ 0 ], a[ 0 ].toLowerCase());
|
28
|
-
return a;
|
29
|
-
}).map(a => {
|
30
|
-
if (/^[a-zA-Z]+_[a-zA-Z]+$/.test(a)) {
|
31
|
-
return `:${a.split(/_/).join('')}`;
|
32
|
-
}
|
33
|
-
return a;
|
34
|
-
}).join('/')}`;
|
35
|
-
}
|
36
|
-
|
37
|
-
const routerMap = paths.map(path => {
|
38
|
-
const pure = path.replace(/^\.\//, '');
|
39
|
-
return {
|
40
|
-
path: pure === 'index.js'
|
41
|
-
? '/'
|
42
|
-
: pure === symbolByContainer
|
43
|
-
? '/container'
|
44
|
-
: path === symbolByEntry
|
45
|
-
? '/entry'
|
46
|
-
: routeHandle(pure),
|
47
|
-
suffix: 'index.js',
|
48
|
-
component: require(`~/pages/${pure}`).default,
|
49
|
-
componentName: pure.replace(/\//g, '_')
|
50
|
-
};
|
51
|
-
});
|
52
|
-
|
53
|
-
const Main = routerMap.find(item => item.componentName === 'index.js');
|
54
|
-
const Entry = routerMap.find(item => item.componentName === symbolByEntry);
|
55
|
-
const Container = routerMap.find(item => item.componentName === symbolByContainer);
|
56
|
-
const ChildrenRoute = routerMap.filter(item => item.componentName.match(new RegExp('Container_')) && item.path !== '/container');
|
57
|
-
const ContainerComponent = Container
|
58
|
-
? Container.component
|
59
|
-
: null;
|
60
|
-
return (
|
61
|
-
<Router history={props.history}>
|
62
|
-
<Switch location={history.location}>
|
63
|
-
{Main && (
|
64
|
-
<Route
|
65
|
-
exact
|
66
|
-
path={Main.path}
|
67
|
-
component={Main.component}
|
68
|
-
/>
|
69
|
-
)}
|
70
|
-
{Entry && (
|
71
|
-
<Route
|
72
|
-
exact
|
73
|
-
path={Entry.path}
|
74
|
-
component={Entry.component}
|
75
|
-
/>
|
76
|
-
)}
|
77
|
-
{Container && (
|
78
|
-
<Route
|
79
|
-
path={Container.path}
|
80
|
-
render={$props => (
|
81
|
-
<ContainerComponent {...$props}>
|
82
|
-
<Switch location={history.location}>
|
83
|
-
{ChildrenRoute.map((route, key) => (
|
84
|
-
<Route
|
85
|
-
exact
|
86
|
-
key={key}
|
87
|
-
path={route.path}
|
88
|
-
component={route.component}
|
89
|
-
/>
|
90
|
-
))}
|
91
|
-
</Switch>
|
92
|
-
</ContainerComponent>
|
93
|
-
)}
|
94
|
-
/>
|
95
|
-
)}
|
96
|
-
</Switch>
|
97
|
-
</Router>
|
98
|
-
);
|
99
|
-
}
|
100
|
-
|
101
|
-
/**
|
102
|
-
* @description 自动化路由组件
|
103
|
-
* @param app {object}
|
104
|
-
* @param history {history}
|
105
|
-
* @return {JSX.Element}
|
106
|
-
*/
|
107
|
-
export const AutomaticRouter = ({
|
108
|
-
app,
|
109
|
-
history
|
110
|
-
}) => {
|
111
|
-
return (
|
112
|
-
<ConfigProvider locale={require('antd/lib/locale/zh_CN').default}>
|
113
|
-
<ReactRouterScanner
|
114
|
-
app={app}
|
115
|
-
history={history}
|
116
|
-
/>
|
117
|
-
</ConfigProvider>
|
118
|
-
);
|
119
|
-
};
|
@@ -1,40 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"projectType": "micro-spa",
|
3
|
-
"installTarget": "node_modules",
|
4
|
-
"installResources": [
|
5
|
-
"jjb-dva-runtime",
|
6
|
-
"jjb-common-decorator"
|
7
|
-
],
|
8
|
-
"environment": {
|
9
|
-
"development": {
|
10
|
-
"API_HOSE": ""
|
11
|
-
},
|
12
|
-
"test": {
|
13
|
-
"API_HOSE": ""
|
14
|
-
},
|
15
|
-
"release": {
|
16
|
-
"API_HOSE": ""
|
17
|
-
},
|
18
|
-
"production": {
|
19
|
-
"API_HOSE": ""
|
20
|
-
}
|
21
|
-
},
|
22
|
-
"contextInject": {
|
23
|
-
"notRouter": true
|
24
|
-
},
|
25
|
-
"windowInject": {
|
26
|
-
"title": "JJB Micro App",
|
27
|
-
"jjbCommonLibUrl": ""
|
28
|
-
},
|
29
|
-
"server": {
|
30
|
-
"port": "8080",
|
31
|
-
"host": "127.0.0.1"
|
32
|
-
},
|
33
|
-
"framework": {
|
34
|
-
"antd": {
|
35
|
-
"link-color": "#021e43",
|
36
|
-
"primary-color": "#021e43",
|
37
|
-
"border-radius-base": "2px"
|
38
|
-
}
|
39
|
-
}
|
40
|
-
}
|
@@ -1,11 +0,0 @@
|
|
1
|
-
const { hasEnvironment } = require('./utils');
|
2
|
-
|
3
|
-
if (!hasEnvironment()) {
|
4
|
-
throw Error('jjb.script[build]: 启动build需要提供NODE_ENV变量,请确认你所运行的脚本是否正确?');
|
5
|
-
}
|
6
|
-
|
7
|
-
require('webpack')(require('./config')('production').webpack).run(err => {
|
8
|
-
if (!err) {
|
9
|
-
console.log('项目打包完成!');
|
10
|
-
}
|
11
|
-
});
|
@@ -1,217 +0,0 @@
|
|
1
|
-
// noinspection JSUnresolvedVariable
|
2
|
-
|
3
|
-
const path = require('path');
|
4
|
-
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
5
|
-
const TerserWebpackPlugin = require('terser-webpack-plugin');
|
6
|
-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
7
|
-
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
8
|
-
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
|
9
|
-
const { requireResolve } = require('./utils');
|
10
|
-
const webpack = require('webpack');
|
11
|
-
|
12
|
-
const config = require(requireResolve('jjb.config.json'));
|
13
|
-
const packageJSON = require(requireResolve('package.json'));
|
14
|
-
const server = (config.server || {});
|
15
|
-
const environment = (config.environment || {})[ process.env.NODE_ENV ];
|
16
|
-
const windowInject = Object.assign((config.windowInject || {}), environment);
|
17
|
-
const contextInject = (config.contextInject || {});
|
18
|
-
const contextData = {
|
19
|
-
...environment,
|
20
|
-
...contextInject
|
21
|
-
};
|
22
|
-
|
23
|
-
module.exports = mode => {
|
24
|
-
const isProduction = mode === 'production';
|
25
|
-
return {
|
26
|
-
server,
|
27
|
-
webpack: {
|
28
|
-
// 模式 ‘development’ | ‘production’
|
29
|
-
mode,
|
30
|
-
// 入口
|
31
|
-
entry: './src/index.js',
|
32
|
-
// 输出
|
33
|
-
output: {
|
34
|
-
libraryTarget: 'umd',
|
35
|
-
// 指定输出目录文件名
|
36
|
-
path: path.resolve(__dirname, '../dist'),
|
37
|
-
// 定义全局变量,暴露到‘window’对象中
|
38
|
-
library: packageJSON.name,
|
39
|
-
// 指定编译的‘js’存放目录文件名称
|
40
|
-
filename: 'static/js/[id].js',
|
41
|
-
// 输出公共路径
|
42
|
-
publicPath: '/'
|
43
|
-
},
|
44
|
-
// ‘node.module’
|
45
|
-
module: {
|
46
|
-
// 文件处理
|
47
|
-
rules: [
|
48
|
-
{
|
49
|
-
// 处理‘less’和‘css’文件
|
50
|
-
test: /\.(less|css)$/,
|
51
|
-
// 以此从下到上处理‘css’
|
52
|
-
use: [
|
53
|
-
// 3:由‘webpack.MiniCssExtractPlugin.loader’做收尾工作
|
54
|
-
// 主要分离css文件
|
55
|
-
{
|
56
|
-
loader: MiniCssExtractPlugin.loader
|
57
|
-
},
|
58
|
-
// 2:将被‘less-loader’处理的‘css’
|
59
|
-
// 由‘css-loader’再次处理
|
60
|
-
{
|
61
|
-
loader: 'css-loader'
|
62
|
-
},
|
63
|
-
// 1:处理‘less’文件
|
64
|
-
{
|
65
|
-
// 使用‘less-loader’
|
66
|
-
loader: 'less-loader',
|
67
|
-
// 配置‘less-loader’
|
68
|
-
options: {
|
69
|
-
// ‘less-loader’特殊配置
|
70
|
-
lessOptions: {
|
71
|
-
// 定义‘less’全局变量,从jjb.config.antd获取
|
72
|
-
modifyVars: (config.framework || {}).antd || {},
|
73
|
-
// 启用‘less-javascript’功能
|
74
|
-
javascriptEnabled: true
|
75
|
-
}
|
76
|
-
}
|
77
|
-
}
|
78
|
-
]
|
79
|
-
},
|
80
|
-
{
|
81
|
-
// 处理‘js’文件
|
82
|
-
test: /\.js$/,
|
83
|
-
// 使用‘babel-loader’
|
84
|
-
loader: 'babel-loader',
|
85
|
-
// 允许‘babel-loader’操作目录
|
86
|
-
include: [
|
87
|
-
// 整个‘src’目录
|
88
|
-
path.resolve(__dirname, '../src'),
|
89
|
-
// ‘jjb-dva-runtime’库
|
90
|
-
path.resolve(__dirname, '../node_modules/jjb-dva-runtime'),
|
91
|
-
// ‘jjb-common-decorator’库
|
92
|
-
path.resolve(__dirname, '../node_modules/jjb-common-decorator')
|
93
|
-
],
|
94
|
-
// 配置‘babel-loader’
|
95
|
-
options: {
|
96
|
-
// 加入一个‘babel-plugin-import’插件,特殊处理‘antd’文件过大问题
|
97
|
-
plugins: [
|
98
|
-
[
|
99
|
-
'import',
|
100
|
-
{
|
101
|
-
// ‘webpack’定义全局变量‘antd’
|
102
|
-
libraryName: 'antd',
|
103
|
-
// 按需将‘es’文件夹中组件导出,绑定到‘antd’变量
|
104
|
-
// 除了‘es’,也可以修改为‘lib’
|
105
|
-
libraryDirectory: 'es',
|
106
|
-
// 这里设为‘true’,表示自动导入‘antd/dist/less’
|
107
|
-
// 或修改为‘css’ | ‘less’
|
108
|
-
style: true
|
109
|
-
}
|
110
|
-
],
|
111
|
-
[
|
112
|
-
'@babel/plugin-proposal-decorators',
|
113
|
-
{
|
114
|
-
'legacy': true
|
115
|
-
}
|
116
|
-
]
|
117
|
-
],
|
118
|
-
// 考虑到使用‘React JSX’语法‘babel-loader’的编译预设要改为‘preset-react’
|
119
|
-
// 可选值‘preset-env’
|
120
|
-
presets: [ '@babel/preset-react' ]
|
121
|
-
}
|
122
|
-
},
|
123
|
-
{
|
124
|
-
// 处理‘svg’文件
|
125
|
-
test: /\.svg/,
|
126
|
-
// 使用‘file-loader’
|
127
|
-
loader: 'file-loader',
|
128
|
-
// 配置‘file-loader’
|
129
|
-
options: {
|
130
|
-
// 指定存储目录
|
131
|
-
outputPath: 'media/svg'
|
132
|
-
}
|
133
|
-
},
|
134
|
-
{
|
135
|
-
// 处理图片文件
|
136
|
-
test: /\.(png|jpg|jpeg|gif|ico|bmp)/,
|
137
|
-
// 使用‘url-loader’或‘raw-loader’
|
138
|
-
loader: 'url-loader',
|
139
|
-
// 配置‘url-loader’
|
140
|
-
options: {
|
141
|
-
// 当文件大小处于(?)byte,输出‘base64’,反之为‘url’.
|
142
|
-
// 这里设为‘false’,表示无论多大多小,都为‘url’.
|
143
|
-
limit: false,
|
144
|
-
// 处理引入地址‘code’编码为‘utf-8’
|
145
|
-
encoding: true,
|
146
|
-
// 若输出为‘url’,需要指定存储目录
|
147
|
-
outputPath: 'media/image'
|
148
|
-
}
|
149
|
-
}
|
150
|
-
]
|
151
|
-
},
|
152
|
-
// 解析
|
153
|
-
resolve: {
|
154
|
-
// 为‘import’或‘require’定义别名路径
|
155
|
-
alias: {
|
156
|
-
'~': requireResolve('src')
|
157
|
-
}
|
158
|
-
},
|
159
|
-
// 插件
|
160
|
-
plugins: [
|
161
|
-
// 定义输出‘html’模板
|
162
|
-
// 并向‘window’全局注入变量
|
163
|
-
new HtmlWebpackPlugin(Object.assign({ template: requireResolve('public/index.html') }, windowInject)),
|
164
|
-
// 对分离的‘css’区块定义同步导入名称,和异步导入名称
|
165
|
-
new MiniCssExtractPlugin({
|
166
|
-
// 同步导入‘import | require’
|
167
|
-
filename: 'static/css/[id].css',
|
168
|
-
// 异步导入‘import | require’
|
169
|
-
chunkFilename: 'static/css/[id].css'
|
170
|
-
}),
|
171
|
-
// 注入全局变量到项目中,从‘jjb.config.contextData’读取
|
172
|
-
new webpack.DefinePlugin({ 'process.env.app': JSON.stringify(contextData) }),
|
173
|
-
// 解决‘moment.js’本地化文件过多问题
|
174
|
-
// 按需加载本地化文件当前项目只需要‘zh_CN.js’
|
175
|
-
new webpack.IgnorePlugin({
|
176
|
-
contextRegExp: /moment$/,
|
177
|
-
resourceRegExp: /^\.\/locale$/
|
178
|
-
}),
|
179
|
-
// 每次打包前删除‘dist’目录
|
180
|
-
new CleanWebpackPlugin()
|
181
|
-
],
|
182
|
-
// 外部扩展
|
183
|
-
externals: {
|
184
|
-
'window:jjb-common-lib': 'jjbCommonLib'
|
185
|
-
},
|
186
|
-
// 打包优化
|
187
|
-
optimization: isProduction
|
188
|
-
? {
|
189
|
-
// 是否启用优化
|
190
|
-
minimize: true,
|
191
|
-
// 优化插件
|
192
|
-
minimizer: [
|
193
|
-
// 压缩‘javascript’代码
|
194
|
-
new TerserWebpackPlugin({ extractComments: false }),
|
195
|
-
// 压缩‘css’代码
|
196
|
-
new CssMinimizerWebpackPlugin()
|
197
|
-
],
|
198
|
-
// 分离‘区块’
|
199
|
-
splitChunks: {
|
200
|
-
// 分离范围‘all’即所有
|
201
|
-
chunks: 'all',
|
202
|
-
// 分离大小范围0
|
203
|
-
minSize: 0,
|
204
|
-
// 分离大小范围100000
|
205
|
-
maxSize: 100000,
|
206
|
-
// 同一个区块被调用两次,需要分离
|
207
|
-
minChunks: 2,
|
208
|
-
// 最大异步请求区块
|
209
|
-
maxAsyncRequests: 6,
|
210
|
-
// 最大初始化请求区块
|
211
|
-
maxInitialRequests: 4
|
212
|
-
}
|
213
|
-
}
|
214
|
-
: {}
|
215
|
-
}
|
216
|
-
};
|
217
|
-
};
|