Vue學習筆記(一)------腳手架vue cli

靜水流深醬發表於2019-04-17

Vue學習筆記(一)------腳手架vue cli

腳手架vue-cli(3.x)

vue-cli是一個基於vue.js進行快速開發的完整系統,提供下面幾個功能:

  • 通過 @vue/cli 搭建互動式的專案腳手架。
  • 通過 @vue/cli + @vue/cli-service-global 快速開始零配置原型開發。
  • 一個執行時依賴 (@vue/cli-service),該依賴:
    • 可升級;
    • 基於 webpack 構建,並帶有合理的預設配置;
    • 可以通過專案內的配置檔案進行配置;
    • 可以通過外掛進行擴充套件。
  • 一個豐富的官方外掛集合,整合了前端生態中最好的工具。
  • 一套完全圖形化的建立和管理 Vue.js 專案的使用者介面。

vue-cli是由以下幾個部分組成:

  • cli(@vue/cli)
  • cli服務(@vue/cli-service)
  • cli外掛

CLI (@vue/cli) 是一個全域性安裝的 npm 包,提供了終端裡的 vue 命令,這些命令都是在全域性安裝之後才可以使用的,例如:使用 vue serve 啟動專案需要在npm install -g @vue/cli-service-global之後才可以。

  • vue create 建立一個vue專案
  • vue serve 啟動vue專案
  • vue ui 進入vue視覺化管理介面

當我們沒有全域性安裝vue時,可以藉助npm 進行vue專案的啟動和打包等操作,例如: npm run serve 啟動vue專案; npm run build打包vue專案; 同時在啟動react專案的時候使用的是npm start; 在打包react專案的時候也是使用的npm run build; 但是建立react專案的是使用的react自己的腳手架create-react-app; vue使用的命令是vue create。

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

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

如果你熟悉 create-react-app 的話,@vue/cli-service 實際上大致於 react-scripts,儘管功能集合不一樣。

對應的vue專案的package.json中內容如下:

{
  ......
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
  ......
}
複製程式碼

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

對應的vue專案的package.json中內容如下:

{
  ......
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.5.0",
    "@vue/cli-plugin-eslint": "^3.5.0",
    "@vue/cli-service": "^3.5.0",
    "@vue/eslint-config-standard": "^4.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.8.0",
    "eslint-plugin-vue": "^5.0.0",
    "less": "^3.0.4",
    "less-loader": "^4.1.0",
    "vue-template-compiler": "^2.5.21"
  }
  ......
}
複製程式碼

腳手架的安裝

關於舊版本,如果你已經全域性安裝了舊版本vue-cli(1.x或者2.x)的話,需要先解除安裝,npm uninstall vue-cli -g,現在是3.x的腳手架@vue/cli。

安裝@vue/cli

npm  intsall @vue/cli  -g 
複製程式碼

安裝完成之後可以使用vue --version 檢視版本的資訊以及是否安裝成功;

Vue學習筆記(一)------腳手架vue cli

腳手架的基礎使用

可以使用vue serve和vue build對單個*.vue檔案進行快速原型開發,但是需要安裝一個額外的全域性擴充套件:

npm install -g @vue/cli-service-global
複製程式碼

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

vue serve常用的幾個引數:
Usage: serve [options] [entry]
在開發環境模式下零配置為 .js 或 .vue 檔案啟動一個伺服器
-o, --open  開啟瀏覽器
-c, --copy  將本地 URL 複製到剪下板
-h, --help  輸出用法資訊
其中 [entry]是入口檔案,入口可以是 main.js、index.js、App.vue 或 app.vue 中的一個。你也可以顯式地指定入口檔案。
複製程式碼
vue build常用的幾個引數
Usage: build [options] [entry]
在生產環境模式下零配置構建一個 .js 或 .vue 檔案
-t, --target <target>  構建目標 (app | lib | wc | wc-async, 預設值:app)
-n, --name <name>      庫的名字或 Web Components 元件的名字 (預設值:入口檔名)
-d, --dest <dir>       輸出目錄 (預設值:dist)
-h, --help             輸出用法資訊
複製程式碼
vue create建立一個新的專案

比如說建立一個新專案: vue create hello-world,當你使用vue create 建立一個專案時會提示你選擇一個preset(預設),你可以選預設的包含了基本的 Babel + ESLint 設定的 preset,或者vue-router, vuex, less, babel, eslint的preset,也可以選“手動選擇特性”來選取需要的特性。

Vue學習筆記(一)------腳手架vue cli

預設設定非常合適快速的常見一個新專案,當你選擇手動建立時,你需要自己選擇需要的依賴:

Vue學習筆記(一)------腳手架vue cli

如果你決定手動選擇特性,在操作提示的最後你可以選擇將已選項儲存為一個將來可複用的 preset。

當我們在使用npm install安裝依賴的時候,下載依賴往往會非常的慢,此時我們需要修改一下,npm的下載源,可以改為淘寶的下載源:

首先檢視當前的npm源是什麼:

npm  config  get registry
複製程式碼

Vue學習筆記(一)------腳手架vue cli

上面的源已經設定為淘寶的源,設定淘寶映象:

npm config set registry https://registry.npm.taobao.org
複製程式碼

也可以進行臨時修改,只生效一次:

npm install 包的名字 --registry https://registry.npm.taobao.org
複製程式碼

vue create 常用的引數檢視:

Vue學習筆記(一)------腳手架vue cli

選項:
  -p, --preset <presetName>       忽略提示符並使用已儲存的或遠端的預設選項
  -d, --default                   忽略提示符並使用預設預設選項
  -i, --inlinePreset <json>       忽略提示符並使用內聯的 JSON 字串預設選項
  -m, --packageManager <command>  在安裝依賴時使用指定的 npm 客戶端
  -r, --registry <url>            在安裝依賴時使用指定的 npm registry
  -g, --git [message]             強制 / 跳過 git 初始化,並可選的指定初始化提交資訊
  -n, --no-git                    跳過 git 初始化
  -f, --force                     覆寫目標目錄可能存在的配置
  -c, --clone                     使用 git clone 獲取遠端預設選項
  -x, --proxy                     使用指定的代理建立專案
  -b, --bare                      建立專案時省略預設元件中的新手指導資訊
  -h, --help                      輸出使用幫助資訊
複製程式碼
vue ui 圖形化介面管理專案

使用vue ui 進入圖形化管理介面

vue  ui
複製程式碼

Vue學習筆記(一)------腳手架vue cli

Vue學習筆記(一)------腳手架vue cli

外掛和preset(預設)

Vue CLI 使用了一套基於外掛的架構。如果你查閱一個新建立專案的 package.json,就會發現依賴都是以 @vue/cli-plugin- 開頭的。外掛可以修改 webpack 的內部配置,也可以向 vue-cli-service 注入命令。在專案建立的過程中,絕大部分列出的特性都是通過外掛來實現的。

現有的專案中安裝外掛,安裝一個新的外掛可以使用:

vue add @vue/eslint
複製程式碼

注意:

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

其實在專案開發中我們一般會使用npm進行的依賴包的管理:

npm  install  包名  --save  在生產環境中使用(package.json中的scripts下)
npm  install  包名  --save-dev 在開發環境中安裝(package.json中的devDependencies下)
npm  install  安裝package.json中的所有的依賴
npm  uninstall [<name><version>][-g]/[--save][-dev]  解除安裝安裝的某個包
npm  update    [<name><version>][-g]/[--save][-dev]  更新安裝的某個包
npm  init  初始化package.json檔案
複製程式碼

在使用vue add時:

vue add @vue/eslint
# 這個命令將 @vue/eslint 解析為完整的包名 @vue/cli-plugin-eslint,然後從 npm 安裝它,呼叫它的生成器。這個和之前的用法等價
vue add @vue/cli-plugin-eslint
複製程式碼

如果想安裝第三方的,例如: @foo/vue-cli-plugin-bar

vue add @foo/bar
複製程式碼

vue-routervuex 的情況比較特殊——它們並沒有自己的外掛,但是你仍然可以這樣新增它們:

vue add router
vue add vuex
複製程式碼

如果出於一些原因你的外掛列在了該專案之外的其它 package.json 檔案裡,你可以在自己專案的 package.json 裡設定 vuePlugins.resolveFrom 選項指向包含其它 package.json 的資料夾。例如,如果你有一個 .config/package.json 檔案,那麼package.json裡面要進行這樣大的修改:

{
  "vuePlugins": {
    "resolveFrom": ".config"
  }
}
複製程式碼

如果你需要在專案裡直接訪問外掛 API 而不需要建立一個完整的外掛,你可以在 package.json 檔案中使用 vuePlugins.service 選項:

{
  "vuePlugins": {
    "service": ["my-commands.js"]
  }
}
複製程式碼
preset(預設)

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

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

Vue學習筆記(一)------腳手架vue cli

進入./vuerc檢視裡面的內容:

Vue學習筆記(一)------腳手架vue cli

下面就是preset的一個列子:

{
  "useTaobaoRegistry": false,
  "presets": {
    "y": {
      "useConfigFiles": true,
      "plugins": {
        "@vue/cli-plugin-babel": {},
        "@vue/cli-plugin-eslint": {
          "config": "standard",
          "lintOn": [
            "save"
          ]
        }
      },
      "router": true,
      "routerHistoryMode": true,
      "vuex": true,
      "cssPreprocessor": "less"
    }
  },
  "latestVersion": "3.6.3",
  "lastChecked": 1555467470124
}
複製程式碼

CLI 服務

在執行專案的時候執行npm run serve其實相當於執行了 vue-cli-service serve命名;

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)。

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

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 程式碼,並生成一個相容老瀏覽器的包用來自動回退。
  • --target 允許你將專案中的任何元件以一個庫或 Web Components 元件的方式進行構建。更多細節請查閱構建目標
  • --report--report-json 會根據構建統計生成報告,它會幫助你分析包中包含的模組們的大小。
vue-cli-service inspect命令
用法:vue-cli-service inspect [options] [...paths]

選項:
  --mode    指定環境模式 (預設值:development)
複製程式碼

你可以使用 vue-cli-service inspect 來審查一個 Vue CLI 專案的 webpack config。

快取和並行處理
  • cache-loader 會預設為 Vue/Babel/TypeScript 編譯開啟。檔案會快取在 node_modules/.cache中——如果你遇到了編譯方面的問題,記得先刪掉快取目錄之後再試試看。
  • thread-loader 會在多核 CPU 的機器上為 Babel/TypeScript 轉譯開啟。

瀏覽器相容性

browserslist

你會發現有 package.json 檔案裡的 browserslist 欄位 (或一個單獨的 .browserslistrc 檔案),指定了專案的目標瀏覽器的範圍。

Vue學習筆記(一)------腳手架vue cli

Polyfill

一個預設的 Vue CLI 專案會使用 @vue/babel-preset-app,它通過 @babel/preset-envbrowserslist 配置來決定專案需要的 polyfill。

預設情況下,它會把 useBuiltIns: 'usage' 傳遞給 @babel/preset-env,這樣它會根據原始碼中出現的語言特性自動檢測需要的 polyfill。這確保了最終包裡 polyfill 數量的最小化。然而,這也意味著如果其中一個依賴需要特殊的 polyfill,預設情況下 Babel 無法將其檢測出來。

如果有依賴需要 polyfill,你有幾種選擇:

  1. 如果該依賴基於一個目標環境不支援的 ES 版本撰寫: 將其新增到 vue.config.js 中的 transpileDependencies 選項。這會為該依賴同時開啟語法語法轉換和根據使用情況檢測 polyfill。
  2. 如果該依賴交付了 ES5 程式碼並顯式地列出了需要的 polyfill: 你可以使用 @vue/babel-preset-apppolyfills 選項預包含所需要的 polyfill。注意 es6.promise 將被預設包含,因為現在的庫依賴 Promise 是非常普遍的。
// babel.config.js
module.exports = {
  presets: [
    ['@vue/app', {
      polyfills: [
        'es6.promise',
        'es6.symbol'
      ]
    }]
  ]
}
複製程式碼
現在模式

Vue CLI 提供了一個“現代模式”幫你解決這個問題。以如下命令為生產環境構建:

vue-cli-service build --modern
複製程式碼

Vue CLI 會產生兩個應用的版本:一個現代版的包,面向支援 ES modules 的現代瀏覽器,另一箇舊版的包,面向不支援的舊瀏覽器。

  • 現代版的包會通過 <script type="module"> 在被支援的瀏覽器中載入;它們還會使用 <link rel="modulepreload"> 進行預載入。
  • 舊版的包會通過 <script nomodule> 載入,並會被支援 ES modules 的瀏覽器忽略。
  • 一個針對 Safari 10 中 <script nomodule> 的修復會被自動注入。

對於一個 Hello World 應用來說,現代版的包已經小了 16%。在生產環境下,現代版的包通常都會表現出顯著的解析速度和運算速度,從而改善應用的載入效能。

HTML 和靜態資源

index檔案

public/index.html 檔案是一個會被 html-webpack-plugin 處理的模板。在構建過程中,資源連結會被自動注入。另外,Vue CLI 也會自動注入 resource hint (preload/prefetch、manifest 和圖示連結 (當用到 PWA 外掛時) 以及構建過程中處理的 JavaScript 和 CSS 檔案的資源連結。

插值

因為 index 檔案被用作模板,所以你可以使用 lodash template 語法插入內容:

  • <%= VALUE %> 用來做不轉義插值;
  • <%- VALUE %> 用來做 HTML 轉義插值;
  • <% expression %> 用來描述 JavaScript 流程控制。

除了html-webpack-plugin 暴露的預設值之外,所有客戶端環境變數也可以直接使用。例如,BASE_URL 的用法:

<link rel="icon" href="<%= BASE_URL %>favicon.ico">
複製程式碼
preload

是一種 resource hint,用來指定頁面載入後很快會被用到的資源,所以在頁面載入的過程中,我們希望在瀏覽器開始主體渲染之前儘早 preload。預設情況下,一個 Vue CLI 應用會為所有初始化渲染需要的檔案自動生成 preload 提示。

prefetch

是一種 resource hint,用來告訴瀏覽器在頁面載入完成後,利用空閒時間提前獲取使用者未來可能會訪問的內容。

不生成 index

當基於已有的後端使用 Vue CLI 時,你可能不需要生成 index.html,這樣生成的資源可以用於一個服務端渲染的頁面。這時可以向 vue.config.js 加入下列程式碼:

// vue.config.js
module.exports = {
  // 去掉檔名中的 hash
  filenameHashing: false,
  // 刪除 HTML 相關的 webpack 外掛
  chainWebpack: config => {
    config.plugins.delete('html')
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')
  }
}
複製程式碼

css相關

引用靜態資源

所有編譯後的 CSS 都會通過 css-loader 來解析其中的 url() 引用,並將這些引用作為模組請求來處理。這意味著你可以根據本地的檔案結構用相對路徑來引用靜態資源。另外要注意的是如果你想要引用一個 npm 依賴中的檔案,或是想要用 webpack alias,則需要在路徑前加上 ~ 的字首來避免歧義。更多細節請參考處理靜態資源

前處理器

你可以在建立專案的時候選擇前處理器 (Sass/Less/Stylus)。如果當時沒有選好,內建的 webpack 仍然會被預配置為可以完成所有的處理。你也可以手動安裝相應的 webpack loader:

# Sass
npm install -D sass-loader node-sass

# Less
npm install -D less-loader less

# Stylus
npm install -D stylus-loader stylus
複製程式碼

然後你就可以匯入相應的檔案型別,或在 *.vue 檔案中這樣來使用:

<style lang="scss">
$color: red;
</style>
複製程式碼
自動化匯入

如果你想自動化匯入檔案 (用於顏色、變數、mixin……),你可以使用 style-resources-loader。這裡有一個關於 Stylus 的在每個單檔案元件和 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

如果想在 JavaScript 中作為 CSS Modules 匯入 CSS 或其它預處理檔案,該檔案應該以 .module.(css|less|sass|scss|styl) 結尾:

import styles from './foo.module.css'
// 所有支援的前處理器都一樣工作
import sassStyles from './foo.module.scss'
複製程式碼

如果你想去掉檔名中的 .module,可以設定 vue.config.js 中的 css.modulestrue

// vue.config.js
module.exports = {
  css: {
    modules: true
  }
}
複製程式碼

如果你希望自定義生成的 CSS Modules 模組的類名,可以通過 vue.config.js 中的 css.loaderOptions.css 選項來實現。所有的 css-loader 選項在這裡都是支援的,例如 localIdentNamecamelCase

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      css: {
        localIdentName: '[name]-[hash]',
        camelCase: 'only'
      }
    }
  }
}
複製程式碼

webpack 相關

.....

相關文章