sfsoul / personalBlog

思考与总结
MIT License
1 stars 0 forks source link

Vue CLI 官网梳理 #35

Open sfsoul opened 3 years ago

sfsoul commented 3 years ago

HTML和静态资源

HTML

Index 文件

public/index.html 文件是一个会被 html-webpack-plugin 处理的模板。在构建过程中资源链接会被自动注入,此外 Vue CLI 还会自动注入 resource hint(preload/prefetch、mainfest 和图标链接)以及构建过程中处理的 JavaScript 和 CSS 文件的资源链接。

插值

因为 index 文件被用作模板,所以可以使用 lodash template 语法插入内容:

除了被 html-webpack-plugin 暴露的默认值之外,所有客户端环境变量也可以直接使用。

// BASE_URL  用法
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

Preload

<link rel="preload"> 是一种 resource hint,用来指定页面加载后很快会被用到的资源,所以在页面加载的过程中,希望在浏览器开始主体渲染之前尽早 preload。

默认情况下,一个 Vue CLI 应用会为所有初始化渲染需要的文件自动生成 preload 提示。

提示会被 @vue/preload-webpack-plugin 注入,并且可以通过 chainWebpackconfig.plugin('preload') 进行修改和删除。

Prefetch

<link rel="prefetch"> 是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能访问的内容。

默认情况下,一个 Vue CLI 应用会为所有作为 async chunk 生成的 JavaScript 文件(通过动态 import() 按需 code splitting 的产物)自动生成 prefetch 提示。

提示会被 @vue/preload-webpack-plugin 注入,并且可以通过 chainWebpackconfig.plugin('prefetch') 进行修改和删除。

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // 移除 prefetch 插件
    config.plugins.delete('prefetch')

    // 或者
    // 修改它的选项:
    config.plugin('prefetch').tap(options => {
      options[0].fileBlacklist = options[0].fileBlacklist || []
      options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/)
      return options
    })
  }
}

当 prefetch 插件被禁用时,可以通过 webpack 的内联注释手动选定要提前获取的代码区块: import (/* webpackPrefetch: true*/ './someAsyncComponent.vue')

webpack 的运行时会在父级区块被加载之后注入 prefetch 链接。Prefetch 链接将会消耗带宽。若应用很大且有很多 async chunk,而用户主要使用的是对带宽较敏感的移动端,则可能需要关掉 prefetch 链接并手动选择要提前获取的代码区块。

构建一个多页应用

Vue CLI 支持使用 vue.config.js 中的 pages 选项构建一个多页面的应用。构建好的应用将会在不同的入口之间高效共享通用的 chunk 以获得最佳的加载性能。

处理静态资源

静态资源科通过两种方式进行处理:

  • 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。
  • 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。

从相对路径导入

当在 JavaScript、CSS 或 *.vue 文件中使用相对路径(必须以 . 开头)引用一个静态资源时,该资源将会被包含进入 webpack 的依赖图中。在其编译过程中,所有诸如 <img src="...">background: url(...) 和 CSS @import 的资源 URL 都会被解析为一个模块依赖。

如:url(./image.png) 会被翻译为 require('./image.png')

<img src="./image.png">

// 会被编译为
h('img', { attrs: { src: require('./image.png') }})

URL 转换规则

public 文件夹

任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。需要通过绝对路径来引用它们。

推荐奖资源作为模块依赖图的一部分导入,这样它们会通过 webpack 的处理并获得如下好处:

public 目录提供的是一个应急手段,当通过绝对路径引用它时,应留意应用将会部署到哪里?若应用没有部署在域名的根部,则需要为 URL 配置 publicPath 前缀:

sfsoul commented 3 years ago

CSS相关

Vue CLI 项目天生支持 PostCSS、CSS Modules 和包含 Sass、Less、Stylus 在内的预处理器。

引用静态资源

所有编译后的 CSS 都会通过 css-loader 来解析其中的 url() 引用,并将这些引用作为模块请求来处理。意味着可以根据本地的文件结构用相对路径来引用静态资源。若想要引用一个 npm 依赖中的文件,或是想要用 webpack alias,则需要在路径前加上 ~ 的前缀来避免歧义。

// example
.bg {
    /* 若URL以 ~ 开头,它会被作为一个模块请求被解析 */
    background: url('~@assets/images/unveil/short_listed_bg.png') no-repeat center center;
}

自动化导入

通过 style-resources-loader 来在每个单文件组件和 Stylus 文件中导入 ./src/styles/imports.styl 的例子:

// 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('stylus').oneOf(type)))
  },
}

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

CSS Modules

可通过 <style module> 以开箱即用的方式在 *.vue 文件中使用 CSS Modules。

sfsoul commented 3 years ago

webpack 相关

简单的配置方式

调整 webpack 配置最简单的方式就是在 vue.config.js 中的 configureWebpack 选项提供一个对象:

// vue.config.js
module.exports = {
  // 该对象会被 webpack-merge 合并入最终的 webpack 配置
  configureWebpack: {
    plugins: [
      new MyAwesomeWebpackPlugin()
    ]
  }
}

若需要基于环境有条件地配置行为或者想要直接修改配置,就换成一个函数(该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。在函数内可以直接修改配置或返回一个将会被合并的对象。

// vue.config.js
module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      // 为生产环境修改配置...
    } else {
      // 为开发环境修改配置...
    }
  }
}

审查项目的 webpack 配置

vue-cli-service 暴露了 inspect 命令用于审查解析好的 webpack 配置。那个全局的 vue 可执行程序同样提供了 inspect 命令。该命令会将解析出来的 webpack 配置、包括链式访问规则和插件的提示打印到 stdout。

// 将其输出重定向到一个文件以便进行查阅:
vue inspect > output.js

// 指定一个路径来审查配置的一小部分:
vue inspect module.rules.0

// 指向一个规则或插件的名字:
vue inspect --rule vue
vue inspect --plugin html

// 列出所有规则和插件的名字
vue inspect --rules
vue inspect --plugins
sfsoul commented 3 years ago

环境变量和模式

替换项目根目录中的下列文件来指定环境变量:

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

一个环境文件只包含环境变量的 "键=值" 对:

FOO=bar
VUE_APP_SECRET=secret
sfsoul commented 3 years ago

构建目标

运行 vue-cli-service build 时,可通过 --target 选项指定不同的构建目标。它运行将相同的源代码根据不同的用例生成不同的构建。

nabs-XM commented 1 year ago

VUE_APP_SECRET是做什么的?咋用呀?大大