diff --git a/README.md b/README.md index d4b56c3fe..cc9235d43 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ The following access addresses are built and deployed by the latest master branc * Multiple tabs support drag and drop sorting `1.8.0 +` * load only local JavaScript code less than 60kb on the homepage `1.8.0 +` * Built in build file volume checking tool `1.8.0 +` +* Example of multi page `1.23.0 +` +* Split chunks `1.23.0 +` ## Other synchronous repositories diff --git a/README.zh.md b/README.zh.md index 102cc0f5b..81272c4ab 100644 --- a/README.zh.md +++ b/README.zh.md @@ -97,6 +97,8 @@ * 多标签页支持拖拽排序 `1.8.0 +` * 优化生产环境构建,首页只加载小于 60kb 的本地 js 代码 `1.8.0 +` * 内置了构建文件体积检查工具 `1.8.0 +` +* 构建多页面示例 `1.23.0 +` +* 分包优化 `1.23.0 +` ## 其它同步仓库 diff --git a/babel.config.js b/babel.config.js index ce0dffbae..bf9a0f4a8 100644 --- a/babel.config.js +++ b/babel.config.js @@ -2,6 +2,17 @@ module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], - // 允许两种编码引入方式共存,也就是 common 规范与 es6 规范的共存处理 + plugins: [ + [ + 'import', + { + libraryName: 'vant', + libraryDirectory: 'es', + style: (name) => `${name}/style/less` + }, + 'vant' + ] + ], + // common + es6 共存 sourceType: 'unambiguous' } diff --git a/dependencies-cdn.js b/dependencies-cdn.js deleted file mode 100644 index 77a070327..000000000 --- a/dependencies-cdn.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = [ - { name: 'vue', library: 'Vue', js: 'https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js', css: '' }, - { name: 'vue-i18n', library: 'VueI18n', js: 'https://cdn.jsdelivr.net/npm/vue-i18n@8.15.1/dist/vue-i18n.min.js', css: '' }, - { name: 'vue-router', library: 'VueRouter', js: 'https://cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js', css: '' }, - { name: 'vuex', library: 'Vuex', js: 'https://cdn.jsdelivr.net/npm/vuex@3.1.2/dist/vuex.min.js', css: '' }, - { name: 'axios', library: 'axios', js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js', css: '' }, - { name: 'better-scroll', library: 'BScroll', js: 'https://cdn.jsdelivr.net/npm/better-scroll@1.15.2/dist/bscroll.min.js', css: '' }, - { name: 'element-ui', library: 'ELEMENT', js: 'https://cdn.jsdelivr.net/npm/element-ui@2.13.1/lib/index.js', css: 'https://cdn.jsdelivr.net/npm/element-ui@2.13.0/lib/theme-chalk/index.css' }, - { name: 'axios-mock-adapter', library: 'AxiosMockAdapter', js: 'https://cdn.jsdelivr.net/npm/axios-mock-adapter@1.18.1/dist/axios-mock-adapter.min.js', css: '' }, - { name: 'lodash', library: '_', js: 'https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js', css: '' }, - { name: 'ua-parser-js', library: 'UAParser', js: 'https://cdn.jsdelivr.net/npm/ua-parser-js@0.7.20/dist/ua-parser.min.js', css: '' }, - { name: 'js-cookie', library: 'Cookies', js: 'https://cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js', css: '' }, - { name: 'nprogress', library: 'NProgress', js: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js', css: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.css' }, - { name: 'dayjs', library: 'dayjs', js: 'https://cdn.jsdelivr.net/npm/dayjs@1.8.17/dayjs.min.js', css: '' }, - { name: 'fuse.js', library: 'Fuse', js: 'https://cdn.jsdelivr.net/npm/fuse.js@5.2.3/dist/fuse.min.js', css: '' }, - { name: 'hotkeys-js', library: 'hotkeys', js: 'https://cdn.jsdelivr.net/npm/hotkeys-js@3.7.3/dist/hotkeys.min.js', css: '' }, - { name: 'lowdb', library: 'low', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/low.min.js', css: '' }, - { name: 'lowdb/adapters/LocalStorage', library: 'LocalStorage', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/LocalStorage.min.js', css: '' }, - { name: 'screenfull', library: 'screenfull', js: 'https://cdn.jsdelivr.net/npm/screenfull@5.0.2/dist/screenfull.min.js', css: '' }, - { name: 'sortablejs', library: 'Sortable', js: 'https://cdn.jsdelivr.net/npm/sortablejs@1.10.1/Sortable.min.js', css: '' }, - { name: '@d2-projects/vue-table-export', library: 'VueTableExport', js: 'https://cdn.jsdelivr.net/npm/@d2-projects/vue-table-export@1.0.1/dist/vue-table-export.js', css: '' }, - { name: '@d2-projects/vue-table-import', library: 'VueTableImport', js: 'https://cdn.jsdelivr.net/npm/@d2-projects/vue-table-import@1.0.0/dist/vue-table-import.js', css: '' }, - { name: 'vue-grid-layout', library: 'VueGridLayout', js: 'https://cdn.jsdelivr.net/npm/vue-grid-layout@2.3.7/dist/vue-grid-layout.umd.min.js', css: '' }, - { name: 'quill', library: 'Quill', js: 'https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.min.js', css: '' }, - { name: 'simplemde', library: 'SimpleMDE', js: 'https://cdn.jsdelivr.net/npm/simplemde@1.11.2/dist/simplemde.min.js', css: 'https://cdn.jsdelivr.net/npm/simplemde@1.11.2/dist/simplemde.min.css' }, - { name: 'vue-json-tree-view', library: 'TreeView', js: 'https://cdn.jsdelivr.net/npm/vue-json-tree-view@2.1.4/dist/vue-json-tree-view.min.js', css: '' } -] diff --git a/package-lock.json b/package-lock.json index 776dde465..6da2d5a60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "d2-admin", - "version": "1.21.0", + "version": "1.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1032,7 +1032,6 @@ "version": "7.12.5", "resolved": "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.12.5.tgz?cache=0&sync_timestamp=1604441331796&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.12.5.tgz", "integrity": "sha1-QQ5+SHRB4bNgwpvnFdhw2bmFiC4=", - "dev": true, "requires": { "regenerator-runtime": "^0.13.4" }, @@ -1040,8 +1039,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz", - "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=", - "dev": true + "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=" } } }, @@ -1772,6 +1770,11 @@ "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", "dev": true }, + "@popperjs/core": { + "version": "2.5.4", + "resolved": "https://registry.npm.taobao.org/@popperjs/core/download/@popperjs/core-2.5.4.tgz", + "integrity": "sha1-3iW12p9yeYWjdX/Vm10Cirp1hBo=" + }, "@soda/friendly-errors-webpack-plugin": { "version": "1.7.1", "resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz", @@ -2220,11 +2223,23 @@ "integrity": "sha1-yz+fdBhp4gzOMw/765JxWQSDiC0=", "dev": true }, + "@vant/icons": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/@vant/icons/download/@vant/icons-1.4.0.tgz", + "integrity": "sha1-qR94lPLzQ1b3il1vi51PGkat0MU=" + }, + "@vant/popperjs": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/@vant/popperjs/download/@vant/popperjs-1.0.0.tgz", + "integrity": "sha1-LWarS44nXJj7gvXv1D/dR5ZNEfI=", + "requires": { + "@popperjs/core": "^2.5.4" + } + }, "@vue/babel-helper-vue-jsx-merge-props": { "version": "1.2.1", "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.2.1.tgz?cache=0&sync_timestamp=1602851211699&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-helper-vue-jsx-merge-props%2Fdownload%2F%40vue%2Fbabel-helper-vue-jsx-merge-props-1.2.1.tgz", - "integrity": "sha1-MWJKelBfsU2h1YAjclpMXycOaoE=", - "dev": true + "integrity": "sha1-MWJKelBfsU2h1YAjclpMXycOaoE=" }, "@vue/babel-helper-vue-transform-on": { "version": "1.0.0-rc.2", @@ -3673,6 +3688,16 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-import": { + "version": "1.13.3", + "resolved": "https://registry.npm.taobao.org/babel-plugin-import/download/babel-plugin-import-1.13.3.tgz?cache=0&sync_timestamp=1606209853373&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-import%2Fdownload%2Fbabel-plugin-import-1.13.3.tgz", + "integrity": "sha1-nbu6fRrHK9QSkXqDDUReAJQdJtc=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/runtime": "^7.0.0" + } + }, "babel-plugin-istanbul": { "version": "5.2.0", "resolved": "https://registry.npm.taobao.org/babel-plugin-istanbul/download/babel-plugin-istanbul-5.2.0.tgz", @@ -10555,6 +10580,12 @@ "integrity": "sha1-p5yezIbuHOP6YgbRIWxQHxR/wH4=", "dev": true }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npm.taobao.org/klona/download/klona-2.0.4.tgz", + "integrity": "sha1-e7Hjr/sMuGJFR+9+j2cI6i4538A=", + "dev": true + }, "launch-editor": { "version": "2.2.1", "resolved": "https://registry.npm.taobao.org/launch-editor/download/launch-editor-2.2.1.tgz", @@ -10580,6 +10611,82 @@ "integrity": "sha1-W4o6d2Xf4AEmHd6RVYnngvjJTR4=", "dev": true }, + "less": { + "version": "3.12.2", + "resolved": "https://registry.npm.taobao.org/less/download/less-3.12.2.tgz?cache=0&sync_timestamp=1601389128401&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fless%2Fdownload%2Fless-3.12.2.tgz", + "integrity": "sha1-FX5t0ypohp34hZMUrTjnAhGvOrQ=", + "dev": true, + "requires": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "native-request": "^1.0.5", + "source-map": "~0.6.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1590596728112&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true, + "optional": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true, + "optional": true + } + } + }, + "less-loader": { + "version": "7.1.0", + "resolved": "https://registry.npm.taobao.org/less-loader/download/less-loader-7.1.0.tgz?cache=0&sync_timestamp=1605095927771&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fless-loader%2Fdownload%2Fless-loader-7.1.0.tgz", + "integrity": "sha1-lY1B6G194Ly0kHEe4PI1qp3Flqo=", + "dev": true, + "requires": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz", + "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz", + "integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-3.0.0.tgz?cache=0&sync_timestamp=1601922251376&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-3.0.0.tgz", + "integrity": "sha1-Z1AvaqK2ai1AMrQnmilEl4oJE+8=", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npm.taobao.org/leven/download/leven-3.1.0.tgz", @@ -11262,6 +11369,13 @@ "to-regex": "^3.0.1" } }, + "native-request": { + "version": "1.0.8", + "resolved": "https://registry.npm.taobao.org/native-request/download/native-request-1.0.8.tgz?cache=0&sync_timestamp=1603410586468&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnative-request%2Fdownload%2Fnative-request-1.0.8.tgz", + "integrity": "sha1-j2a/YG4PfqJ8DlmV6y9dA+M65vs=", + "dev": true, + "optional": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz", @@ -15678,6 +15792,18 @@ "spdx-expression-parse": "^3.0.0" } }, + "vant": { + "version": "2.11.1", + "resolved": "https://registry.npm.taobao.org/vant/download/vant-2.11.1.tgz", + "integrity": "sha1-5x4SHJUXcM5BLRcqqN82K+8fubw=", + "requires": { + "@babel/runtime": "7.x", + "@vant/icons": "1.4.0", + "@vant/popperjs": "^1.0.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", + "vue-lazyload": "1.2.3" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", @@ -15867,6 +15993,11 @@ "vue": "^2.5.16" } }, + "vue-lazyload": { + "version": "1.2.3", + "resolved": "https://registry.npm.taobao.org/vue-lazyload/download/vue-lazyload-1.2.3.tgz", + "integrity": "sha1-kB+ewVx+bKeHgaK65KNDaGve2yw=" + }, "vue-loader": { "version": "15.9.5", "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.9.5.tgz?cache=0&sync_timestamp=1604764703761&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.5.tgz", diff --git a/package.json b/package.json index da937dd70..7fc0b579b 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "simplemde": "^1.11.2", "sortablejs": "^1.10.1", "ua-parser-js": "^0.7.20", + "vant": "^2.11.1", "vue": "^2.6.11", "vue-grid-layout": "^2.3.7", "vue-i18n": "^8.15.1", @@ -59,6 +60,7 @@ "@vue/eslint-config-standard": "^5.1.2", "@vue/test-utils": "^1.0.2", "babel-eslint": "^10.0.3", + "babel-plugin-import": "^1.13.3", "compression-webpack-plugin": "^3.0.1", "cz-conventional-changelog": "^3.2.0", "eslint": "^6.8.0", @@ -67,6 +69,8 @@ "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", "eslint-plugin-vue": "^6.2.2", + "less": "^3.12.2", + "less-loader": "^7.1.0", "sass": "^1.23.7", "sass-loader": "^8.0.0", "svg-sprite-loader": "^4.1.6", diff --git a/public/index.html b/public/index.html index d03f160d6..be933d1dc 100644 --- a/public/index.html +++ b/public/index.html @@ -7,13 +7,8 @@ <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %> - <% } %> - - <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> - - <% } %> <%= VUE_APP_TITLE %> + + + +
+ + <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> + + <% } %> + + diff --git a/src.mobile/App.vue b/src.mobile/App.vue new file mode 100644 index 000000000..7de07d67a --- /dev/null +++ b/src.mobile/App.vue @@ -0,0 +1,5 @@ + diff --git a/src.mobile/main.js b/src.mobile/main.js new file mode 100644 index 000000000..cf39ad1c3 --- /dev/null +++ b/src.mobile/main.js @@ -0,0 +1,15 @@ +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store' + +import 'flex.css' +import './vant' + +Vue.config.productionTip = false + +new Vue({ + router, + store, + render: h => h(App) +}).$mount('#app') diff --git a/src.mobile/router/index.js b/src.mobile/router/index.js new file mode 100644 index 000000000..e6d0e216a --- /dev/null +++ b/src.mobile/router/index.js @@ -0,0 +1,18 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/', + name: 'index', + component: () => import('../views/index.vue') + } +] + +const router = new VueRouter({ + routes +}) + +export default router diff --git a/src.mobile/store/index.js b/src.mobile/store/index.js new file mode 100644 index 000000000..332b91692 --- /dev/null +++ b/src.mobile/store/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +Vue.use(Vuex) + +export default new Vuex.Store({ + state: { + }, + mutations: { + }, + actions: { + }, + modules: { + } +}) diff --git a/src.mobile/vant.js b/src.mobile/vant.js new file mode 100644 index 000000000..76eeea2dc --- /dev/null +++ b/src.mobile/vant.js @@ -0,0 +1,7 @@ +import Vue from 'vue' + +import { + Button +} from 'vant' + +Vue.use(Button) diff --git a/src.mobile/views/index.vue b/src.mobile/views/index.vue new file mode 100644 index 000000000..60bcde9e5 --- /dev/null +++ b/src.mobile/views/index.vue @@ -0,0 +1,7 @@ + diff --git a/vue.config.js b/vue.config.js index f9fb3584b..f95b6173b 100644 --- a/vue.config.js +++ b/vue.config.js @@ -2,49 +2,97 @@ const CompressionWebpackPlugin = require('compression-webpack-plugin') const VueFilenameInjector = require('@d2-projects/vue-filename-injector') const ThemeColorReplacer = require('webpack-theme-color-replacer') const forElementUI = require('webpack-theme-color-replacer/forElementUI') -const cdnDependencies = require('./dependencies-cdn') -const { chain, set, each } = require('lodash') +const { set, each, compact, map, keys } = require('lodash') -// 拼接路径 const resolve = dir => require('path').join(__dirname, dir) -// 增加环境变量 +// Add environment variable process.env.VUE_APP_VERSION = require('./package.json').version process.env.VUE_APP_BUILD_TIME = require('dayjs')().format('YYYY-M-D HH:mm:ss') -// 基础路径 注意发布之前要先修改这里 -const publicPath = process.env.VUE_APP_PUBLIC_PATH || '/' - -// 设置不参与构建的库 -const externals = {} -cdnDependencies.forEach(pkg => { externals[pkg.name] = pkg.library }) +// Build configuration for multiple pages +const pages = { + index: { + entry: 'src/main.js', + template: 'public/index.html', + filename: 'index.html', + chunks: [ + 'manifest', + 'index', + 'chunk-index', + 'chunk-vendor', + 'chunk-common', + 'chunk-vue', + 'chunk-element' + ] + }, + mobile: { + entry: 'src.mobile/main.js', + template: 'public/mobile.html', + filename: 'mobile.html', + chunks: [ + 'manifest', + 'mobile', + 'chunk-mobile', + 'chunk-vendor', + 'chunk-common', + 'chunk-vue' + ] + } +} -// 引入文件的 cdn 链接 +// Set up the external dependency package introduced by the method of using CDN +// For example +// if you set the Axios related link configuration here +// Axios will no longer participate in the packaging during the construction. Finally +// the external link you configured will be used to import Axios in the build result const cdn = { - css: cdnDependencies.map(e => e.css).filter(e => e), - js: cdnDependencies.map(e => e.js).filter(e => e) + // Which external dependencies related to index page are introduced in the form of CDN links + index: [ + // { + // name: 'axios', + // library: 'axios', + // js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js', + // css: '' + // } + ], + // Which external dependencies related to mobile page are introduced in the form of CDN links + mobile: [ + // { + // name: 'axios', + // library: 'axios', + // js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js', + // css: '' + // } + ] } -// 多页配置,默认未开启,如需要请参考 https://cli.vuejs.org/zh/config/#pages -const pages = undefined -// const pages = { -// index: './src/main.js', -// subpage: './src/subpage.js' -// } +// Set external dependent packages that do not participate in the build +const externals = {} +keys(pages).forEach(name => { + cdn[name].forEach(p => { + externals[p.name] = p.library + }) +}) module.exports = { - // 根据你的实际情况更改这里 - publicPath, + publicPath: process.env.VUE_APP_PUBLIC_PATH || '/', lintOnSave: true, devServer: { - publicPath, // 和 publicPath 保持一致 - disableHostCheck: process.env.NODE_ENV === 'development' // 关闭 host check,方便使用 ngrok 之类的内网转发工具 + publicPath: process.env.VUE_APP_PUBLIC_PATH || '/', + disableHostCheck: process.env.NODE_ENV === 'development' }, css: { loaderOptions: { - // 设置 scss 公用变量文件 sass: { prependData: '@import \'~@/assets/style/public.scss\';' + }, + less: { + lessOptions: { + modifyVars: { + blue: '#2262AB' + } + } } } }, @@ -66,33 +114,92 @@ module.exports = { } return configNew }, - // 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js + // default: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js chainWebpack: config => { - /** - * 添加 CDN 参数到 htmlWebpackPlugin 配置中 - * 已适配多页 - */ - const htmlPluginNames = chain(pages).keys().map(page => 'html-' + page).value() - const targetHtmlPluginNames = htmlPluginNames.length ? htmlPluginNames : ['html'] - each(targetHtmlPluginNames, name => { - config.plugin(name).tap(options => { - set(options, '[0].cdn', process.env.NODE_ENV === 'production' ? cdn : []) + config.optimization.runtimeChunk({ + name: 'manifest' + }) + config.optimization.splitChunks({ + cacheGroups: { + // External dependencies common to all pages + libs: { + name: 'chunk-vendor', + chunks: 'initial', + minChunks: 1, + test: /[\\/]node_modules[\\/]/, + priority: 1, + reuseExistingChunk: true, + enforce: true + }, + // Code common to all pages + common: { + name: 'chunk-common', + chunks: 'initial', + minChunks: 2, + maxInitialRequests: 5, + minSize: 0, + priority: 2, + reuseExistingChunk: true, + enforce: true + }, + // External dependencies that are only used by the index page + index: { + name: 'chunk-index', + chunks: 'all', + minChunks: 1, + test: /[\\/]node_modules[\\/](sortablejs|screenfull|nprogress|hotkeys-js|fuse\.js|better-scroll|lowdb|shortid)[\\/]/, + priority: 3, + reuseExistingChunk: true, + enforce: true + }, + // External dependencies that are only used by the mobile page + mobile: { + name: 'chunk-mobile', + chunks: 'all', + minChunks: 1, + test: /[\\/]node_modules[\\/](vant)[\\/]/, + priority: 3, + reuseExistingChunk: true, + enforce: true + }, + // Vue family packages + vue: { + name: 'chunk-vue', + test: /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/, + chunks: 'all', + priority: 3, + reuseExistingChunk: true, + enforce: true + }, + // only element-ui + element: { + name: 'chunk-element', + test: /[\\/]node_modules[\\/]element-ui[\\/]/, + chunks: 'all', + priority: 3, + reuseExistingChunk: true, + enforce: true + } + } + }) + // Add the CDN settings to the settings of the htmlwebpackplugin plug-in + keys(pages).forEach(name => { + const packages = cdn[name] + config.plugin(`html-${name}`).tap(options => { + const setting = { + css: compact(map(packages, 'css')), + js: compact(map(packages, 'js')) + } + set(options, '[0].cdn', process.env.NODE_ENV === 'production' ? setting : []) return options }) }) - - /** - * 删除懒加载模块的 prefetch preload,降低带宽压力 - * https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch - * https://cli.vuejs.org/zh/guide/html-and-static-assets.html#preload - * 而且预渲染时生成的 prefetch 标签是 modern 版本的,低版本浏览器是不需要的 - */ - config.plugins - .delete('prefetch') - .delete('preload') - // 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559 - config.resolve - .symlinks(true) + // Remove prefetch preload settings for lazy load modules + each(keys(pages), name => { + config.plugins.delete(`prefetch-${name}`) + config.plugins.delete(`preload-${name}`) + }) + // webpack-theme-color-replacer config .plugin('theme-color-replacer') .use(ThemeColorReplacer, [{ @@ -104,11 +211,11 @@ module.exports = { changeSelector: forElementUI.changeSelector }]) config - // 开发环境 sourcemap 不包含列信息 + // The development environment sourcemap does not contain column information .when(process.env.NODE_ENV === 'development', config => config.devtool('cheap-source-map') ) - // 预览环境构建 vue-loader 添加 filename + // Add file name .when( process.env.VUE_APP_SCOURCE_LINK === 'TRUE', config => VueFilenameInjector(config, { @@ -142,15 +249,9 @@ module.exports = { .exclude .add(resolve('src/assets/svg-icons/icons')) .end() - // 重新设置 alias + // set alias config.resolve.alias - .set('@api', resolve('src/api')) - // 分析工具 - if (process.env.npm_config_report) { - config - .plugin('webpack-bundle-analyzer') - .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) - } + .set('@.mobile', resolve('src.mobile')) }, // 不输出 map 文件 productionSourceMap: false,