Uncover Vue - vue-cli3 comprehensive configuration

Posted by Mistah Roth on Tue, 10 Dec 2019 23:22:25 +0100

vue-cli3-config

Create project

Configure environment variables

   select different environments by adding -- mode xxx to the scripts configuration item in package.json

Create. Env,. Env. Production,. Env.analyz and other files in the root directory of the project

                             

The    node   Env and base   URL are two special variables that are always available in the code

. env serve default environment variable

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 default environment variable

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 for package analysis of webpack bundle analyzer

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'

Modify package.json

"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "analyz": "vue-cli-service build --mode analyz",
  "lint": "vue-cli-service lint"
}

Configure vue.config.js

const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);

module.exports = {
  baseUrl: './', // Default '/', basic URL when deploying application package
  outputDir: process.env.outputDir || 'dist', // 'dist', directory of production environment construction files
  assetsDir: '',  // Directory of static resources (js, css, img, fonts) relative to outputDir
  lintOnSave: false,
  runtimeCompiler: true, // Whether to use a Vue build with a runtime compiler
  productionSourceMap: false,  // source map of production environment
  parallel: require('os').cpus().length > 1,
  pwa: {}
};

Configure proxy cross domain

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
          }
        }
    }
}

Repair HMR failure

module.exports = {
    chainWebpack: config => {
        // Repair HMR
        config.resolve.symlinks(true);
    }
}

add alias

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 => {
        // add alias
        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'));
    }
}

Add package analysis

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
    chainWebpack: config => {
        // Packaged Analytics
        if (process.env.IS_ANALYZ) {
          config.plugin('webpack-report')
            .use(BundleAnalyzerPlugin, [{
              analyzerMode: 'static',
            }]);
        }
    }
}

Configure externals

                        


module.exports = {
    configureWebpack: config => {
        config.externals = {
          'vue': 'Vue',
          'element-ui': 'ELEMENT',
          'vue-router': 'VueRouter',
          'vuex': 'Vuex',
          'axios': 'axios'
        }
    }
}

Remove console.log

Method 1:
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']//Remove console
                        }
                    },
                    sourceMap: false,
                    parallel: true
                })
            );
            config.plugins = [
                ...config.plugins,
                ...plugins
            ];
        }
    }
}
Method 2: use Babel plugin transform remove console plug-in
npm i --save-dev babel-plugin-transform-remove-console

Configure in babel.config.js

const plugins = [];
if(['production', 'prod'].includes(process.env.NODE_ENV)) {  
  plugins.push("transform-remove-console")
}

module.exports = {
  presets: [["@vue/app",{"useBuiltIns": "entry"}]],
  plugins: plugins
};

Turn on gzip compression

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
            ];
        }
    }
}

                    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
            ];
        }
    }
}

Provide global styles and global variables for sass

                              .

Configuration information in environment variable can be accessed by injecting sass variable in   css

module.exports = {
    css: {
        modules: false,
        extract: IS_PROD,
        sourceMap: false,
        loaderOptions: {
          sass: {
            // Passing in shared global variables to global sass style
            data: `@import "~assets/scss/variables.scss";$src: "${process.env.VUE_APP_SRC}";`
          }
        }
    }
}

Reference in scss

.home {
    background: url($src + '/images/500.png');
}

Add IE compatibility

npm i --save @babel/polyfill

   add in main.js

import '@babel/polyfill';

Configure babel.config.js

const plugins = [];

module.exports = {
  presets: [["@vue/app",{"useBuiltIns": "entry"}]],
  plugins: plugins
};

Complete configuration

  • Installation dependency
npm i --save-dev compression-webpack-plugin babel-plugin-transform-remove-console  @gfx/zopfli brotli-webpack-plugin
  • package.json
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "analyz": "vue-cli-service build --mode analyz",
    "lint": "vue-cli-service lint"
}
  • babel.config.js
const plugins = [];
// if(['production', 'prod'].includes(process.env.NODE_ENV)) {  
//   plugins.push("transform-remove-console")
// }

module.exports = {
  presets: [["@vue/app",{"useBuiltIns": "entry"}]],
  plugins: plugins
};
  • vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// const zopfli = require("@gfx/zopfli");
// const BrotliPlugin = require("brotli-webpack-plugin");

const path = require('path');
const resolve = (dir) => path.join(__dirname, dir);
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;

module.exports = {
    baseUrl: './', // Default '/', basic URL when deploying application package
    outputDir: process.env.outputDir || 'dist', // 'dist', directory of production environment construction files
    assetsDir: '',  // Directory of static resources (js, css, img, fonts) relative to outputDir
    lintOnSave: false,
    runtimeCompiler: true, // Whether to use a Vue build with a runtime compiler
    productionSourceMap: false,  // source map of production environment

    configureWebpack: config => {
        // config.externals = {
        //     'vue': 'Vue',
        //     'element-ui': 'ELEMENT',
        //     'vue-router': 'VueRouter',
        //     'vuex': 'Vuex',
        //     'axios': 'axios'
        // }

        if (IS_PROD) {
            const plugins = [];
            plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log']//Remove console
                        }
                    },
                    sourceMap: false,
                    parallel: true
                })
            );
            plugins.push(
                new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: productionGzipExtensions,
                    threshold: 10240,
                    minRatio: 0.8
                })
            );
            // Zopfli compression https://webpack.js.org/plugins/compression-webpack-plugin/
            // 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
            ];
        }
    },
    chainWebpack: config => {
        // Repair HMR
        config.resolve.symlinks(true);

        // add alias
        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'));

        // Packaged Analytics
        if (process.env.IS_ANALYZ) {
            config.plugin('webpack-report')
                .use(BundleAnalyzerPlugin, [{
                    analyzerMode: 'static',
                }]);
        }

        // Multi page configuration, adding hash for js
        // config.output.chunkFilename(`js/[name].[chunkhash:8].js`)

        // Modify image output path
        // config.module
        //   .rule('images')
        //   .test(/\.(png|jpe?g|gif|ico)(\?.*)?$/)
        //   .use('url-loader')
        //   .loader('url-loader')
        //   .options({
        //       name: path.join('../assets/', 'img/[name].[ext]')
        //   })
    },
    css: {
        modules: false,
        extract: IS_PROD,
        // Add hash for css suffix
        // extract: {
        //  filename: 'css/[name].[hash:8].css',
        //  chunkFilename: 'css/[name].[hash:8].css'
        //},
        sourceMap: false,
        loaderOptions: {
            sass: {
                // Passing in shared global variables to global sass style
                // data: `@import "~assets/scss/variables.scss";$src: "${process.env.VUE_APP_SRC}";`
                data: `$src: "${process.env.VUE_APP_SRC}";`
            },
            // px to rem
            // postcss: {
            //   plugins: [
            //     require('postcss-pxtorem')({
            //       Rootvalue: 1, / / base of conversion
            //       Selectorsblacklist: ['weui ',' El '], / / ignore transform regular matches
            //       propList   : ['*']
            //     })
            //   ]
            // }
        }
    },
    pluginOptions: {
        // Install the Vue cli plugin style resources loader plug-in
        // Add global style global.scss
        // "style-resources-loader": {
        //   preProcessor: "scss",
        //   patterns: [
        //     resolve(__dirname, "./src/scss/scss/variables.scss")
        //   ]
        // }
    },
    parallel: require('os').cpus().length > 1,
    pwa: {},
    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
            }
        }
    }
};

Uncover vue series

Topics: Javascript Vue Webpack JSON sass