經過在package.json裏的scripts配置項中添加--mode xxx來選擇不一樣環境css
在項目根目錄中新建.env, .env.production, .env.analyz等文件html
只有以 VUE_APP_ 開頭的變量會被 webpack.DefinePlugin 靜態嵌入到客戶端側的包中,代碼中能夠經過process.env.VUE_APP_BASE_API訪問vue
NODE_ENV 和 BASE_URL 是兩個特殊變量,在代碼中始終可用webpack
.env serve默認的環境變量ios
NODE_ENV = 'development' VUE_APP_BASE_API = 'https://demo.cn/api' VUE_APP_SRC = 'https://wechat-timg.oss-cn-hangzhou.aliyuncs.com/demo'
.env.production build默認的環境變量git
NODE_ENV = 'production' VUE_APP_BASE_API = 'https://demo.com/api' VUE_APP_SRC = 'https://img-wechat.oss-cn-hangzhou.aliyuncs.com/demo'
.env.analyz 用於webpack-bundle-analyzer打包分析github
NODE_ENV = 'production' IS_ANALYZ = 'analyz' VUE_APP_BASE_API = 'https://demo.com/api' VUE_APP_SRC = 'https://img-wechat.oss-cn-hangzhou.aliyuncs.com/demo'
修改package.jsonweb
"scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "analyz": "vue-cli-service build --mode analyz", "lint": "vue-cli-service lint" }
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV); module.exports = { baseUrl: './', // 默認'/',部署應用包時的基本 URL outputDir: process.env.outputDir || 'dist', // 'dist', 生產環境構建文件的目錄 assetsDir: '', // 相對於outputDir的靜態資源(js、css、img、fonts)目錄 lintOnSave: false, runtimeCompiler: true, // 是否使用包含運行時編譯器的 Vue 構建版本 productionSourceMap: false, // 生產環境的 source map parallel: require('os').cpus().length > 1, pwa: {} };
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV); module.exports = { devServer: { // overlay: { // warnings: true, // errors: true // }, open: IS_PROD, host: '0.0.0.0', port: 8000, https: false, hotOnly: false, proxy: { '/api': { target: process.env.VUE_APP_BASE_API || 'http://127.0.0.1:8080', changeOrigin: true } } } }
module.exports = { chainWebpack: config => { // 修復HMR config.resolve.symlinks(true); } }
const path = require('path'); const resolve = (dir) => path.join(__dirname, dir); const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV); module.exports = { chainWebpack: config => { // 添加別名 config.resolve.alias .set('@', resolve('src')) .set('assets', resolve('src/assets')) .set('components', resolve('src/components')) .set('layout', resolve('src/layout')) .set('base', resolve('src/base')) .set('static', resolve('src/static')); } }
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { chainWebpack: config => { // 打包分析 if (process.env.IS_ANALYZ) { config.plugin('webpack-report') .use(BundleAnalyzerPlugin, [{ analyzerMode: 'static', }]); } } }
防止將某些 import 的包(package)打包到 bundle 中,而是在運行時(runtime)再去從外部獲取這些擴展依賴vue-router
module.exports = { configureWebpack: config => { config.externals = { 'vue': 'Vue', 'element-ui': 'ELEMENT', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios' } } }
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { configureWebpack: config => { if (IS_PROD) { const plugins = []; plugins.push( new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_console: true, drop_debugger: false, pure_funcs: ['console.log']//移除console } }, sourceMap: false, parallel: true }) ); config.plugins = [ ...config.plugins, ...plugins ]; } } }
npm i --save-dev babel-plugin-transform-remove-console
在babel.config.js中配置vuex
const plugins = []; if(['production', 'prod'].includes(process.env.NODE_ENV)) { plugins.push("transform-remove-console") } module.exports = { presets: [["@vue/app",{"useBuiltIns": "entry"}]], plugins: plugins };
npm i --save-dev compression-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin'); const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; module.exports = { configureWebpack: config => { if (IS_PROD) { const plugins = []; plugins.push( new CompressionWebpackPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: productionGzipExtensions, threshold: 10240, minRatio: 0.8 }) ); config.plugins = [ ...config.plugins, ...plugins ]; } } }
還能夠開啓比gzip體驗更好的Zopfli壓縮詳見https://webpack.js.org/plugins/compression-webpack-plugin
npm i --save-dev @gfx/zopfli brotli-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin'); const zopfli = require("@gfx/zopfli"); const BrotliPlugin = require("brotli-webpack-plugin"); const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; module.exports = { configureWebpack: config => { if (IS_PROD) { const plugins = []; plugins.push( new CompressionWebpackPlugin({ algorithm(input, compressionOptions, callback) { return zopfli.gzip(input, compressionOptions, callback); }, compressionOptions: { numiterations: 15 }, minRatio: 0.99, test: productionGzipExtensions }) ); plugins.push( new BrotliPlugin({ test: productionGzipExtensions, minRatio: 0.99 }) ); config.plugins = [ ...config.plugins, ...plugins ]; } } }
能夠經過在main.js中Vue.prototype.$src = process.env.VUE_APP_SRC;掛載環境變量中的配置信息,而後在js中使用$src訪問。
css中能夠使用注入sass變量訪問環境變量中的配置信息
module.exports = { css: { modules: false, extract: IS_PROD, sourceMap: false, loaderOptions: { sass: { // 向全局sass樣式傳入共享的全局變量 data: `@import "~assets/scss/variables.scss";$src: "${process.env.VUE_APP_SRC}";` } } } }
在scss中引用
.home { background: url($src + '/images/500.png'); }
npm i --save @babel/polyfill
在main.js中添加
import '@babel/polyfill';
配置babel.config.js
const plugins = []; module.exports = { presets: [["@vue/app",{"useBuiltIns": "entry"}]], plugins: plugins };