5 模式和环境变量 – Vue CLI

1 三种模式

  • development 模式用于 vue-cli-service serve
  • test 模式用于 vue-cli-service test:unit
  • production 模式用于 vue-cli-service build 和 vue-cli-service test:e2e

当运行 vue-cli-service 命令时,所有的环境变量都从对应的环境文件中载入。如果文件内部不包含 NODE_ENV 变量,它的值将取决于模式,例如,在 production 模式下被设置为 “production”,在 test 模式下被设置为 “test”,默认则是 “development”。

如果你想要在构建命令中使用开发环境变量,需要使用–mode参数,例如:

vue-cli-service build --mode development

2 环境变量

在项目根目录中新建下列文件来指定环境变量文件

.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

环境文件的内容格式只允许包含环境变量的“键=值”对,例如:

// .env.dev
VUE_APP_ENV=dev
NODE_ENV=development
# 默认base地址
VUE_APP_API_BASE=https://api-xxx.com

3 在客户端侧代码中使用环境变量

在环境文件中,以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在项目的代码中这样访问它们:

console.log(process.env.VUE_APP_SECRET)

除了 VUE_APP_* 变量之外,在你的应用代码中始终可用的还有两个特殊的变量:

NODE_ENV - 会是 "development"、"production" 或 "test" 中的一个。具体的值取决于应用运行的模式。
BASE_URL - 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。

所有解析出来的环境变量都可以在 public/index.html 中以 HTML 插值中介绍的方式使用。

在 vue.config.js 文件中计算环境变量。它们仍然需要以 VUE_APP_ 前缀开头。这可以用于版本信息:

// vue.config.js
process.env.VUE_APP_VERSION = require('./package.json').version

module.exports = {
  // config
}

4 只在本地有效的变量

.local结尾的本地环境文件默认会被忽略,且出现在 .gitignore 中。比如 .env.development.local 将会在 development 模式下被载入,且被 git 忽略。

4. webpack 相关 – Vue CLI

1 简单的配置方式

在 vue.config.js 中的 configureWebpack 选项提供一个对象,该对象将会被 webpack-merge 合并入最终的 webpack 配置。

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      new MyAwesomeWebpackPlugin()
    ]
  }
}

2 链式操作 (高级)

审查项目的 webpack 配置可以通过命令保存到output.js内查看

vue inspect > output.js

3 修改 Loader 选项

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
        .tap(options => {
          // 修改它的选项...
          return options
        })
  }
}

4 添加一个新的 Loader

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // GraphQL Loader
    config.module
      .rule('graphql')
      .test(/\.graphql$/)
      .use('graphql-tag/loader')
        .loader('graphql-tag/loader')
        .end()
      // 你还可以再添加一个 loader
      .use('other-loader')
        .loader('other-loader')
        .end()
  }
}

5 修改插件选项

比方说你想要将 index.html 默认的路径从 /Users/username/proj/public/index.html 改为 /Users/username/proj/app/templates/index.html。

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        return [/* 传递给 html-webpack-plugin's 构造函数的新参数 */]
      })
  }
}

3. css相关 – Vue CLI

1 引用静态资源

所有编译后的 CSS 都会通过 css-loader 来解析其中的 url()来进行引用,如果你想要引用一个 npm 依赖中的文件,或是想要用 webpack alias,则需要在路径前加上 ~

2 预处理器

如果创建项目时没有选择预处理器 (Sass/Less/Stylus),可以手动安装相应的 webpack loader,例如:

npm install -D sass-loader sass

3 自动化导入

通常一个项目中我们会有一些公共的css文件来定义颜色,mixin等等,例如variable.sass里面定义了一些字号、颜色等等。每次我们在页面中要使用这些公共的变量时都需要先把variable.sassimport进来,有点麻烦。你可以使用 style-resources-loader来完成自动导入,来避免手动操作。配置方法如下:

// vue.config.js
const path = require('path')

module.exports = {
  chainWebpack: config => {
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
    types.forEach(type => addStyleResource(config.module.rule('scss').oneOf(type)))
  },
}

function addStyleResource (rule) {
  rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, './src/styles/variable.sass'),
      ],
    })
}

4 PostCSS

通过 vue.config.js 中的 css.loaderOptions.postcss 配置 postcss-loader。项目默认开启了 autoprefixer。如果要配置目标浏览器,可使用 package.json 的 browserslist 字段。

2. HTML 和静态资源 – Vue CLI

浏览器兼容性

package.json 文件里的 browserslist 字段 (或一个单独的 .browserslistrc 文件),指定了项目的目标浏览器的范围。这个值会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。

Polyfill

翻译为一块代码或插件,可以让旧浏览器兼容新语法,默认情况会根据browserslist 配置来决定项目需要的 polyfill

现代模式

为了兼容老浏览器,经过babel编译后的代码十分臃肿,而最新版本的浏览器已经支持了es6,所以你需要一个现代版的包,用下面的命令
vue-cli-service build --modern

 

HTML

public/index.html 文件是一个会被 html-webpack-plugin 处理的模板。在构建过程中,资源链接会被自动注入。所有客户端环境变量也可以直接使用。例如,BASE_URL 的用法:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

 

Preload

预先加载,<link rel=”preload”> 是一种 resource hint,可以指定一些资源在页面渲染完成之前提前加载,这些提示会被 @vue/preload-webpack-plugin 注入

Prefetch

也是一种 resource hint,页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。
可以通过 chainWebpack 的 config.plugin(‘prefetch’) 进行修改和删除。

多页应用

Vue CLI 支持使用 vue.config.js 中的 pages 选项构建一个多页面的应用。例如:
pages: {
    admin: {
      entry: 'src/client.js',
      template: 'public/client.html',
      filename: 'client.html'
    },
    index: {
      entry: 'src/main.js',
      template: 'public/index.html',
      filename: 'index.html'
    }
  },

 

处理静态资源

放置在 public 目录下或通过绝对路径被引用的文件,将会直接被拷贝,而不会经过 webpack 的处理。

模块加载限制

所有 <img src=”…”>、background: url(…) 和 CSS @import 的资源 URL 都会被解析为一个模块依赖。
所以,url(./image.png) 会被翻译为 require(‘./image.png’),假设一个页面有100张图片,文件大小不一,为了减少请求数,我们可以设置一个值来决定小于这个值的文件都会放到一起请求。代码如下:
// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('images')
        .use('url-loader')
          .loader('url-loader')
          .tap(options => Object.assign(options, { limit: 10240 }))
  }
}

 

url转换规则

如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析。这意味着你甚至可以引用 Node 模块中的资源

public 文件夹

任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径BASE_URL来引用它们。
在模板中使用base_url
<img :src="`${publicPath}my-image.png`">
...
data () {
  return {
    publicPath: process.env.BASE_URL
  }
}

 

1. 基础 – Vue CLI

安装

npm install -g @vue/cli

 

升级

npm update -g @vue/cli

 

安装快速原型开发

npm install -g @vue/cli-service-global

 

使用快速原型开发

vue serve vue build

 

创建一个项目

vue create test

 

在现有的项目安装插件

vue add eslint

 

Preset

如果是手动创建的项目,可以使用Preset保存设置,便于下次创建同样配置的项目
在 vue create 过程中保存的 preset 会被放在你的 home 目录下的一个配置文件中 (~/.vuerc)

vue-cli-service

在一个 Vue CLI 项目中,@vue/cli-service 安装了一个名为 vue-cli-service 的命令,可以使用npx来运行
npx vue-cli-service serve npx vue-cli-service build npx vue-cli-service inspect

 

Git Hook

@vue/cli-service 也会安装 yorkie,它会让你在 package.json 的 gitHooks 字段中方便地指定 Git hook:
{ 
    "gitHooks": { 
        "pre-commit": "lint-staged"
         },
...