@dmqweb/elpis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/.eslintrc +59 -0
- package/.vscode/settings.json +15 -0
- package/README.md +198 -0
- package/app/controller/base.js +41 -0
- package/app/controller/project.js +98 -0
- package/app/controller/view.js +24 -0
- package/app/extend/logger.js +43 -0
- package/app/middleware/api-params-verify.js +89 -0
- package/app/middleware/api-sign-verify.js +47 -0
- package/app/middleware/error-handler.js +41 -0
- package/app/middleware/project-handler.js +27 -0
- package/app/middleware.js +40 -0
- package/app/pages/asserts/custom.css +12 -0
- package/app/pages/boot.js +59 -0
- package/app/pages/common/curl.js +88 -0
- package/app/pages/common/util.js +3 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +40 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +141 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +39 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +146 -0
- package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +24 -0
- package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +118 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +177 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +157 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +150 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +113 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +35 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +134 -0
- package/app/pages/dashboard/dashboard.vue +127 -0
- package/app/pages/dashboard/entry.dashboard.js +46 -0
- package/app/pages/store/index.js +5 -0
- package/app/pages/store/menu.js +61 -0
- package/app/pages/store/project.js +13 -0
- package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
- package/app/pages/widgets/header-container/asserts/logo.png +0 -0
- package/app/pages/widgets/header-container/header-container.vue +144 -0
- package/app/pages/widgets/schema-form/complex-view/input/input.vue +165 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +166 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +144 -0
- package/app/pages/widgets/schema-form/form-item.config.js +24 -0
- package/app/pages/widgets/schema-form/schema-form.vue +144 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +57 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +77 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +51 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +58 -0
- package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +138 -0
- package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
- package/app/pages/widgets/schema-table/schema-table.vue +254 -0
- package/app/pages/widgets/sider-container/sider-container.vue +32 -0
- package/app/router/business.js +15 -0
- package/app/router/project.js +10 -0
- package/app/router/view.js +11 -0
- package/app/router-schema/business.js +82 -0
- package/app/router-schema/project.js +40 -0
- package/app/service/base.js +13 -0
- package/app/service/project.js +55 -0
- package/app/view/entry.tpl +27 -0
- package/app/webpack/config/blank.js +3 -0
- package/app/webpack/config/webpack.base.js +269 -0
- package/app/webpack/config/webpack.dev.js +61 -0
- package/app/webpack/config/webpack.prod.js +149 -0
- package/app/webpack/dev.js +58 -0
- package/app/webpack/prod.js +21 -0
- package/config/config.default.js +3 -0
- package/elpis-core/env.js +22 -0
- package/elpis-core/index.js +99 -0
- package/elpis-core/loader/config.js +51 -0
- package/elpis-core/loader/controller.js +75 -0
- package/elpis-core/loader/extend.js +54 -0
- package/elpis-core/loader/middleware.js +69 -0
- package/elpis-core/loader/router-schema.js +50 -0
- package/elpis-core/loader/router.js +52 -0
- package/elpis-core/loader/service.js +74 -0
- package/index.js +29 -0
- package/jsconfig.json +16 -0
- package/logs/applocation.log +3 -0
- package/model/index.js +119 -0
- package/package.json +93 -0
- package/test/controller/project.test.js +216 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = {
|
|
3
|
+
'/api/proj/product/list': {
|
|
4
|
+
get: {
|
|
5
|
+
query: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
page: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
},
|
|
11
|
+
pageSize: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
'/api/proj/product': {
|
|
19
|
+
put: {
|
|
20
|
+
body: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
product_id: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
},
|
|
26
|
+
product_name:{
|
|
27
|
+
type: 'string',
|
|
28
|
+
},
|
|
29
|
+
product_price: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
},
|
|
32
|
+
inventory: {
|
|
33
|
+
type: 'number',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
required: ['product_id', 'product_name'],
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
post: {
|
|
40
|
+
body: {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
product_name:{
|
|
44
|
+
type: 'string',
|
|
45
|
+
},
|
|
46
|
+
product_price: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
},
|
|
49
|
+
inventory: {
|
|
50
|
+
type: 'number',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
required: ['product_name'],
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
delete: {
|
|
57
|
+
body: {
|
|
58
|
+
type: 'object',
|
|
59
|
+
properties: {
|
|
60
|
+
product_id: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
required: ['product_id'],
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
get: {
|
|
68
|
+
query: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
product_id: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ['product_id'],
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
'/api/proj/product_enum/list': {
|
|
80
|
+
get: {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// API路由模式定义文件\
|
|
2
|
+
|
|
3
|
+
// 用于定义和验证API接口的请求规范
|
|
4
|
+
module.exports = {
|
|
5
|
+
'/api/project': {
|
|
6
|
+
// 获取项目配置接口
|
|
7
|
+
get: {
|
|
8
|
+
query: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
proj_key: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
required: ['proj_key'],
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
'/api/project/list': {
|
|
21
|
+
// 获取项目列表接口
|
|
22
|
+
get: {
|
|
23
|
+
query: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
proj_key: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// 获取项目列表关键数据接口
|
|
35
|
+
'/api/project/model_list': {
|
|
36
|
+
get: {
|
|
37
|
+
// 这个接口不需要任何参数
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module.exports = (app) => {
|
|
2
|
+
const BaseService = require('./base')(app);
|
|
3
|
+
const modelList = require('../../model/index')(app);
|
|
4
|
+
// console.log(JSON.stringify(modelList));
|
|
5
|
+
return class projectService extends BaseService {
|
|
6
|
+
/**
|
|
7
|
+
* 获取项目配置
|
|
8
|
+
* @param {string} projectKey 项目键值,用于指定要获取的项目配置
|
|
9
|
+
*/
|
|
10
|
+
async get(projectKey) {
|
|
11
|
+
let projConfig;
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const foundModel = modelList.find(modelItem => {
|
|
15
|
+
const { project } = modelItem;
|
|
16
|
+
return project[projectKey];
|
|
17
|
+
});
|
|
18
|
+
if (foundModel) {
|
|
19
|
+
const { project } = foundModel;
|
|
20
|
+
projConfig = project[projectKey];
|
|
21
|
+
if (projConfig) {
|
|
22
|
+
projConfig.proj_key = projectKey;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return projConfig;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 获取统一模型下的项目列表,如果无 projectKey,则获取所有项目列表
|
|
31
|
+
* @param {string} proj_key 项目key
|
|
32
|
+
*/
|
|
33
|
+
async getProjectList({ projectKey }) {
|
|
34
|
+
return modelList.reduce((preList, modelItem) => {
|
|
35
|
+
const { project } = modelItem;
|
|
36
|
+
|
|
37
|
+
// 如果有传 projectKey,但项目里面没有这个 projectKey,则返回
|
|
38
|
+
if (projectKey && !project[projectKey]) return preList;
|
|
39
|
+
|
|
40
|
+
for(const projKey in project) {
|
|
41
|
+
preList.push(project[projKey]);
|
|
42
|
+
}
|
|
43
|
+
return preList;
|
|
44
|
+
}, [])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 获取所有模型与项目的结构化数据
|
|
50
|
+
*/
|
|
51
|
+
async getModelList() {
|
|
52
|
+
return modelList;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN" >
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{{name}}</title>
|
|
7
|
+
<link href="/static/normalize.css" rel="stylesheet" >
|
|
8
|
+
<link href="/static/logo.png" rel="icon" type="image/x-icon" >
|
|
9
|
+
</head>
|
|
10
|
+
<body style="margin: 0;">
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<input id="projKey" value="{{ projKey }}" style="display: none;" />
|
|
13
|
+
<input id="env" value="{{ env }}" style="display: none;" />
|
|
14
|
+
<input id="options" value="{{ options }}" style="display: none;" />
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
try {
|
|
18
|
+
window.projKey = document.getElementById('projKey').value
|
|
19
|
+
window.env = document.getElementById('env').value
|
|
20
|
+
const options = document.getElementById('options').value
|
|
21
|
+
window.options = JSON.parse(options)
|
|
22
|
+
} catch (e) {
|
|
23
|
+
console.log(e)
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { VueLoaderPlugin } = require('vue-loader');
|
|
3
|
+
const webpack = require("webpack");
|
|
4
|
+
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
5
|
+
const glob = require("glob");
|
|
6
|
+
const merge = require('webpack-merge');
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
|
|
9
|
+
// 动态构造 elpis下的 entry 和 HtmlWebpackPluginList
|
|
10
|
+
const elpisEntries = {}
|
|
11
|
+
const elpisHtmlWebpackPluginList = []
|
|
12
|
+
// 获取 elpis/app/pages 目录下所有入口文件(entry.xx.js)
|
|
13
|
+
const elpisEntryList = path.resolve(__dirname, '../../pages/**/entry.*.js');
|
|
14
|
+
glob.sync(elpisEntryList).forEach(file=>handleFile(file,elpisEntries,elpisHtmlWebpackPluginList))
|
|
15
|
+
|
|
16
|
+
// 动态构造 业务目录下的 entry 和 HtmlWebpackPluginList
|
|
17
|
+
const businessEntries = {}
|
|
18
|
+
const businessHtmlWebpackPluginList = []
|
|
19
|
+
// 获取 elpis/app/pages 目录下所有入口文件(entry.xx.js)
|
|
20
|
+
const businessEntryList = path.resolve(process.cwd(), './app/pages/**/entry.*.js');
|
|
21
|
+
glob.sync(businessEntryList).forEach(file=>handleFile(file,businessEntries,businessHtmlWebpackPluginList))
|
|
22
|
+
|
|
23
|
+
function handleFile(file,entires = {},HtmlWebpackPluginList = []) {
|
|
24
|
+
// 构造 entry
|
|
25
|
+
const entryName = path.basename(file, '.js')
|
|
26
|
+
entires[entryName] = file
|
|
27
|
+
// 构造 HtmlWebpackPlugin 最终渲染的页面文件
|
|
28
|
+
HtmlWebpackPluginList.push(
|
|
29
|
+
// html-webpack-plugin 辅助注入打包后的 bundle 文件到 tpl中
|
|
30
|
+
new HtmlWebpackPlugin({
|
|
31
|
+
// 模板文件路径
|
|
32
|
+
filename: path.resolve(process.cwd(), './app/public/dist',`${entryName}.tpl`),
|
|
33
|
+
// 指定要使用的模板文件
|
|
34
|
+
template: path.resolve(__dirname, '../../view/entry.tpl'),
|
|
35
|
+
// 要注入的代码块
|
|
36
|
+
chunks:[ `${entryName}`]
|
|
37
|
+
})
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 加载业务webpack.config.js的配置
|
|
42
|
+
let businessWebpackConfig = {};
|
|
43
|
+
try {
|
|
44
|
+
businessWebpackConfig = require(`${process.cwd()}/app/webpack.config.js`);
|
|
45
|
+
} catch (e) {}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* webpack 基础配置
|
|
49
|
+
*/
|
|
50
|
+
module.exports = merge.smart({
|
|
51
|
+
// 添加 mode 配置以解决警告
|
|
52
|
+
mode: 'production',
|
|
53
|
+
|
|
54
|
+
// entry(入口):指定 webpack 构建依赖图的开始点
|
|
55
|
+
// webpack 会从这个点开始,递归地构建模块依赖关系图
|
|
56
|
+
entry: Object.assign({},elpisEntries,businessEntries),
|
|
57
|
+
|
|
58
|
+
// module(模块):配置如何处理项目中的不同类型模块
|
|
59
|
+
// 例如如何处理 CSS、图片、字体等非 JavaScript 模块
|
|
60
|
+
module: {
|
|
61
|
+
rules: [{
|
|
62
|
+
test: /\.vue$/,
|
|
63
|
+
use: {
|
|
64
|
+
loader: require.resolve('vue-loader')
|
|
65
|
+
}
|
|
66
|
+
}, {
|
|
67
|
+
test: /\.js$/,
|
|
68
|
+
include: [
|
|
69
|
+
// 处理elpis中的目录文件
|
|
70
|
+
path.resolve(__dirname, '../../pages'),
|
|
71
|
+
// 处理业务目录文件
|
|
72
|
+
path.resolve(process.cwd(), './app/pages'),
|
|
73
|
+
],
|
|
74
|
+
use: {
|
|
75
|
+
loader: require.resolve('babel-loader'),
|
|
76
|
+
options: {
|
|
77
|
+
sourceType: 'module',
|
|
78
|
+
// 添加配置以正确处理 ES6 模块
|
|
79
|
+
presets: [
|
|
80
|
+
[require.resolve('@babel/preset-env'), {
|
|
81
|
+
// 移除 modules: false 配置,让 Babel 自动处理模块转换
|
|
82
|
+
targets: {
|
|
83
|
+
browsers: ['last 2 versions', 'ie >= 11']
|
|
84
|
+
},
|
|
85
|
+
}]
|
|
86
|
+
],
|
|
87
|
+
plugins: [
|
|
88
|
+
require.resolve('@babel/plugin-transform-runtime')
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}, {
|
|
93
|
+
test: /\.(mjs|js)$/,
|
|
94
|
+
type: 'javascript/auto', // 自动识别模块类型
|
|
95
|
+
include: [
|
|
96
|
+
path.resolve(process.cwd(), './app/pages')
|
|
97
|
+
],
|
|
98
|
+
use: {
|
|
99
|
+
loader:require.resolve('babel-loader') // 复用已配置的 babel-loader
|
|
100
|
+
}
|
|
101
|
+
}, {
|
|
102
|
+
test: /\.(png|jpe?g|gif)(\?.+)?$/,
|
|
103
|
+
use: {
|
|
104
|
+
loader: require.resolve('url-loader'),
|
|
105
|
+
options: {
|
|
106
|
+
limit: 300,
|
|
107
|
+
esModule: false
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, {
|
|
111
|
+
test: /\.css$/,
|
|
112
|
+
use: [{
|
|
113
|
+
loader: require.resolve('style-loader')
|
|
114
|
+
}, {
|
|
115
|
+
loader: require.resolve('css-loader')
|
|
116
|
+
}]
|
|
117
|
+
}, {
|
|
118
|
+
test: /\.less$/,
|
|
119
|
+
use: [{
|
|
120
|
+
loader: require.resolve('style-loader')
|
|
121
|
+
}, {
|
|
122
|
+
loader: require.resolve('css-loader')
|
|
123
|
+
}, {
|
|
124
|
+
loader: require.resolve('less-loader')
|
|
125
|
+
}]
|
|
126
|
+
}, {
|
|
127
|
+
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
|
|
128
|
+
use: {
|
|
129
|
+
loader: require.resolve('file-loader')
|
|
130
|
+
}
|
|
131
|
+
}]
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
// output(出口):指定 webpack 如何输出编译后的文件以及输出到哪里
|
|
135
|
+
// 因为开发和生产环境输出不一致,所以在各自环境下配置
|
|
136
|
+
output: {},
|
|
137
|
+
|
|
138
|
+
// 配置 模块解析时的具体行为(定义在webpack在打包时,如何找到并解析具体模块的路径)
|
|
139
|
+
// 例如设置模块查找目录、文件扩展名、别名等
|
|
140
|
+
resolve: {
|
|
141
|
+
extensions: ['.js', '.vue', '.css', '.less'],
|
|
142
|
+
alias: (()=>{
|
|
143
|
+
// 由于webpack的构建是在编译时进行,所以当businessDashboardRouterConfig没配置router文件时,会报错,进行兼容
|
|
144
|
+
const blankAlias = {};
|
|
145
|
+
const blankPath = path.resolve(__dirname,"./blank.js");
|
|
146
|
+
|
|
147
|
+
// dashboard 路由扩展配置
|
|
148
|
+
const businessDashboardRouterConfig = path.resolve(process.cwd(),"./app/pages/dashboard/router.js")
|
|
149
|
+
blankAlias["$businessDashboardRouterConfig"] = fs.existsSync(businessDashboardRouterConfig)?businessDashboardRouterConfig:blankPath;
|
|
150
|
+
|
|
151
|
+
// 业务扩展 schema-view 的 component 配置
|
|
152
|
+
const businessComponentConfig = path.resolve(process.cwd(),"./app/pages/dashboard/complex-view/schema-view/components/component.config.js");
|
|
153
|
+
blankAlias["$businessComponentConfig"] = fs.existsSync(businessComponentConfig)?businessComponentConfig:blankPath;
|
|
154
|
+
|
|
155
|
+
// 业务扩展 schema-form 的 component 配置
|
|
156
|
+
const businessFormItemConfig = path.resolve(process.cwd(),"./app/pages/widgets/schema-form/form-item.config.js");
|
|
157
|
+
blankAlias["$businessFormItemConfig"] = fs.existsSync(businessFormItemConfig)?businessFormItemConfig:blankPath;
|
|
158
|
+
|
|
159
|
+
// 业务扩展 search-item 的 component 配置
|
|
160
|
+
const businessSearchItemConfig = path.resolve(process.cwd(),"./app/pages/widgets/schema-search-bar/search-item.config.js");
|
|
161
|
+
blankAlias["$businessSearchItemConfig"] = fs.existsSync(businessSearchItemConfig)?businessSearchItemConfig:blankPath;
|
|
162
|
+
console.log('%cdmq:::%s',`color:green;font-weight:bold;`,`哈哈哈哈`,businessSearchItemConfig,fs.existsSync(businessSearchItemConfig));
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
// 外部pages的vue引用vue时(由elpis的boot.js使用)需要修改引用到内部的vue
|
|
166
|
+
"vue": path.resolve(__dirname,"../../../node_modules/vue"),
|
|
167
|
+
$elpisPage: path.resolve(__dirname, '../../pages'),
|
|
168
|
+
$elpisCommon: path.resolve(__dirname, '../../pages/common'),
|
|
169
|
+
$elpisCurl: path.resolve(__dirname, '../../pages/common/curl.js'),
|
|
170
|
+
$elpisUtils: path.resolve(__dirname, '../../pages/common/util.js'),
|
|
171
|
+
|
|
172
|
+
$elpisWidgets: path.resolve(__dirname, '../../pages/widgets'),
|
|
173
|
+
$elpisHeaderContainer: path.resolve(__dirname, '../../pages/widgets/header-container/header-container.vue'),
|
|
174
|
+
$elpisSiderContainer: path.resolve(__dirname, '../../pages/widgets/sider-container/sider-container.vue'),
|
|
175
|
+
$elpisSchemaTable: path.resolve(__dirname, '../../pages/widgets/schema-table/schema-table.vue'),
|
|
176
|
+
$elpisSchemaForm: path.resolve(__dirname, '../../pages/widgets/schema-form/schema-form.vue'),
|
|
177
|
+
$elpisSchemaSearchBar: path.resolve(__dirname, '../../pages/widgets/schema-search-bar/schema-search-bar.vue'),
|
|
178
|
+
|
|
179
|
+
$elpisStore: path.resolve(__dirname, '../../pages/store'),
|
|
180
|
+
$elpisBoot: path.resolve(__dirname,"../../pages/boot.js"),
|
|
181
|
+
// 自定义dashboard路由页面使用
|
|
182
|
+
// $businessDashboardRouterConfig: path.resolve(process.cwd(),"./app/pages/dashboard/router.js")
|
|
183
|
+
...blankAlias
|
|
184
|
+
}
|
|
185
|
+
})(),
|
|
186
|
+
// 添加 fallback 配置以解决 Node.js 核心模块在浏览器环境中的问题
|
|
187
|
+
fallback: {
|
|
188
|
+
"process": false
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
// plugins(插件):用于执行更广泛的任务,比如打包优化、环境变量注入等
|
|
194
|
+
// 插件功能更强大,可以处理整个构建过程中的各种任务
|
|
195
|
+
plugins: [
|
|
196
|
+
// 处理 .vue 文件,这个插件时必须的
|
|
197
|
+
// 将你在 webpack 配置中定义的其他规则复制并应用到 .vue 文件
|
|
198
|
+
new VueLoaderPlugin(),
|
|
199
|
+
|
|
200
|
+
new webpack.ProvidePlugin({
|
|
201
|
+
// 配置第三方库暴露到 window context 下
|
|
202
|
+
Vue: 'vue',
|
|
203
|
+
axios: 'axios',
|
|
204
|
+
_: 'lodash'
|
|
205
|
+
}),
|
|
206
|
+
|
|
207
|
+
new webpack.DefinePlugin({
|
|
208
|
+
// 定义全局变量
|
|
209
|
+
__VUE_OPTIONS_API__: 'true', // 支持 vue 解析Options API
|
|
210
|
+
__VUE_PROD_DEVTOOLS__: 'false', // 禁用 vue 的调试工具
|
|
211
|
+
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' // 禁用生产环境显示 "水合"信息
|
|
212
|
+
}),
|
|
213
|
+
|
|
214
|
+
// 构造最终渲染的页面模板
|
|
215
|
+
...elpisHtmlWebpackPluginList,
|
|
216
|
+
...businessHtmlWebpackPluginList
|
|
217
|
+
],
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// 用于控制 webpack 的代码分割、压缩、作用域提升等优化功能
|
|
221
|
+
optimization: {
|
|
222
|
+
/**
|
|
223
|
+
* 把js代码打包成3种类型
|
|
224
|
+
* 1. vendor:第三方 lib 库,基本不会改动,除非依赖版本升级
|
|
225
|
+
* 2. common:业务组件代码的公共部分抽取出来,改动较少
|
|
226
|
+
* 2. entry.{page}: 不用页面 entry 里的业务组件代码的差异部分, 会经常改动
|
|
227
|
+
* 目的:把改动和引用频率不一样的 js文件区分出来,以达到更好利用浏览器缓存的效果
|
|
228
|
+
*/
|
|
229
|
+
splitChunks: {
|
|
230
|
+
// 对所有类型的 chunks 进行代码分割优化(包括同步和异步加载的模块)
|
|
231
|
+
chunks: 'all',
|
|
232
|
+
// 按需加载时的最大并行请求数为 10(控制动态导入时能同时加载的 chunk 数量)
|
|
233
|
+
maxAsyncRequests: 10,
|
|
234
|
+
// 入口点初始加载时的最大并行请求数为 10(控制首屏加载时能同时加载的 chunk 数量)
|
|
235
|
+
maxInitialRequests: 10,
|
|
236
|
+
// 缓存组配置(定义不同类型的模块如何分组打包)
|
|
237
|
+
cacheGroups: {
|
|
238
|
+
// 第三方库缓存组(处理 node_modules 中的第三方依赖)
|
|
239
|
+
vendor: {
|
|
240
|
+
// 匹配 node_modules 目录下的所有模块(跨平台兼容路径分隔符)
|
|
241
|
+
test: /[\\/]node_modules[\\/]/,
|
|
242
|
+
// 将匹配的模块打包到名为 vendor 的 chunk 中
|
|
243
|
+
name: 'vendor',
|
|
244
|
+
// 设置缓存组优先级为 20(数值越大优先级越高)
|
|
245
|
+
priority: 20,
|
|
246
|
+
// 强制执行此缓存组(忽略全局 minSize、minChunks 等限制条件)
|
|
247
|
+
enforce: true,
|
|
248
|
+
// 如果已存在包含相同模块的 chunk,则重用它而不是创建新的
|
|
249
|
+
reuseExistingChunk: true
|
|
250
|
+
},
|
|
251
|
+
common: { // 公共模块
|
|
252
|
+
test: /[\\/]common|widgets[\\/]/, // 匹配 common 或 widgets 目录下的模块为公共模块
|
|
253
|
+
name: 'common', // 模块名称
|
|
254
|
+
minChunks: 2, // 引用过两次即被归为公共模块
|
|
255
|
+
minSize: 1, // 最小分割文件
|
|
256
|
+
priority: 10, // 优先级
|
|
257
|
+
reuseExistingChunk: true // 复用已有的公共 chunk
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
// 将 webpack 运行时生成的代码打包到 runtime.js 中
|
|
262
|
+
runtimeChunk: true
|
|
263
|
+
},
|
|
264
|
+
// 添加实验性功能支持ES6模块
|
|
265
|
+
experiments: {
|
|
266
|
+
topLevelAwait: true,
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
},businessWebpackConfig)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const webpack = require('webpack')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const merge = require('webpack-merge')
|
|
4
|
+
|
|
5
|
+
// 基类配置
|
|
6
|
+
const baseConfig = require('./webpack.base.js')
|
|
7
|
+
|
|
8
|
+
// deserver 配置
|
|
9
|
+
const DEV_SERVER_CONFIG = {
|
|
10
|
+
HOST: '127.0.0.1',
|
|
11
|
+
PORT: 9002,
|
|
12
|
+
HMR_PATH: '/__webpack_hmr', // 默认
|
|
13
|
+
TIMEOUT: 20000
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 开发阶段的 entry 配置需要加入 hmr
|
|
17
|
+
Object.keys(baseConfig.entry).forEach(v => {
|
|
18
|
+
// 第三方库不作为 hmr 入口
|
|
19
|
+
if ( v !== 'vendor' ){
|
|
20
|
+
baseConfig.entry[v] = [
|
|
21
|
+
baseConfig.entry[v],
|
|
22
|
+
`${require.resolve('webpack-hot-middleware/client')}?path=http://${DEV_SERVER_CONFIG.HOST}:${DEV_SERVER_CONFIG.PORT}${DEV_SERVER_CONFIG.HMR_PATH}&timeout=${DEV_SERVER_CONFIG.TIMEOUT}&reload=true`
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// 生产环境 webpack 配置
|
|
28
|
+
const webpackDevConfig = merge(baseConfig, {
|
|
29
|
+
// 指定开发环境配置
|
|
30
|
+
mode: 'development',
|
|
31
|
+
|
|
32
|
+
// 添加开发阶段插件,呈现代码的映射关系,便于在开发过程中调试代码
|
|
33
|
+
devtool: 'eval-cheap-module-source-map',
|
|
34
|
+
|
|
35
|
+
// 开发阶段 output 配置
|
|
36
|
+
output: {
|
|
37
|
+
// 定义输出文件名格式:在 js 目录下生成固定名称的bundle.js
|
|
38
|
+
filename: 'js/[name].bundle.js',
|
|
39
|
+
// 定义输出文件的绝对路径:
|
|
40
|
+
path: path.join(process.cwd(), './app/public/dist/dev/'),
|
|
41
|
+
// 外部资源公共路径
|
|
42
|
+
publicPath: `http://${DEV_SERVER_CONFIG.HOST}:${DEV_SERVER_CONFIG.PORT}/public/dist/dev/`,
|
|
43
|
+
//
|
|
44
|
+
globalObject: 'this'
|
|
45
|
+
},
|
|
46
|
+
plugins: [
|
|
47
|
+
// 用于实现热模块替换
|
|
48
|
+
// 热模块替换允许在运行时更新模块,而无需完全刷新页面
|
|
49
|
+
new webpack.HotModuleReplacementPlugin({
|
|
50
|
+
// 启用多步编译模式
|
|
51
|
+
multiStep: true
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
// 配置开发环境 webpack 配置
|
|
58
|
+
webpackDevConfig,
|
|
59
|
+
// devServer 配置 ,暴露给 dev.js使用
|
|
60
|
+
DEV_SERVER_CONFIG
|
|
61
|
+
}
|