@mangjuxiong/elpis 1.0.2

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.
Files changed (81) hide show
  1. package/.babelrc +5 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc +66 -0
  4. package/README.md +214 -0
  5. package/app/controller/base.js +39 -0
  6. package/app/controller/project.js +75 -0
  7. package/app/controller/view.js +19 -0
  8. package/app/extend/database.js +5 -0
  9. package/app/extend/logger.js +38 -0
  10. package/app/middleware/api-params-verify.js +74 -0
  11. package/app/middleware/api-sign-verify.js +36 -0
  12. package/app/middleware/error-handle.js +32 -0
  13. package/app/middleware/project-handler.js +26 -0
  14. package/app/middleware.js +39 -0
  15. package/app/pages/asserts/custom.css +14 -0
  16. package/app/pages/boot.js +48 -0
  17. package/app/pages/common/curl.js +80 -0
  18. package/app/pages/common/utils.js +34 -0
  19. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +24 -0
  20. package/app/pages/dashboard/complex-view/header-view/head-view.vue +113 -0
  21. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +35 -0
  23. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +118 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/components-config.js +23 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +103 -0
  27. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +112 -0
  28. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +124 -0
  29. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +90 -0
  30. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +22 -0
  31. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +113 -0
  32. package/app/pages/dashboard/dashboard.vue +85 -0
  33. package/app/pages/dashboard/entry.dashboard.js +46 -0
  34. package/app/pages/store/index.js +4 -0
  35. package/app/pages/store/menu.js +54 -0
  36. package/app/pages/store/project.js +13 -0
  37. package/app/pages/widgets/head-container/asserts/logo.png +0 -0
  38. package/app/pages/widgets/head-container/head-container.vue +77 -0
  39. package/app/pages/widgets/schema-form/complex-view/input/input.vue +134 -0
  40. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +135 -0
  41. package/app/pages/widgets/schema-form/complex-view/select/select.vue +120 -0
  42. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  43. package/app/pages/widgets/schema-form/schema-form.vue +130 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +51 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +55 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +38 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +40 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +100 -0
  49. package/app/pages/widgets/schema-search-bar/search-item-config.js +31 -0
  50. package/app/pages/widgets/schema-table/schema-table.vue +225 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +27 -0
  52. package/app/public/output/entry.page1.tpl +42 -0
  53. package/app/public/static/logo.jpg +0 -0
  54. package/app/public/static/normalize.css +267 -0
  55. package/app/router/project.js +6 -0
  56. package/app/router/view.js +7 -0
  57. package/app/router-schema/project.js +30 -0
  58. package/app/service/base.js +13 -0
  59. package/app/service/project.js +42 -0
  60. package/app/view/entry.tpl +25 -0
  61. package/app/webpack/config/babel.config.js +4 -0
  62. package/app/webpack/config/webpack.base.js +229 -0
  63. package/app/webpack/config/webpack.dev.js +57 -0
  64. package/app/webpack/config/webpack.prod.js +120 -0
  65. package/app/webpack/libs/blank.js +1 -0
  66. package/app/webpack/libs/dev.js +53 -0
  67. package/app/webpack/libs/prod.js +22 -0
  68. package/config/config.default.js +4 -0
  69. package/elpis-core/env.js +20 -0
  70. package/elpis-core/index.js +81 -0
  71. package/elpis-core/loader/config.js +52 -0
  72. package/elpis-core/loader/controller.js +59 -0
  73. package/elpis-core/loader/extend.js +47 -0
  74. package/elpis-core/loader/middleware.js +57 -0
  75. package/elpis-core/loader/router-schema.js +41 -0
  76. package/elpis-core/loader/router.js +42 -0
  77. package/elpis-core/loader/service.js +59 -0
  78. package/index.js +39 -0
  79. package/model/index.js +107 -0
  80. package/package.json +90 -0
  81. package/test/controller/project.test.js +194 -0
@@ -0,0 +1,267 @@
1
+ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2
+
3
+ /**
4
+ * 1. Set default font family to sans-serif.
5
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
6
+ * user zoom.
7
+ */
8
+ html,
9
+ body,
10
+ span,
11
+ div,
12
+ p,
13
+ a,
14
+ table,
15
+ tbody,
16
+ td,
17
+ h1,
18
+ h2,
19
+ h3,
20
+ img,
21
+ form,
22
+ font,
23
+ strong,
24
+ b,
25
+ i,
26
+ dl,
27
+ dt,
28
+ dd,
29
+ ol,
30
+ ul,
31
+ li,
32
+ dl,
33
+ dd,
34
+ dt,
35
+ iframe,
36
+ label,
37
+ blockquote,
38
+ input,
39
+ button {
40
+ padding: 0;
41
+ margin: 0;
42
+ list-style: none;
43
+ }
44
+
45
+ html {
46
+ font-family: 'Open Sans', 'Helvetica Neue', 'Microsoft Yahei', sans-serif; /* 1 */
47
+ -ms-text-size-adjust: 100%; /* 2 */
48
+ -webkit-text-size-adjust: 100%; /* 2 */
49
+ }
50
+
51
+ /**
52
+ * Remove default margin.
53
+ */
54
+
55
+ body {
56
+ margin: 0;
57
+ }
58
+
59
+ /* Links
60
+ ========================================================================== */
61
+
62
+ /**
63
+ * Remove the gray background color from active links in IE 10.
64
+ */
65
+
66
+ a {
67
+ background-color: transparent;
68
+ text-decoration: none;
69
+ }
70
+
71
+ /**
72
+ * Improve readability when focused and also mouse hovered in all browsers.
73
+ */
74
+
75
+ a:active,
76
+ a:hover {
77
+ outline: 0;
78
+ }
79
+
80
+ /* Text-level semantics
81
+ ========================================================================== */
82
+
83
+ /**
84
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
85
+ */
86
+
87
+ b,
88
+ strong {
89
+ font-weight: bold;
90
+ }
91
+
92
+ /* Embedded content
93
+ ========================================================================== */
94
+
95
+ /**
96
+ * Remove border when inside `a` element in IE 8/9/10.
97
+ */
98
+
99
+ img {
100
+ border: 0;
101
+ }
102
+
103
+ /* Grouping content
104
+ ========================================================================== */
105
+
106
+ /**
107
+ * Address margin not present in IE 8/9 and Safari.
108
+ */
109
+
110
+ figure {
111
+ margin: 1em 40px;
112
+ }
113
+
114
+ /* Forms
115
+ ========================================================================== */
116
+
117
+ /**
118
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
119
+ * styling of `select`, unless a `border` property is set.
120
+ */
121
+
122
+ /**
123
+ * 1. Correct color not being inherited.
124
+ * Known issue: affects color of disabled elements.
125
+ * 2. Correct font properties not being inherited.
126
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
127
+ */
128
+
129
+ button,
130
+ input,
131
+ optgroup,
132
+ select,
133
+ textarea {
134
+ color: inherit; /* 1 */
135
+ font: inherit; /* 2 */
136
+ margin: 0; /* 3 */
137
+ }
138
+
139
+ /**
140
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
141
+ */
142
+
143
+ button {
144
+ overflow: visible;
145
+ }
146
+
147
+ /**
148
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
149
+ * All other form control elements do not inherit `text-transform` values.
150
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
151
+ * Correct `select` style inheritance in Firefox.
152
+ */
153
+
154
+ button,
155
+ select {
156
+ text-transform: none;
157
+ }
158
+
159
+ /**
160
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
161
+ * and `video` controls.
162
+ * 2. Correct inability to style clickable `input` types in iOS.
163
+ * 3. Improve usability and consistency of cursor style between image-type
164
+ * `input` and others.
165
+ */
166
+
167
+ button,
168
+ html input[type="button"], /* 1 */
169
+ input[type="reset"],
170
+ input[type="submit"] {
171
+ -webkit-appearance: button; /* 2 */
172
+ cursor: pointer; /* 3 */
173
+ }
174
+
175
+ /**
176
+ * Re-set default cursor for disabled elements.
177
+ */
178
+
179
+ button[disabled],
180
+ html input[disabled] {
181
+ cursor: default;
182
+ }
183
+
184
+ /**
185
+ * Remove inner padding and border in Firefox 4+.
186
+ */
187
+
188
+ button::-moz-focus-inner,
189
+ input::-moz-focus-inner {
190
+ border: 0;
191
+ padding: 0;
192
+ }
193
+
194
+ /**
195
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
196
+ * the UA stylesheet.
197
+ */
198
+
199
+ input {
200
+ line-height: normal;
201
+ }
202
+
203
+ /**
204
+ * It's recommended that you don't attempt to style these elements.
205
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
206
+ *
207
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
208
+ * 2. Remove excess padding in IE 8/9/10.
209
+ */
210
+
211
+ input[type='checkbox'],
212
+ input[type='radio'] {
213
+ box-sizing: border-box; /* 1 */
214
+ padding: 0; /* 2 */
215
+ }
216
+
217
+ /**
218
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
219
+ * `font-size` values of the `input`, it causes the cursor style of the
220
+ * decrement button to change from `default` to `text`.
221
+ */
222
+
223
+ input[type='number']::-webkit-inner-spin-button,
224
+ input[type='number']::-webkit-outer-spin-button {
225
+ height: auto;
226
+ }
227
+
228
+ /**
229
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
230
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
231
+ * (include `-moz` to future-proof).
232
+ */
233
+
234
+ input[type='search'] {
235
+ -webkit-appearance: textfield; /* 1 */
236
+ -moz-box-sizing: content-box;
237
+ -webkit-box-sizing: content-box; /* 2 */
238
+ box-sizing: content-box;
239
+ }
240
+
241
+ /**
242
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
243
+ * Safari (but not Chrome) clips the cancel button when the search input has
244
+ * padding (and `textfield` appearance).
245
+ */
246
+
247
+ input[type='search']::-webkit-search-cancel-button,
248
+ input[type='search']::-webkit-search-decoration {
249
+ -webkit-appearance: none;
250
+ }
251
+
252
+ /* Tables
253
+ ========================================================================== */
254
+
255
+ /**
256
+ * Remove most spacing between table cells.
257
+ */
258
+
259
+ table {
260
+ border-collapse: collapse;
261
+ border-spacing: 0;
262
+ }
263
+
264
+ td,
265
+ th {
266
+ padding: 0;
267
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = (app, router) => {
2
+ const { project: projectController } = app.controllers;
3
+ router.get('/api/project/model_list', projectController.getModelList.bind(projectController));
4
+ router.get('/api/project/list', projectController.getList.bind(projectController));
5
+ router.get('/api/project', projectController.getProject.bind(projectController));
6
+ };
@@ -0,0 +1,7 @@
1
+ module.exports = (app, router) => {
2
+ const { view: viewController } = app.controllers;
3
+ //用户输入 http://ip:port/view/xxx,就能渲染对应的页面
4
+ router.get('/view/:page', viewController.renderPage.bind(viewController));
5
+ //用户输入 http://ip:port/view/xxx/xxx/*,就能渲染对应的页面
6
+ router.get('/view/:page/*', viewController.renderPage.bind(viewController));
7
+ };
@@ -0,0 +1,30 @@
1
+ module.exports = {
2
+ '/api/project/model_list': {
3
+ get: {},
4
+ },
5
+ '/api/project/list': {
6
+ get: {
7
+ query: {
8
+ type: 'object',
9
+ properties: {
10
+ proj_key: {
11
+ type: 'string'
12
+ }
13
+ }
14
+ }
15
+ },
16
+ },
17
+ '/api/project': {
18
+ get: {
19
+ query: {
20
+ type: 'object',
21
+ properties: {
22
+ proj_key: {
23
+ type: 'string',
24
+ }
25
+ },
26
+ required: ['proj_key'],
27
+ }
28
+ },
29
+ },
30
+ };
@@ -0,0 +1,13 @@
1
+ const superagent = require('superagent');
2
+ module.exports = (app) =>
3
+ class BaseService {
4
+ /**
5
+ * service基类
6
+ * 统一收拢 service 相关公共方法
7
+ */
8
+ constructor(ctx) {
9
+ this.app = app;
10
+ this.config = app.config;
11
+ this.curl = superagent;
12
+ }
13
+ };
@@ -0,0 +1,42 @@
1
+ module.exports = (app) => {
2
+ const BaseService = require('./base')(app);
3
+ const modelList = require('../../model')(app);
4
+
5
+ return class ProjectService extends BaseService {
6
+ /**
7
+ * 获取所有模型和项目的结构化数据
8
+ */
9
+ async getModelList() {
10
+ return modelList;
11
+ };
12
+ /**
13
+ * 获取当前projKey 对应模型下的项目列表,如果无projKey,则返回所有项目列表
14
+ */
15
+ getList({projKey}){
16
+ return modelList.reduce((preList,modelItem)=>{
17
+ const { project } = modelItem;
18
+ // 如果有projKey,则只返回projKey对应的项目,否则返回所有项目
19
+ if(projKey && !project[projKey]) return preList;
20
+ // 遍历project的key,将该model的所有project插入数据返回
21
+ for(const pKeyt in project){
22
+ preList.push(project[pKeyt]);
23
+ }
24
+ return preList;
25
+ },[]);
26
+ };
27
+ /**
28
+ * 根据proj_key获取项目配置
29
+ */
30
+ getProject({projKey}){
31
+ let projectConfig;
32
+ modelList.some(modelItem=>{
33
+ const { project } = modelItem;
34
+ if(project[projKey]){
35
+ projectConfig = project[projKey];
36
+ return true;
37
+ }
38
+ });
39
+ return projectConfig;
40
+ };
41
+ };
42
+ };
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html class="dark">
3
+ <head>
4
+ <meta charset="UTF-8"/>
5
+ <title>{{name}}</title>
6
+ <link href="/static/normalize.css" rel="stylesheet"/>
7
+ <link href="/static/logo.jpg" rel="icon" type="image/x-icon"/>
8
+ </head>
9
+ <body style="margin: 0;">
10
+ <div id="root"></div>
11
+ <input id="env" value="{{env}}" style="display: none;"/>
12
+ <input id="options" value="{{options}}" style="display: none;"/>
13
+ <input id="projKey" value="{{projKey}}" style="display: none;"/>
14
+ </body>
15
+ <script type="text/javascript">
16
+ try{
17
+ window.env = document.getElementById("env").value;
18
+ const options = document.getElementById("options").value;
19
+ window.options = JSON.parse(options);
20
+ window.projKey = document.getElementById("projKey").value;
21
+ }catch(e){
22
+ console.log("🚀 ~ e:", e)
23
+ }
24
+ </script>
25
+ </html>
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ presets: [require.resolve('@babel/preset-env')],
3
+ plugins: [require.resolve('@babel/plugin-transform-runtime')],
4
+ };
@@ -0,0 +1,229 @@
1
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
2
+ const path = require('path');
3
+ const { VueLoaderPlugin } = require('vue-loader');
4
+ const webpack = require('webpack');
5
+ const mrege = require('webpack-merge');
6
+ const glob = require('glob');
7
+ const fs = require('fs');
8
+
9
+ // 动态构造 pageEnytries 和 HtmlWebpackPluginList
10
+ const pageEntries = {};
11
+ const HtmlWebpackPluginList = [];
12
+
13
+ // 获取 elpis/app/pages目录下所有入口文件(entry.xx.js)
14
+ const elpisEntryList = glob.sync(path.resolve(__dirname, '../../pages/**/entry.*.js'));
15
+ // 获取业务方 app/pages目录下所有入口文件(entry.xx.js)
16
+ const businessEntryList = glob.sync(path.resolve(process.cwd(), './app/pages/**/entry.*.js'));
17
+ // 合并eplis和业务方的所有入口文件
18
+ const entryList = elpisEntryList.concat(businessEntryList);
19
+
20
+ entryList.forEach((file) => {
21
+ const entryName = path.basename(file, '.js');
22
+ // 构造entry
23
+ pageEntries[entryName] = file;
24
+ // 构造最终渲染的页面文件
25
+ HtmlWebpackPluginList.push(
26
+ // html-webpack-plugin 辅助注入打包后的bundle文件到tpl文件中
27
+ new HtmlWebpackPlugin({
28
+ // 产物(最终模板)输出路径
29
+ filename: path.resolve(process.cwd(), './app/public/dist/', `${entryName}.tpl`),
30
+ // 指定要使用的模板文件
31
+ template: path.resolve(__dirname, '../../view', 'entry.tpl'),
32
+ // 要注入的代码块
33
+ chunks: [entryName],
34
+ })
35
+ );
36
+ });
37
+
38
+ // 加载业务 webpack 配置
39
+ let businessWebpackConfig = {};
40
+ try {
41
+ businessWebpackConfig = require(`${process.cwd()}/app/webpack.config.js`);
42
+ } catch (err) {}
43
+
44
+ /**
45
+ * webpack 基础配置
46
+ */
47
+ module.exports = mrege.smart(
48
+ {
49
+ // 入口配置
50
+ entry: pageEntries,
51
+ // 模块解析配置(决定要加载哪些模块,以及用什么方式去解析)
52
+ module: {
53
+ rules: [
54
+ {
55
+ test: /\.vue$/,
56
+ use: {
57
+ loader: require.resolve('vue-loader'),
58
+ },
59
+ },
60
+ {
61
+ test: /\.js$/,
62
+ // 只对app/pages目录下的js文件进行babel-loader处理,加快打包速度
63
+ include: [
64
+ // elpis目录
65
+ path.resolve(__dirname, '../../pages'),
66
+ // 业务目录
67
+ path.resolve(process.cwd(), './app/pages'),
68
+ ],
69
+ use: {
70
+ loader: require.resolve('babel-loader'),
71
+ },
72
+ },
73
+ {
74
+ test: /\.(png|jpe?g|gif)(\?.+)?$/,
75
+ use: {
76
+ loader: require.resolve('url-loader'),
77
+ options: {
78
+ limit: 300,
79
+ esMoudle: false,
80
+ },
81
+ },
82
+ },
83
+ {
84
+ test: /\.css$/,
85
+ use: [require.resolve('style-loader'), require.resolve('css-loader')],
86
+ },
87
+ {
88
+ test: /\.less$/,
89
+ use: [require.resolve('style-loader'), require.resolve('css-loader'), require.resolve('less-loader')],
90
+ },
91
+ {
92
+ test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
93
+ use: require.resolve('file-loader'),
94
+ },
95
+ ],
96
+ },
97
+ // 产物输出路径,因为开发和生产环境输出一致,所以各个环境配各个环境的
98
+ output: {},
99
+ // 配置模块解析的具体行为(定义webpack在打包时如何找到并解析具体模块路径)
100
+ resolve: {
101
+ extensions: ['.js', '.vue', '.less', '.css'],
102
+ alias: (() => {
103
+ const aliasMap = {};
104
+ const blankModulePath = path.resolve(__dirname, '../libs/blank.js');
105
+
106
+ // dashboard 路由配置
107
+ const businessDashboardRouterConfig = path.resolve(process.cwd(), './app/pages/dashboard/router.js');
108
+ aliasMap['@businessDashboardRouterConfig'] = fs.existsSync(businessDashboardRouterConfig)
109
+ ? businessDashboardRouterConfig
110
+ : blankModulePath;
111
+
112
+ // schema-view component 扩展配置
113
+ const businessComponentConfig = path.resolve(
114
+ process.cwd(),
115
+ './app/pages/dashboard/complex-view/schema-view/components/components-config.js'
116
+ );
117
+ aliasMap['@businessComponentConfig'] = fs.existsSync(businessComponentConfig)
118
+ ? businessComponentConfig
119
+ : blankModulePath;
120
+
121
+ // schema-from 扩展配置
122
+ const businessFormItemConfig = path.resolve(
123
+ process.cwd(),
124
+ './app/pages/widgets/schema-form/form-item-config.js'
125
+ );
126
+ aliasMap['@businessFormItemConfig'] = fs.existsSync(businessFormItemConfig)
127
+ ? businessFormItemConfig
128
+ : blankModulePath;
129
+
130
+ // schema-search-bar 扩展配置
131
+ const businessSearchItemConfig = path.resolve(
132
+ process.cwd(),
133
+ './app/pages/widgets/schema-search-bar/search-item-config.js'
134
+ );
135
+ aliasMap['@businessSearchItemConfig'] = fs.existsSync(businessSearchItemConfig)
136
+ ? businessSearchItemConfig
137
+ : blankModulePath;
138
+
139
+ // header-container 扩展配置
140
+ const bussinessHeaderConfig = path.resolve(
141
+ process.cwd(),
142
+ './app/pages/widgets/header-container/header-config.js'
143
+ );
144
+ aliasMap['@bussinessHeaderConfig'] = fs.existsSync(bussinessHeaderConfig)
145
+ ? bussinessHeaderConfig
146
+ : blankModulePath;
147
+
148
+ return {
149
+ vue: require.resolve('vue'),
150
+ '@elpisElement': path.resolve(__dirname, '../../../node_modules/element-plus'),
151
+ '@babel/runtime/helpers/asyncToGenerator': require.resolve('@babel/runtime/helpers/asyncToGenerator'),
152
+ '@elpisPages': path.resolve(__dirname, '../../pages'),
153
+ '@elpisCommon': path.resolve(__dirname, '../../pages/common'),
154
+ '@elpisCurl': path.resolve(__dirname, '../../pages/common/curl.js'),
155
+ '@elpisUtils': path.resolve(__dirname, '../../pages/common/utils.js'),
156
+ '@elpisWidgets': path.resolve(__dirname, '../../pages/widgets'),
157
+ '@elpisHeadContainer': path.resolve(__dirname, '../../pages/widgets/head-container/head-container.vue'),
158
+ '@elpisSchemaForm': path.resolve(__dirname, '../../pages/widgets/schema-form/schema-form.vue'),
159
+ '@elpisSchemaSearchBar': path.resolve(
160
+ __dirname,
161
+ '../../pages/widgets/schema-search-bar/schema-search-bar.vue'
162
+ ),
163
+ '@elpisSchemaTable': path.resolve(__dirname, '../../pages/widgets/schema-table/schema-table.vue'),
164
+ '@elpisSiderContainer': path.resolve(__dirname, '../../pages/widgets/sider-container/sider-container.vue'),
165
+ '@elpisStore': path.resolve(__dirname, '../../pages/store'),
166
+ '@elpisBoot': path.resolve(__dirname, '../../pages/boot.js'),
167
+ ...aliasMap,
168
+ };
169
+ })(),
170
+ },
171
+ // 配置webpack插件
172
+ plugins: [
173
+ // 处理.vue文件,这个插件是必须的,它的职能是将你定义过的其他规则复制并应用到.vue文件里
174
+ // 例如,如果有条规则是/\.css$/,那么它会应用到.vue文件里的<style>板块中
175
+ new VueLoaderPlugin(),
176
+ // 把第三方库暴露到window.context下
177
+ new webpack.ProvidePlugin({
178
+ Vue: 'vue',
179
+ axios: 'axios',
180
+ _: 'lodash',
181
+ }),
182
+ // 定义全局常量
183
+ new webpack.DefinePlugin({
184
+ __VUE_OPTIONS_API__: 'true', // 支持vue解析optionsApi
185
+ __VUE_PROD_DEVTOOLS__: 'false', // 禁用vue测试工具
186
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false', // 禁用生产环境显示“水合”信息
187
+ }),
188
+ // 构造最终渲染的页面模板
189
+ ...HtmlWebpackPluginList,
190
+ ],
191
+ // 配置打包输出优化(代码分割,模块合并,缓存,TreeSharing,压缩等优化策略)
192
+ optimization: {
193
+ /**
194
+ * 把js文件打包成三种类型
195
+ * 1. vendor: 把第三方代码打包成单独的chunk,基本不会改动,除非依赖版本升级
196
+ * 2. common: 业务组件代码的公共部分抽取出来,改动较少
197
+ * 3. entry.{page}: 不用页面entry里的业务组件代码的差异部分,会经常改动
198
+ * 目的:把改动和引入频率不一样的js区分出来,以达到更好利用浏览器缓存的效果
199
+ */
200
+ splitChunks: {
201
+ chunks: 'all', // 对同步和异步模块都进行分割
202
+ maxAsyncRequests: 10, // 每次异步加载的最大并行请求数
203
+ maxInitialRequests: 10, // 入口点的最大并行请求数
204
+ cacheGroups: {
205
+ vendor: {
206
+ // 第三方库
207
+ test: /[\\/]node_modules[\\/]/, // 打包node_modules下的文件
208
+ name: 'vendor',
209
+ priority: 20, // 优先级,数字越大优先越高
210
+ enforce: true, // 强制执行
211
+ reuseExistingChunk: true, // 复用已有的公共chunk
212
+ },
213
+ common: {
214
+ // 公共模块
215
+ test: /[\\/]common|widgets[\\/]/,
216
+ name: 'common',
217
+ minChunks: 2, // 被两个引用即被归为公共模块
218
+ minSize: 1, // 最小分割大小(1 byte)
219
+ priority: 10, // 优先级
220
+ reuseExistingChunk: true, // 复用已有的公共chunk
221
+ },
222
+ },
223
+ },
224
+ // 将webpack运行时生成的代码打包到runtime.js
225
+ runtimeChunk: true,
226
+ },
227
+ },
228
+ businessWebpackConfig
229
+ );
@@ -0,0 +1,57 @@
1
+ const path = require('path');
2
+ const mrege = require('webpack-merge');
3
+ const webpack = require('webpack');
4
+
5
+ // 基类配置
6
+ const baseConfig = require('./webpack.base.js');
7
+ // dev-server 配置
8
+ const DEV_SERVER_CONFIG = {
9
+ host: '127.0.0.1',
10
+ port: '9011',
11
+ hmrPath: '__webpack_hmr', // 官方规定
12
+ timeout: 20000,
13
+ };
14
+
15
+ // 开发阶段 entry 配置需要加入hmr
16
+ Object.keys(baseConfig.entry).forEach((key) => {
17
+ // 第三方包 不需要加入hmr
18
+ if (key !== 'vendor') {
19
+ baseConfig.entry[key] = [
20
+ // 注入主入口文件
21
+ baseConfig.entry[key],
22
+ // 注入hmr
23
+ `${require.resolve('webpack-hot-middleware/client')}?path=http://${DEV_SERVER_CONFIG.host}:${
24
+ DEV_SERVER_CONFIG.port
25
+ }/${DEV_SERVER_CONFIG.hmrPath}&timeout=${DEV_SERVER_CONFIG.timeout}&reload=true`,
26
+ ];
27
+ }
28
+ });
29
+
30
+ // 开发环境 webpack 配置
31
+ const webpackConfig = mrege(baseConfig, {
32
+ // 开发环境
33
+ mode: 'development',
34
+ // source-map开发工具
35
+ devtool: 'eval-cheap-module-source-map',
36
+ // 开发环境的 output 配置
37
+ output: {
38
+ filename: 'js/[name]_[chunkhash:8].bundle.js',
39
+ path: path.join(process.cwd(), './app/public/dist/dev/'), // 输出文件存储路径
40
+ publicPath: `http://${DEV_SERVER_CONFIG.host}:${DEV_SERVER_CONFIG.port}/public/dist/dev/`, // 外部资源的路径
41
+ globalObject: 'this', // 支持多环境打包
42
+ },
43
+ // 开发阶段插件
44
+ plugins: [
45
+ // 用于实现热模块替换,模块热替换允许在应用程序运行时更新,极大地提升开发效率
46
+ new webpack.HotModuleReplacementPlugin({
47
+ multiStep: false,
48
+ }),
49
+ ],
50
+ });
51
+
52
+ module.exports = {
53
+ // webpack配置
54
+ webpackConfig,
55
+ // dev-server 配置,暴露给dev.js使用
56
+ DEV_SERVER_CONFIG,
57
+ };