vue 快速入門 系列 —— vue-cli 上

彭加李發表於2021-08-11

其他章節請看:

vue 快速入門 系列

Vue CLI 4.x 上

vue loader 一文中我們已經學會從零搭建一個簡單的,用於單檔案元件開發的腳手架;本篇,我們將全面學習 vue-cli 這個官方的、成熟的腳手架。

分上下兩篇進行,上篇主要是”基礎“,下篇主要是“開發”

Tip:介紹順序儘可能保持與官方文件一致

介紹

vue-cli 是一個基於 vue.js 進行快速開發的完整系統

讓我們專注在撰寫應用上,而不必花好幾天去糾結配置的問題。

Vue CLI 有幾個獨立的部分:clicli 服務cli 外掛

CLI

CLI (@vue/cli) 是一個全域性安裝的 npm 包,提供了終端裡的 vue 命令。

可以通過 vue create(下文將會詳細介紹) 快速搭建一個新專案。

CLI 服務

CLI 服務 (@vue/cli-service) 是一個開發環境依賴。它是一個 npm 包,區域性安裝在每個 @vue/cli 建立的專案中。

CLI 服務是構建於 webpackwebpack-dev-server 之上的。它包含了:

  • 載入其它 CLI 外掛的核心服務;
  • 一個針對絕大部分應用優化過的內部的 webpack 配置;
  • 專案內部的 vue-cli-service 命令,提供 servebuildinspect 命令。

CLI 外掛

CLI 外掛是向你的 Vue 專案提供可選功能的 npm 包,例如 Babel/TypeScript 轉譯、ESLint 整合、單元測試和 end-to-end 測試等。Vue CLI 外掛的名字以 @vue/cli-plugin- (內建外掛) 或 vue-cli-plugin- (社群外掛) 開頭,非常容易使用。

當你在專案內部執行 vue-cli-service 命令時,它會自動解析並載入 package.json 中列出的所有 CLI 外掛。

外掛可以作為專案建立過程的一部分,或在後期加入到專案中,也可以被歸成一組可複用的預設(preset)。

安裝

全域性安裝 @vue/cli 這個包:

> npm install -g @vue/cli

你可以通過簡單執行 vue,看看是否展示出了一份所有可用命令的幫助資訊,來驗證它是否安裝成功。你還可以用這個命令來檢查其版本是否正確。請看示例:

// 驗證是否安裝成功
> vue 
Usage: vue <command> [options]
Options:
  -h, --help                                 output usage information
...
// 檢視版本
> vue --version
@vue/cli 4.5.13

升級

如需升級全域性的 Vue CLI 包,請執行:

npm update -g @vue/cli

若需升級專案中的 Vue CLI 相關模組(以 @vue/cli-plugin-vue-cli-plugin- 開頭),請在專案目錄下執行 vue upgrade

用法: upgrade [options] [plugin-name]

(試用)升級 Vue CLI 服務及外掛

選項:
  -t, --to <version>    升級 <plugin-name> 到指定的版本
  -f, --from <version>  跳過本地版本檢測,預設外掛是從此處指定的版本升級上來
  -r, --registry <url>  使用指定的 registry 地址安裝依賴
  --all                 升級所有的外掛
  --next                檢查外掛新版本時,包括 alpha/beta/rc 版本在內
  -h, --help            輸出幫助內容

基礎

快速原型開發

你可以使用 vue servevue build 命令對單個 *.vue 檔案進行快速原型開發,不過這需要先額外安裝一個全域性的擴充套件:

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

vue serve 的缺點就是它需要安裝全域性依賴,這使得它在不同機器上的一致性不能得到保證。因此這隻適用於快速原型開發。

vue serve

你所需要的僅僅是一個 App.vue 檔案。

請看示例:

建立目錄 demo,新建 App.vue 檔案:

// demo/App.vue

<template>
  <h1>Hello!</h1>
</template>

然後在這個 App.vue 檔案所在的目錄下執行:

demo> vue serve

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.0.103:8080/

訪問 http://localhost:8080/,頁面顯示 Hello,並有熱模組替換功能。

vue serve 使用了和 vue create 建立的專案相同的預設設定 (webpack、Babel、PostCSS 和 ESLint)。它會在當前目錄自動推匯入口檔案——入口可以是 main.js、index.js、App.vue 或 app.vue 中的一個。

:在此專案中寫 less 提示需要 css-loader,編寫的 postcss 也未生效 color: lch(53 105 40);—— lch 是明天的 css 語法。

vue build

你也可以使用 vue build 將目標檔案構建成一個生產環境的包並用來部署:

demo> vue build

/  Building for production...

  File                                 Size                                                    Gzipped  

  dist\js\chunk-vendors.86166fc4.js    65.95 KiB                                               23.71 KiB
  dist\js\app.6d4e2596.js              1.79 KiB                                                0.89 KiB 

dist 目錄中會生成 index.html,筆者在 dist 目錄下執行靜態檔案伺服器,在開啟的頁面中能看到 Hello!

demo> cd dist

dist> anywhere
Running at http://192.168.85.1:8000/
Also running at https://192.168.85.1:8001/

vue build 也提供了將元件構建成為一個庫或一個 Web Components 元件的能力

建立一個專案

執行以下命令來建立一個新專案:

> vue create vue-hello-world

提示選取一個預設(preset)。

Vue CLI v4.5.13
? Please pick a preset:
  Default ([Vue 2] babel, eslint) // 預設選項 vue2
  Default (Vue 3) ([Vue 3] babel, eslint) // 預設選項 vue3
> Manually select features // 手動選擇

Tip:筆者使用 powershell 終端,可以通過上下鍵來切換選項

預設的設定非常適合快速建立一個新專案的原型,而手動設定則提供了更多的選項,它們是面向生產的專案更加需要的。

如果選擇 default 則會直接建立專案,建立專案包括 babel,eslin 這些工具,而 vue-router,vuex等其他依賴需要自己手動安裝。

由於我們的專案需要 vue-router、vuex,所以就選擇“手動選擇”。

Vue CLI v4.5.13
? Please pick a preset: Manually select features
? Check the features needed for your project: 
 (*) Choose Vue version                   // vue 的版本
 (*) Babel                                // 程式碼編譯
 (*) TypeScript                           // ts
 (*) Progressive Web App (PWA) Support    // 漸進式網頁應用程式    
 (*) Router                               // 路由 - vue router
 (*) Vuex                                 // 狀態管理 - vuex
 (*) CSS Pre-processors                   // css預處理      
 (*) Linter / Formatter                   // 程式碼風格、格式校驗      
 (*) Unit Testing                         // 單元測試
>(*) E2E Testing                          // 端對端測試

Tip:這裡為了演示,所以選擇全部(筆者使用空格鍵來選中或取消)

全部選中後,回車,會依次詢問我們對應特性的一些具體需求,比如 vue 的版本、是否使用class風格的元件語法、路由是否使用 history 模式等等:

Vue CLI v4.5.13
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 2.x
  3.x

選擇 vue 2,回車:

Vue CLI v4.5.13
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 2.x
? Use class-style component syntax? (Y/n)

這裡詢問的是是否使用class風格的元件語法,如果在專案中想要保持使用TypeScript的class風格的話,建議大家選擇 y:

...
? Choose a version of Vue.js that you want to start the project with 2.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) 

將 Babel 與 TypeScript 一起使用,選擇 y:

...
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)   

路由是否使用 history 模式。因為 history 需要額外配置,所以這裡選用 hash,輸入n:

// CSS Pre-processors
...
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with dart-sass)
  Sass/SCSS (with node-sass)
  Less
  Stylus

選擇一種CSS預處理型別,筆者選用 less:

// Linter / Formatter
...
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: (Use arrow keys)
> ESLint with error prevention only   // 只進行報錯提醒           
  ESLint + Airbnb config              // airbnb 模式
  ESLint + Standard config            // 標準模式  
  ESLint + Prettier                   // prettier 模式  
  TSLint (deprecated)                 // 已棄用

選擇 eslint 模式,筆者選標準模式:

...
? 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

選擇校驗時機,一般都會選擇儲存時校驗,好及時做出調整,筆者選第一項:

// Unit Testing
...
? Pick additional lint features: Lint on save   
? Pick a unit testing solution: (Use arrow keys)
> Mocha + Chai
  Jes

選擇單元測試解決方案,普遍用到最多的時Mocha + chai,我們也選第一項。

// E2E Testing E2E(End To End)
...
? Pick a unit testing solution: Mocha
? Pick an E2E testing solution: (Use arrow keys)
> Cypress (Chrome only)
  Nightwatch (WebDriver-based)
  WebdriverIO (WebDriver/DevTools based) 

選擇端對端測試的型別,預設回車:

// 額外選項
...
? Pick an E2E testing solution: Cypress
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files   // 在專用配置檔案中
  In package.json

選擇 Babel, ESLint 等配置存放位置,建議使用第一個(專用配置檔案)

Tip: 如果選用第一項,例如 eslint 的配置就會單獨存放在一個檔案(.eslintrc.js)中;如果選第二項,該配置就會存放在 package.josn 中,而 package.json 是不能寫註釋,而且太多配置都寫入 package.json 也不好維護

? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N)

是否儲存成一個預設給以後專案使用。這裡選 y,然後輸入儲存當前配置項的名稱,例如 presetNameA

? Save this as a preset for future projects? Yes
? Save preset as:

隨後就會建立完畢,並提示通過 npm run serve 啟動服務:

...
�  Generating README.md...

�  Successfully created project vue-hello-world.
�  Get started with the following commands:

 $ cd vue-hello-world
 $ npm run serve
> npm run serve
...
Time: 3055ms

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.0.103:8080/

通過瀏覽器訪問 http://localhost:8080/ 即可訪問專案。

Tip:下次建立專案的時候就會看到剛儲存的預設(presetNameA):

> vue create demo 

Vue CLI v4.5.13
? Please pick a preset: (Use arrow keys)
> presetNameA ([Vue 2] less, babel, typescript, pwa, router, vuex, eslint, unit-mocha, e2e-cypress)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3) ([Vue 3] babel, eslint)
  Manually select features

外掛

Vue CLI 使用了一套基於外掛的架構。如果你查閱一個新建立專案的 package.json,就會發現依賴都是以 @vue/cli-plugin- 開頭的:

// vue-hello-world/package.json
{
  "name": "vue-hello-world",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "register-service-worker": "^1.7.1",
    "vue": "^2.6.11",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^9.1.2",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@types/chai": "^4.2.11",
    "@types/mocha": "^5.2.4",
    "@typescript-eslint/eslint-plugin": "^4.18.0",
    "@typescript-eslint/parser": "^4.18.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-e2e-cypress": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-pwa": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-unit-mocha": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "@vue/eslint-config-typescript": "^7.0.0",
    "@vue/test-utils": "^1.0.3",
    "chai": "^4.1.2",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "typescript": "~4.1.5",
    "vue-template-compiler": "^2.6.11"
  }
}

外掛可以修改 webpack 的內部配置,也可以向 vue-cli-service 注入命令。在專案建立的過程中,絕大部分列出的特性都是通過外掛來實現的。

基於外掛的架構使得 Vue CLI 靈活且可擴充套件。

下面我們將通過一個示例來講解外掛,首先新建專案 demo2(選擇 Default):

// 選則`Default ([Vue 2] babel, eslint)`預設建立
> vue create demo2

Tip: 前面建立的專案(vue-hello-world)是基於 typescript,演示起來不是很方便

vue add

每個 CLI 外掛都會包含一個 (用來建立檔案的) 生成器和一個 (用來調整 webpack 核心配置和注入命令的) 執行時外掛。當你使用 vue create 來建立一個新專案的時候,有些外掛會根據你選擇的特性被預安裝好。如果你想在一個已經被建立好的專案中安裝一個外掛,可以使用 vue add 命令,例如 vue add axios

Tipvue add 的設計意圖是為了安裝和呼叫 Vue CLI 外掛。這不意味著替換掉普通的 npm 包。對於這些普通的 npm 包,你仍然需要選用包管理器。

下面我們通過安裝 axios 來詳細瞭解一下vue add 外掛npm install 包之間的區別:

> npm i axios

安裝完成,專案中只有 package.json 會增加相應的依賴:

"dependencies": {
+    "axios": "^0.21.1",
     "core-js": "^3.6.5",
     "vue": "^2.6.11"
},

將 axios 這個包刪除,再次用 vue add 安裝 axios 外掛:

// 刪除
> npm r axios
> vue add axios

 WARN  There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed?

Tip: 由於會更改檔案,所以會讓你先提交程式碼

> vue add axios

�  Installing vue-cli-plugin-axios...

...

Run `npm audit` for details.
✔  Successfully installed plugin: vue-cli-plugin-axios

告訴我們正在安裝的包是:vue-cli-plugin-axios

安裝完成,通過 git status 就能知道此命令修改的檔案和內容:

demo2> git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   package-lock.json
        modified:   package.json
        modified:   src/main.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        src/plugins/
// package.json

"devDependencies": {
  "axios": "^0.18.0",
  "vue-cli-plugin-axios": "~0.0.4",
},
// main.js

import './plugins/axios'
// src/plugins/axios.js

"use strict";

import Vue from 'vue';
import axios from "axios";

// Full config:  https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

let config = {
  // baseURL: process.env.baseURL || process.env.apiUrl || ""
  // timeout: 60 * 1000, // Timeout
  // withCredentials: true, // Check cross-site Access-Control
};

const _axios = axios.create(config);

_axios.interceptors.request.use(
  function(config) {
    // Do something before request is sent
    return config;
  },
  function(error) {
    // Do something with request error
    return Promise.reject(error);
  }
);

// Add a response interceptor
_axios.interceptors.response.use(
  function(response) {
    // Do something with response data
    return response;
  },
  function(error) {
    // Do something with response error
    return Promise.reject(error);
  }
);

Plugin.install = function(Vue, options) {
  Vue.axios = _axios;
  window.axios = _axios;
  Object.defineProperties(Vue.prototype, {
    axios: {
      get() {
        return _axios;
      }
    },
    $axios: {
      get() {
        return _axios;
      }
    },
  });
};

Vue.use(Plugin)

export default Plugin;

接著啟動服務,eslint 報錯,於是修改 eslint 配置繞過程式碼校驗,再次重啟服務。

// package.json

"extends": [
   "plugin:vue/essential",
-  "eslint:recommended"
],

在任意元件中即可使用 axios,例如在 App.vue 中使用:

<script>
export default {}

console.log(window.axios);
</script>

瀏覽器控制檯會輸出:

ƒ wrap() {
    var args = new Array(arguments.length);
    for (var i = 0; i < args.length; i++) {
      args[i] = arguments[i];
    }
    return fn.apply(thisArg, args);
  }

至此,axios 已經成功引入我們的專案,而且範文也已經就緒。

通過這個示例我們也就明白,vue 提供的這個外掛比 npm 這種方式更友好,比如有範文

vue add vuex
> vue add vuex

�  Installing @vue/cli-plugin-vuex...
...

安裝 axios 對應的包是 vue-cli-plugin-axios,以 vue-cli-plugin- 開頭,屬於第三方外掛

而 vuex 對應的包是 @vue/cli-plugin-vuex,以 @vue/cli-plugin- 開頭。

使用 GUI 安裝和管理外掛

我們通過 vue ui 命令使用 GUI 安裝和管理外掛。由於前面我們已經全域性安裝,所以在任意目錄下執行即可:

> vue ui
�  Starting GUI...
�  Ready on http://localhost:8001

瀏覽器自動開啟頁面,並來到Vue 專案管理器系統,匯入專案(例如 vue-hello-world),你會可以看見如下幾個選單:

  • 外掛,會顯示已安裝的外掛,以及通過新增外掛就可以查詢外掛,在查詢外掛的頁面,我們知道:
    • 沒有 jquery 對應的外掛
    • axios 對應的外掛,將滑鼠移到新增外掛的圖示上會顯示:這個外掛帶有一個生成器,可以在專案中修改或增加檔案
  • 依賴,能清晰的知道執行依賴有哪些(例如 vue),開發依賴有哪些(例如 eslint
  • 配置,裡面有配置 Vue 專案程式碼質量和糾錯
  • 任務,包括專案中 package.json 中 scripts 對應的任務(servebuildlint等)。還有 inspect,能檢查 webpack 配置,比如檢視專案對應開發環境和生成環境的 webpack 配置。

Preset

一個 Vue CLI preset 是一個包含建立新專案所需預定義選項和外掛的 JSON 物件,讓使用者無需在命令提示中選擇它們。

vue create 過程中儲存的 preset 會被放在你的 home 目錄下的一個配置檔案中 (~/.vuerc)。你可以通過直接編輯這個檔案來調整、新增、刪除儲存好的 preset。

筆者預設如下:

> cat ~/.vuerc              
{
  "useTaobaoRegistry": false,
  "latestVersion": "4.5.13",
  "lastChecked": 1622962273301,        
  "presets": {
    "presetNameA": {
      "useConfigFiles": true,
      "plugins": {
        "@vue/cli-plugin-babel": {},   
        "@vue/cli-plugin-typescript": {
          "classComponent": true,      
          "useTsWithBabel": true       
        },
        "@vue/cli-plugin-pwa": {},     
        "@vue/cli-plugin-router": {    
          "historyMode": false
        },
        "@vue/cli-plugin-vuex": {},    
        "@vue/cli-plugin-eslint": {
          "config": "standard",
          "lintOn": [
            "save"
          ]
        },
        "@vue/cli-plugin-unit-mocha": {},
        "@vue/cli-plugin-e2e-cypress": {}
      },
      "vueVersion": "2",
      "cssPreprocessor": "less"
    }
  }
}

Preset 的資料會被外掛生成器用來生成相應的專案檔案。除了上述這些欄位,你也可以為整合工具新增配置:

{
  "useConfigFiles": true,
  "plugins": {...},
  "configs": {
    "vue": {...},
    "postcss": {...},
    "eslintConfig": {...},
    "jest": {...}
  }
}

這些額外的配置將會根據 useConfigFiles 的值被合併到 package.json 或相應的配置檔案中。例如,當 "useConfigFiles": true 的時候,configs 的值將會被合併到 vue.config.js 中。

你可以顯式地指定用到的外掛的版本:

{
  "plugins": {
    "@vue/cli-plugin-eslint": {
      "version": "^3.0.0",
      // ... 該外掛的其它選項
    }
  }
}

注意對於官方外掛來說這不是必須的——當被忽略時,CLI 會自動使用 registry 中最新的版本。不過推薦為 preset 列出的所有第三方外掛提供顯式的版本範圍。

CLI 服務

使用命令

在一個 Vue CLI 專案中,@vue/cli-service 安裝了一個名為 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者從終端中以 ./node_modules/.bin/vue-cli-service 訪問這個命令。

上文我們建立的專案 demo2 的 package.json 中的命令有:

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

可以通過 npmnpx(最新版的 npm 應該已經自帶) 執行命令:

> npm run serve
> npx vue-cli-service serve

Tip: 可以通過 vue ui 命令使用 GUI 執行更多的特性指令碼

vue-cli-service serve
用法:vue-cli-service serve [options] [entry]

選項:

  --open    在伺服器啟動時開啟瀏覽器
  --copy    在伺服器啟動時將 URL 複製到剪下版
  --mode    指定環境模式 (預設值:development)
  --host    指定 host (預設值:0.0.0.0)
  --port    指定 port (預設值:8080)
  --https   使用 https (預設值:false)

vue-cli-service serve 命令會啟動一個開發伺服器 (基於 webpack-dev-server) 並附帶開箱即用的模組熱過載 (Hot-Module-Replacement)。

除了通過命令列引數,你也可以使用 vue.config.js 裡的 devServer 欄位配置開發伺服器

命令列引數 [entry] 將被指定為唯一入口,而非額外的追加入口。嘗試使用 [entry] 覆蓋 config.pages 中的 entry 將可能引發錯誤。

// 在伺服器啟動時開啟瀏覽器
demo2> npx vue-cli-service serve --open

// 或者指定 entry
demo2> npx vue-cli-service serve --open ./src/main.js

Tip:終端可能因為 eslint 報錯而終止編譯,可以更改 eslint 配置。在專案根目錄下新建 vue.config.js,重啟服務即可。

// vue.config.js
module.exports = {
    lintOnSave: true
}
vue-cli-service build
用法:vue-cli-service build [options] [entry|pattern]

選項:

  --mode        指定環境模式 (預設值:production)
  --dest        指定輸出目錄 (預設值:dist)
  --modern      面向現代瀏覽器帶自動回退地構建應用
  --target      app | lib | wc | wc-async (預設值:app)
  --name        庫或 Web Components 模式下的名字 (預設值:package.json 中的 "name" 欄位或入口檔名)
  --no-clean    在構建專案之前不清除目標目錄
  --report      生成 report.html 以幫助分析包內容
  --report-json 生成 report.json 以幫助分析包內容
  --watch       監聽檔案變化

vue-cli-service build 會在 dist/ 目錄產生一個可用於生產環境的包,帶有 JS/CSS/HTML 的壓縮,和為更好的快取而做的自動的 vendor chunk splitting。它的 chunk manifest 會內聯在 HTML 裡。

這裡還有一些有用的命令引數:

  • --modern 使用現代模式構建應用,為現代瀏覽器交付原生支援的 ES2015 程式碼,並生成一個相容老瀏覽器的包用來自動回退。
// 打包生成了兩份:現代包和遺留包
demo2> npx vue-cli-service build --modern

// 為生產構建遺留包...
/  Building legacy bundle for production...

  File                                        Size                                                 Gzipped  

  dist\js\chunk-vendors-legacy.7b12297e.js    117.56 KiB                                           40.92 KiB
  dist\js\app-legacy.853ea99d.js              5.15 KiB                                             1.84 KiB 
  dist\css\app.fb0c6e1c.css                   0.33 KiB                                             0.23 KiB 

// 省略了影像和其他型別的資產
  Images and other types of assets omitted.

// 為生產構建現代捆綁...
-  Building modern bundle for production...

  File                                 Size                                                    Gzipped  

  dist\js\chunk-vendors.1e2bb21b.js    92.78 KiB                                               32.14 KiB
  dist\js\app.d739a095.js              5.07 KiB                                                1.81 KiB 
  dist\css\app.fb0c6e1c.css            0.33 KiB                                                0.23 KiB 

// 省略了影像和其他型別的資產
  Images and other types of assets omitted.
  • --target 允許你將專案中的任何元件以一個庫或 Web Components 元件的方式進行構建。

  • --report--report-json 會根據構建統計生成報告,它會幫助你分析包中包含的模組們的大小。

demo2> npx vue-cli-service build --report

|  Building for production...

  File                                 Size                                                    Gzipped  

  dist\js\chunk-vendors.7b12297e.js    117.55 KiB                                              40.92 KiB
  dist\js\app.853ea99d.js              5.14 KiB                                                1.83 KiB 
  dist\css\app.fb0c6e1c.css            0.33 KiB                                                0.23 KiB 

  Images and other types of assets omitted.

會在 dist 目錄中生成 report.html

Tip: 如果你使用的是 vscode,只需要安裝 Live Server 外掛,即可右鍵通過 live server 檢視 report.html,非常方便。

如果是 --report,則不會生成 report.html,而會生成 report.json

vue-cli-service inspect
用法:vue-cli-service inspect [options] [...paths]

選項:

  --mode    指定環境模式 (預設值:development)

審查一個 Vue CLI 專案的 webpack config。請看示例:

// 提取出webpack開發配置,匯出到 webpack.config.development.js 中
demo2> npx vue-cli-service inspect --mode development >> webpack.config.development.js

// 提取出webpack生成配置
demo2> npx vue-cli-service inspect --mode production >> webpack.config.production.js

:接下來我們學習過程中會參考這兩個配置檔案

檢視所有的可用命令

有些 CLI 外掛會向 vue-cli-service 注入額外的命令。例如 @vue/cli-plugin-eslint 會注入 vue-cli-service lint 命令。你可以執行以下命令檢視所有注入的命令:

demo2> npx vue-cli-service help

  Usage: vue-cli-service <command> [options]

  Commands:

    serve     start development server
    build     build for production
    inspect   inspect internal webpack config
    lint      lint and fix source files

  run vue-cli-service help [command] for usage of a specific command.

也可以這樣學習每個命令可用的選項:

npx vue-cli-service help [command]
快取和並行處理
  • cache-loader 會預設為 Vue/Babel/TypeScript 編譯開啟。檔案會快取在 node_modules/.cache 中——如果你遇到了編譯方面的問題,記得先刪掉快取目錄之後再試試看。
// demo2 中的快取檔案:
demo2> dir .\node_modules\.cache\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2021/8/11     11:30                babel-loader
d-----         2021/8/11     11:30                eslint-loader
d-----         2021/7/19     19:31                terser-webpack-plugin
d-----         2021/8/11     11:30                vue-loader
  • thread-loader 會在多核 CPU 的機器上為 Babel/TypeScript 轉譯開啟。

Tip:雖然 package.json 中沒有 cache-loaderthread-loader,但 demo2/node_modules 中有。

Git Hook

在安裝之後,@vue/cli-service 也會安裝 yorkie,它會讓你在 package.json 的 gitHooks 欄位中方便地指定 Git hook:

{
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
   "lint-staged": {
    "*.{js,vue}": [
      "vue-cli-service lint",
      "git add"
    ]
  }
}

Tip:yorkie,fork 專案 husky,並做了一些改變,比如更改了從 package.json 中讀取鉤子的位置:

// before
{
  "scripts": {
    "precommit": "foo"
  }
}
// after
{
  "gitHooks": {
    "pre-commit": "foo"
  }
}

具體用法,請看示例(在demo2基礎上進行):

// package.json
{
  ...
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,vue}": [
      "vue-cli-service lint",
      "git add"
    ]
  }
}

執行 git commit 命令報錯:

demo2> git commit -m 'xx'
On branch master
  (use "git add <file>..." to include in what will be committed)
        src/a.js

'lint-staged' 不是內部或外部命令,也不是可執行的程式
或批處理檔案。

pre-commit hook failed (add --no-verify to bypass)

安裝依賴包:

// lint-staged - 對暫存的 git 檔案執行 linter,不要讓不好的程式碼溜進你的程式碼庫!
demo2> npm i -D lint-staged

接下來給 eslint 增加一個規則,然後在 a.js 中故意不遵守該規則:

// package.json
{
  "eslintConfig": {
    "rules": {
      "no-console": "error"
    }
  },
}
// src/a.js
let i = 1
console.log(i);

執行git commit命令,驗證不通過,終止提交:

// 需要先 git add
demo2> git add src/a.js
demo2> git commit -m 'xx'
 > running pre-commit hook: lint-staged
⚠ Some of your tasks use `git add` command. Please remove it from the config since all modifications made by tasks will be 
automatically added to the git commit index.

[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.{js,vue}
[STARTED] vue-cli-service lint
[FAILED] vue-cli-service lint [FAILED]
[FAILED] vue-cli-service lint [FAILED]
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SKIPPED] Skipped because of errors from tasks.
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...

✖ vue-cli-service lint:
error: Unexpected console statement (no-console) at src\a.js:2:1:
  1 | let i = 1
> 2 | console.log(i);
    | ^
  3 |


1 error found.

pre-commit hook failed (add --no-verify to bypass)

Tip:Git 鉤子,和其它版本控制系統一樣,Git 能在特定的重要動作發生時觸發自定義指令碼。有兩組這樣的鉤子:客戶端的和伺服器端的。客戶端鉤子由諸如提交和合並這樣的操作所呼叫,而伺服器端鉤子作用於諸如接收被推送的提交這樣的聯網操作。你可以隨心所欲地運用這些鉤子。

// 專案 demo2 的 git hooks
demo2> dir .\.git\hooks\

    目錄: demo2\.git\hooks

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2021/7/19      9:11            870 applypatch-msg
-a----         2021/7/19      9:07            478 applypatch-msg.sample
-a----         2021/7/19      9:11            854 commit-msg
-a----         2021/7/19      9:07            896 commit-msg.sample
-a----         2021/7/19      9:07           4655 fsmonitor-watchman.sample
-a----         2021/7/19      9:11            874 post-applypatch
-a----         2021/7/19      9:11            866 post-checkout
-a----         2021/7/19      9:11            858 post-commit
-a----         2021/7/19      9:11            854 post-merge
-a----         2021/7/19      9:11            862 post-receive
-a----         2021/7/19      9:11            862 post-rewrite
-a----         2021/7/19      9:11            858 post-update
-a----         2021/7/19      9:07            189 post-update.sample
-a----         2021/7/19      9:11            870 pre-applypatch
-a----         2021/7/19      9:07            424 pre-applypatch.sample
-a----         2021/7/19      9:11            858 pre-auto-gc
-a----         2021/7/19      9:11            854 pre-commit
-a----         2021/7/19      9:07           1643 pre-commit.sample
-a----         2021/7/19      9:07            416 pre-merge-commit.sample
-a----         2021/7/19      9:11            846 pre-push
-a----         2021/7/19      9:07           1348 pre-push.sample
-a----         2021/7/19      9:11            854 pre-rebase
-a----         2021/7/19      9:07           4898 pre-rebase.sample
-a----         2021/7/19      9:11            858 pre-receive
-a----         2021/7/19      9:07            544 pre-receive.sample
-a----         2021/7/19      9:11            913 prepare-commit-msg
-a----         2021/7/19      9:07           1492 prepare-commit-msg.sample
-a----         2021/7/19      9:11            878 push-to-checkout
-a----         2021/7/19      9:11            886 sendemail-validate
-a----         2021/7/19      9:11            838 update
-a----         2021/7/19      9:07           3635 update.sample
配置時無需 Eject

通過 vue create 建立的專案無需額外的配置就已經可以跑起來了。外掛的設計也是可以相互共存的,所以絕大多數情況下,你只需要在互動式命令提示中選取需要的功能即可。

不過我們也知道滿足每一個需求是不太可能的,而且一個專案的需求也會不斷改變。通過 Vue CLI 建立的專案讓你無需 eject 就能夠配置工具的幾乎每個角落。

其他章節請看:

vue 快速入門 系列

相關文章