vue-cli3出來很久了,之前一直使用vue-cli2的配置,並且區分了生產和開發環境,自己的理解,環境分兩大類,開發環境 和生產環境,最近升級到了vue-cli4當然改動並不大。
升級的主要原因嘛,第一個就是趕趕時髦,二個就是vue-cli2里面使用異步組件的時候,打包出來的都是1.js,2.js這樣子的名字就非常不友好了,根本不知道這是哪個組件。vue-cli3借助更新版的webpack呢,就可以顯示組件名稱了,這樣比較好,
還有一個就是vue-cli3配置起來相對是比較簡單的,在一個文件里面全部搞定了,不用像vue-cli2一樣,好幾個文件要改,那么多文件誰知道誰是誰啊,是吧。
對於命令來說,就是dev和build的區別,
一般都會有預發布和正式生產兩個環境區別
預發布 就使用預發布的接口
正式的就使用正式的接口
對於程序員來說,本地測試也需要測試預發布的接口和生產的接口,上線也需要區分上到預發布或者上到生產
所以根據這些的不同,分成了兩大部分,每一部分都分了預發和正式
具體可以參照下圖
根據這些不同呢,就在package.json中區分了四種情況
然后在項目根目錄下新建4個對應的文件就好
環境變量下最好手動指定一下NOED_ENV,因為開發環境不會壓縮js,而打包之后需要壓縮js
,然后在api中就可以讀取到具體的mode了
vue.config.js中
之前寫的太簡單了,現在需要加上靜態資源cdn引入,這樣可以顯著減小包的體積,下面貼下具體的設置vue.config.js的代碼吧
1 const path = require('path') 2 3 4 // 項目部署路徑的BASE_URL 5 const publicPath = process.env.VUE_APP_PUBLISH_PATH 6 7 // 項目的打包輸出目錄 8 const outputDir = process.env.VUE_APP_OUTPUT_DIR 9 10 const isProduction = process.env.NODE_ENV === 'production'; 11 const cdn = { 12 // 開發環境 13 dev: { 14 css: [], 15 js: [], 16 }, 17 // 生產環境 18 build: { 19 css: [], 20 js: [ 21 "https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js", 22 "https://cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js", 23 "https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js", 24 "https://cdn.jsdelivr.net/npm/vue-lazyload@1.3.3/vue-lazyload.min.js" 25 ], 26 }, 27 }; 28 29 30 // 添加樣式自動化導入 31 const addStyleResourceLoader = webpackConfig => { 32 const fileTypes = ['less', 'sass', 'scss'] 33 const cssModules = ['vue-modules', 'vue', 'normal-modules', 'normal'] 34 const targetRules = fileTypes.reduce((rulesArr, fileType) => rulesArr.concat( 35 cssModules.map(cssModule => webpackConfig.module.rule(fileType).oneOf(cssModule)) 36 ), []) 37 targetRules.forEach(rule => { 38 rule.use('style-resource').loader('style-resources-loader').options({ 39 patterns: [ 40 path.resolve(__dirname, `./src/style/*.${rule.names[0]}`) 41 ] 42 }) 43 }) 44 } 45 46 // 添加包分析工具 47 const addBundleAnalyzer = webpackConfig => { 48 if (process.argv[2] === 'build' && process.env.npm_config_report) { 49 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 50 webpackConfig.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin) 51 } 52 } 53 54 // 優化打包行為 —— 移除打包后的 js.map 文件和 console 輸出 55 // 注意,只能移除默認形式的 console; 無法移除形如 let log = console.log; log(111) 這種形式的輸出 56 const upgradeMinimizer = webpackConfig => { 57 webpackConfig.optimization.minimizer('terser').tap(args => { 58 args[0].terserOptions.compress.drop_console = true; 59 args[0].terserOptions.compress.drop_debugger = true; 60 args[0].terserOptions.compress.pure_funcs = ['console.log'] 61 return args 62 }) 63 } 64 65 module.exports = { 66 lintOnSave: false, // 關閉eslint 67 productionSourceMap: false, // 關閉生產環境的sourcemap 68 publicPath: './', 69 outputDir: process.env.outputDir, // 生成文件的目錄名稱 70 chainWebpack: config => { 71 config.plugin('html').tap((args) => { 72 if (isProduction) { 73 args[0].cdn = cdn.build; 74 } 75 return args; 76 }); 77 addStyleResourceLoader(config) 78 addBundleAnalyzer(config) 79 upgradeMinimizer(config) 80 }, 81 configureWebpack: config => { 82 if (isProduction) { 83 config.externals = { 84 'vue': 'Vue', 85 'vue-router': 'VueRouter', 86 'axios': 'axios' 87 } 88 } 89 } 90 }
下面是index.html的寫法
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="utf-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 8 <link rel="icon" href="<%= BASE_URL %>favicon.ico"> 9 <title><%= htmlWebpackPlugin.options.title %></title> 10 </head> 11 12 <body> 13 <noscript> 14 <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. 15 Please enable it to continue.</strong> 16 </noscript> 17 <div id="app"></div> 18 <!-- built files will be auto injected --> 19 <% for (var i in 20 htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> 21 <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> 22 <% } %> 23 </body> 24 </html>
然后在package.js編寫腳本
1 { 2 "name": "test-cli4", 3 "version": "0.1.0", 4 "private": true, 5 "scripts": { 6 "dev": "vue-cli-service serve --mode development", 7 "dev-prod": "vue-cli-service serve --mode development_prod", 8 "build-dev": "vue-cli-service build --mode production_pre", 9 "build-prod": "vue-cli-service build --mode production" 10 }, 11 "dependencies": { 12 "core-js": "^3.6.4", 13 "vue": "^2.6.11", 14 "vue-router": "^3.1.6" 15 }, 16 "devDependencies": { 17 "@vue/cli-plugin-babel": "~4.3.0", 18 "@vue/cli-plugin-eslint": "~4.3.0", 19 "@vue/cli-plugin-router": "~4.3.0", 20 "@vue/cli-service": "~4.3.0", 21 "@vue/eslint-config-prettier": "^6.0.0", 22 "babel-eslint": "^10.1.0", 23 "eslint": "^6.7.2", 24 "eslint-plugin-prettier": "^3.1.1", 25 "eslint-plugin-vue": "^6.2.2", 26 "node-sass": "^4.12.0", 27 "prettier": "^1.19.1", 28 "sass-loader": "^8.0.2", 29 "style-resources-loader": "^1.3.3", 30 "vue-template-compiler": "^2.6.11" 31 } 32 }
更vue-cli2一樣,如果需要顯示打包之后的分析,直接后面接上 --report即可
好了,大功告成!!!
說個題外話,項目開發經常是cli2和cli3並存的,官方呢,非常貼心的提供了方法讓這兩者共存,官方說法如下,自己實踐了下,還是挺好用的,靠譜
npm install -g @vue/cli-init # `vue init` 的運行效果將會跟 `vue-cli@2.x` 相同 vue init webpack my-project
此時,就可以愉快的開發啦