vue面试题 vue-cli4 脚手架相关配置详解

作者: tww844475003 分类: 前端开发 发布时间: 2021-05-22 20:15

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:

  • 通过 @vue/cli 实现的交互式的项目脚手架。
  • 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。
  • 一个运行时依赖 (@vue/cli-service),该依赖:
    • 可升级;
    • 基于 webpack 构建,并带有合理的默认配置;
    • 可以通过项目内的配置文件进行配置;
    • 可以通过插件进行扩展。
  • 一个丰富的官方插件集合,集成了前端生态中最好的工具。
  • 一套完全图形化的创建和管理 Vue.js 项目的用户界面。

在 vue 技术面试过程中也是必问问题,下面我们来一起学习 vue-cli 脚手架在构建 vue 项目的一些常用配置

配置多环境变量

通过在 package.json 里的 scripts 配置项中添加–mode xxx 来选择不同环境只有以 VUE_APP 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中,代码中可以通过 process.env.VUE_APP_API 访问NODE_ENV 和 BASE_URL 是两个特殊变量,在代码中始终可用配置在项目根目录中新建.env, .env.dev, .env.prod 等文件

.env、.env.dev、.env.prod .env.local【local 只作用于联调】

serve 默认的本地开发环境配置

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

配置 proxy 代理解决跨域问题

module.exports = {
  devServer: {
    proxy: {
      '/apis': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  },
}

修复 HMR(热更新)失效

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

修复 Lazy loading routes Error: Cyclic dependency

module.exports = {
  chainWebpack: config => {
    // vue-cli-service build js和css加载顺序反了 #1978
    // 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中
    config.plugin("html").tap(args => {
      // 修复 Lazy loading routes Error
      args[0].chunksSortMode = "none";
      return args;
    });
  }
};

添加别名 alias

const path = require("path");

const resolve = dir => path.join(__dirname, dir);

module.exports = {
  chainWebpack: config => {
    // 添加别名
    config.resolve.alias
      .set('@', resolve('src'))
      .set('@components', resolve('src/components'))
      .set('@views', resolve('src/views'))
      .set('@router', resolve('src/router'))
      .set('@store', resolve('src/store'))
      .set('@static', resolve('src/static'));
  }
}

压缩图片

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

module.exports = {
  chainWebpack: config => {
    if (IS_PROD) {
      config.module
        .rule('images')
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options({
          mozjpeg: {
            progressive: true,
            quality: 65
          },
          optipng: {
            enabled: false
          },
          pngquant: {
            quality: [0.65, 0.9],
            speed: 4
          },
          gifsicle: {
            interlaced: false
          }
        })
    }
  }
}

开启Gzip压缩

const isProduction = process.env.NODE_ENV !== 'development'; // 是否为生产环境
const CompressionWebpackPlugin = require('compression-webpack-plugin'); // gzip压缩

module.exports = {
  productionSourceMap: true,
  configureWebpack: config => {
    // 生产环境相关配置
    if (isProduction) {
      // gzip压缩
      const productionGzipExtensions = ['html', 'js', 'css'];
      config.plugins.push(
        new CompressionWebpackPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')

),
          threshold: 10240, // 只有大小大于该值的资源会被处理 10240
          minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
          deleteOriginalAssets: false, // 删除原文件
        })
      )
    }
  }
}

开启CDN加速

const isProduction = process.env.NODE_ENV !== 'development'; // 是否为生产环境
const devNeedCdn = false; // 本地环境是否需要使用cdn

// cdn链接
const cdn = {
  externals: {
    vue: 'Vue',
    vuex: 'Vuex',
    'vue-router': 'VueRouter',
    'marked': 'marked',
    'highlight.js': 'hljs',
    'nprogress': 'NProgress',
    'axios': 'axios'
  },
  css: [
    'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css'
  ],
  js: [
    'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
    'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
    'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',
    'https://cdn.bootcss.com/marked/0.8.0/marked.min.js',
    'https://cdn.bootcss.com/highlight.js/9.18.1/highlight.min.js',
    'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js',
    'https://cdn.bootcss.com/axios/0.19.2/axios.min.js'
  ]
};

module.exports = {
  chainWebpack: config => {
    config.plugin('html').tap(args => {
      // 生产环境或本地需要cdn时,才注入cdn
      if (isProduction || devNeedCdn) args[0].cdn = cdn;
      return args;
    })
  },
  configureWebpack: config => {
    // 用cdn方式引入,则构建时需要忽略相关资源
    if (isProduction || devNeedCdn) config.externals = cdn.externals;
  }
}

删除console.log

// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  configureWebpack: config => {
    config.plugins.push(
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: {
            drop_debugger: true,
            drop_console: true,
            pure_funcs: ['console.log']
          }
        },
        sourceMap: false,
        parallel: true
      })
    )
  }
}

前端开发那点事
微信公众号搜索“前端开发那点事”

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注