• 注册
  • GitChat讨论 关注:4 内容:10

    vue-cli3.0的配置与优化

  • 查看作者
  • 打赏作者
  • 拉黑名单
    • Vue 作为前端目前三大框架之一,相信大家都不陌生。在国内,由于 Vue 使用简便、学习成本低以及中文资料丰富,深受大量中小型公司的青睐。
      Vue 创建项目是使用 vue-cli,目前 vue-cli 已经出到了 3.0 版本,这版本项目结构相当清晰,而且把大量的配置都封装成 @vue/cli-service 包里面,几乎成为开箱即用的脚手架。
      然而,需求千变万化,不可能每一个项目都能够在 vue-cli 创建项目之后,就马上运用到业务场景,需要对它进行合适的优化以及修改。
      Vue Cli 3.0 新建项目
      用 vue-cli 创建项目,看起来十分简单。安装依赖,运行命令就可以了:
      $ npm install -g @vue/cli

      OR

      $ yarn global add @vue/cli
      $ vue create hello-world

      然而对 vue-cli 配置的优化,就是从这里开始的。首先,我们需要选择自己手动选择配置:

      Vue CLI v3.11.0
      ? Please pick a preset: Manually select features
      ? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
      >(*) Babel
      ( ) TypeScript
      ( ) Progressive Web App (PWA) Support
      ( ) Router
      ( ) Vuex
      ( ) CSS Pre-processors
      (*) Linter / Formatter
      ( ) Unit Testing
      ( ) E2E Testing

      这里需要根据自己的业务需求来选择,我在做项目的时候,基本上必须选择的都是:Babel、Router、Vuex、Linter。其余配置,可以根据自己的需求选择。
      选择完之后,会问你是否使用 History Mode 的路由,其实就是路径上面是否出现 #
      我个人建议,不要选择 History Mode,因为 # 能够帮你避免很多错误的出现。特别是当项目没有前后端分离地十分彻底的情况下,直接跟路由,可能导致跳转到其他页面。
      ? Use history mode for router? (Requires proper server setup for index fallback in production) No

      然后会选择 Linter 并且选择代码风格,我选择的是 ESLint + Standard,然后选择 Lint on save。

      ? Pick a linter / formatter config: Standard
      ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
      >(*) Lint on save
      ( ) Lint and fix on commit
      最后,会问你需要把配置写到单独的文件里面还是写到 package.json 里面,这里选择写到单独文件里面。
      原因是我们需要去调整这些配置,如果写到 package 中,不方便调整。
      ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?
      > In dedicated config files
        In package.json
      回车后,会生成下面的目录结构
      +--- .browserslistrc
      +--- .editorconfig
      +--- .eslintrc.js
      +--- .gitignore
      +--- babel.config.js
      +--- package.json
      +--- postcss.config.js
      +--- public
      |   +--- favicon.ico
      |   +--- index.html
      +--- README.md
      +--- src
      |   +--- App.vue
      |   +--- assets
      |   |   +--- logo.png
      |   +--- components
      |   |   +--- HelloWorld.vue
      |   +--- main.js
      |   +--- router.js
      |   +--- store.js
      |   +--- views
      |   |   +--- About.vue
      |   |   +--- Home.vue
      +--- yarn.lock

      Vue Cli 3.0 配置 vue.config.js

      我们观察一下这里面的目录,发现没有 webpack 的配置,并不是 3.0 版本没有使用 webpack,而是它把 webpack 封装起来了。那么我们怎么用去调整 webpack 配置呢?3.0 版本提供了一个 vue.config.js 的途径。

      publicPath

      PublicPath 是 webpack 中十分重要的一个配置,这个配置决定了生成资源的路径。我会把 publicPath 在 .env 中配置,development 的时候,配置成 ./;production 模式下,配置成生产环境的路径。

      module.exports = {
        publicPath: process.env.PUBLIC_PATH
      }

      chainWebpack 与 configureWebpack

      这两个都可以用来调整 webpack 配置,区别在于 configureWebpack 是简单通过 webpack-merge 对 webpack 进行扩展,而 chainWebpack 则是通过 webpack-chain 插件进行扩展。
      具体用哪一个,其实我觉得都可以,看哪一个方便以及熟悉程度。
      configureWebpack
      configureWebpack 的配置使用正常赋值的形式,往 config 对象中添加或者修改数值即可:

        configureWebpack: config => {
          if (process.env.NODE_ENV === 'production') {
            // 为生产环境修改配置...
            config.mode = 'production'
          } else {
            // 为开发环境修改配置...
            config.mode = 'development'
          }
          Object.assign(config, {
            externals,
            // 开发生产共同配置
            resolve: {
              extensions: ['.js', '.vue', '.json'],
              alias: {
                '@': path.resolve(__dirname, './src')
              }
            }
          })
        },

      chainWebpack
      chainWebpack 的配置则是使用链式操作,通过调用方法来进行扩展:

        chainWebpack: config => {
          config.resolve.symlinks(true)
          config.module
            .rule('vue')
            .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
              options.transformAssetUrls = {
                audio: 'src'
              }
              return options
            })
        },

      alias

      使用别名是 Vue 开发中常用的技巧,如果大家也讨厌每次都要写无数个 ../ 的话,alias 是必备的配置。
      alias: {
        '@': path.resolve(__dirname, './src')
      }
      配置了之后,在 Vue 的模板中,可以使用 @ 进行路径的引用:
      <audio preload="preload" ref="audio" src="@/assets/music.mp3" loop="true" class="hidden"></audio>
      import loading from '@/components/loading'
      注意 scss 中的图片路径,需要使用 ~@
      background: url(~@/assets/index-bg.jpg) no-repeat 0 0/100% 100%;

      CSS

      CSS 配置的是 Sass 或者 Scss 的属性,其中重要的是 loaderOptions,一般用来定义全局引入的 Scss:
        css: {
          // 是否使用css分离插件 ExtractTextPlugin
          extract: true,
          // 开启 CSS source maps?
          sourceMap: false,
          // css预设器配置项
          loaderOptions: {
            sass: {
              data: `@import "~@/scss/resources.scss";`
            }
          },
          // 启用 CSS modules for all css / pre-processor files.
          modules: true
        },

      devServer

      devServe 用来配置 webpack-dev-serve 的属性,可以把 host 配置成 0.0.0.0,这样能够以 localhost 以及电脑 IP 访问项目。

      devServer: {
          host: '0.0.0.0',
          port: 3000,
          https: false,
          disableHostCheck: true
      }

      external

      配置完这些基本东西之后,需要配置 external。这个属性在 webpack 中十分的重要而且常用,是用来定义外部引入的对象,定义了之后 webpack 就不会把这个对象对应的包打包进去项目文件中。
      例如,我们在几个项目中都用到了 Vue,如果不配置 external,每个项目里面都会有 webpack 打包进来的 Vue 包,这样是非浪费服务器资源,而且加载文件大小也相对较大。
      而如果配置了 external,我们就可以每次都加载同一个资源路径的 Vue,webpack 不会把 Vue 打包进去。
      那怎么样去设置 external 呢?

      以加载 Vue 为例,首先我们要在项目中引入 vue.min.js:

      <script type="text/javascript" src=".../vue.min.js"></script>
      然后,我们需要打开这个 vue.min.js,看一下里面暴露的对象是什么:
      /*!
      * Vue.js v2.6.10
      * (c) 2014-2019 Evan You
      * Released under the MIT License.
      */
      !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Vue=t()}(this,function(){"use strict";var e=Object.freeze({});function t(e){return null==e}function n(e){return...
      一般我们打开之后,就看前两行或者最后两行,看到有 e.Vue 或者 module.Vue 之类的,这个 Vue 就是我们要的对象名字了。
      拿到这个对象名称之后,建议在 vue.config.js 的顶部,定义一个 external 对象,来专门负责这些 externals:
      const externals = {
        Swal: 'Swal',
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        axios: 'axios',
        qs: 'Qs',
        Mock: 'Mock',
        TweenMax: 'TweenMax',
        TimelineMax: 'TimelineMax',
        AlloyTouch: 'AlloyTouch',
        Transform: 'Transform',
        html2canvas: 'html2canvas'
      }
      然后在 configureWebpack 中把 external 配置到 webpack 中:
        configureWebpack: config => {
          Object.assign(config, {
            externals,
          })
        },

      Vue Cli 3.0 配置 .env

      在开始配置的时候,一般会先在根目录新建两个文件:.env.development 以及 .env.production。这两个文件的作用是,当我们使用不同的 mode( development 和 production ) 去构建项目的时候,能够用 process.env 来获取对应文件中定义的配置。
      .env.development
      VUE_APP_SERVE=true
      PUBLIC_PATH=./
      VUE_APP_STATIC_PATH=https://www.bootcdn.cn/
      注意一点,如果需要把 .env 里面的变量用到项目中,例如 public 中的 index.html 需要在前面加上 VUE_APP。具体的 .env 配置,可以在官网中的 API 查看。
      使用这个配置文件有几个好处:
      1. 不需要查看具体代码就能方便修改里面的信息

      2. 方便同事或者其他开发人员查看配置详情

      3. 能够很好地区分开发环境与生成环境

      4. 定了文件之后,能够在项目任何地方使用里面定义的变量

      Vue Cli 3.0 配置页面模板

      说完上面的配置之后,其实之前所做的很多工作,都是为了配置页面模板所打下的基础。
      页面模板是指 public 文件夹中的 index.html 文件,这个 index.html 比普通的 HTML 文件功能强大很多。它是一个会被 html-webpack-plugin 处理的模板,能够使用很多模板插值,条件渲染的语法。

      插值

      前面说到我们在 .env 中定义了一些静态资源的路径,这里就能够用上了:
      <script type="text/javascript" src="<%= VUE_APP_STATIC_PATH %>/vue.min.js"></script>
      <script type="text/javascript" src="<%= VUE_APP_STATIC_PATH %>/axios.min.js"></script>
      <script type="text/javascript" src="<%= VUE_APP_STATIC_PATH %>/qs.min.js"></script>
      使用 VUE_APP_ + 所以定义的变量名,就可以拿到对应的 .env 中的值,这样我们就不需要在 index.html 中写上详细的资源地址,只需要写上后缀就行。

      表达式

      除了能够插值之外,另一个常用的就是表达式,可以在页面上面使用 if else。我们可以在 .env 中配置一个属性,用来区分当前的状态是开发中,还是线上。然后对应不同的状态,加载不同的资源:

      <% if (VUE_APP_SERVE === 'false') { %>
      ...
      <% } else { %>
      ...
      <% } %>

      模拟数据

      除了使用简单的插值跟表达式以外,前端开发经常需要处理的是模拟数据的情况。在后端没有给我们足够的数据支持的时候,我们需要自己去模拟数据以便测试我们的功能页面。
      这里我们可以利用 API 工具加上页面模板,来实现模拟数据。
      首先,我们需要找到一款合适的 API 工具,现在有很多开源的文档工具例如:apiDoc、Swagger 和 ShowDoc 等。不过这些都需要团队去学习如何使用,并且需要搭建环境。
      我最终选择了 Postman,Postman 中有一个 Mock 功能,这个功能允许我们做数据模拟。

      vue-cli3.0的配置与优化

      由于后端开发人员几乎都会使用 Postman 来测试自己的接口,所以我们只需要让后端同事导出一份 Postman 的文件,我们导入就有了对应项目的所有接口。
      接下来我们要做的是,新建各种例子,然后在 Mock 的地址中,测试一下是否配置成功:

      vue-cli3.0的配置与优化

      配置好 Postman 之后,我们就可以在页面模板中,把这些接口加入到 Vue 对象里面:
      Vue.prototype.$projectOptions = {
        addUserInfo: '<%= VUE_APP_POSTMAN %>/addUserInfo',
      }
      然后就可以在项目中,用 this.$projectOptions.addUserInfo 来请求 Postman 中我们定义的接口了。
      页面模板中还有很多可以优化的配置,像 Preload 和 Prefetch 等等,这些大家可以根据情况来使用,这里就不一样展开了。

      结尾

      最后给大家一些配置优化的小 Tips:
      • vue-cli 的配置大部分跟 webpack 有关,用好 webpack 就能对 vue-cli 的配置得心应手

      • vue-cli 已经是一个成熟的脚手架了,能够用官网提供的方法解决的情况下,就不用自己去找额外的 Loader 跟插件,避免不必要的麻烦

      • vue-cli 有模板功能,可以把自己配置好的文件弄成模板,下次新建项目的时候,直接用自己的模板 

      请登录之后再进行评论

      登录
    • 帖子间隔 侧栏位置: