介紹
- Vue CLI 是一個基於 Vue.js 進行快速開發的完整系統
- 經過 @vue/cli 搭建交互式的項目腳手架。
- 經過 @vue/cli + @vue/cli-service-global 快速開始零配置原型開發。
- 一個運行時依賴 (@vue/cli-service) 一個開發環境依賴,局部安裝在每一個 @vue/cli 建立的項目中。
- 可升級 ?
- 基於 webpack 構建,並帶有合理的默認配置;
- 能夠經過項目內的配置文件進行配置;
- 能夠經過插件進行擴展。—— cli 插件是用來給 webpack 安裝 loader包或插件包的工具,同時它可以自動的完成這些包的配置。
- 一個豐富的官方插件集合,集成了前端生態中最好的工具。
- 一套徹底圖形化的建立和管理 Vue.js 項目的用戶界面。
- Vue CLI 致力於將 Vue 生態中的工具基礎標準化。
該系統的組件
CLI
- @vue/cli 提供了終端裏的 vue 命令
- vue create 快速建立一個新項目的腳手架
- vue serve 構建新想法的原型
- vue ui 經過一套圖形化界面管理你的全部項目
CLI 服務
- @vue/cli-service 是一個開發環境依賴,局部安裝在每一個 @vue/cli 建立的項目中。
- CLI 服務是構建於 webpack 和 webpack-dev-server 之上
- 加載其它 CLI 插件的核心服務
- 一個針對絕大部分應用優化過的內部的 webpack 配置
- 項目內部的 vue-cli-service 命令,提供 serve、build 和 inspect 命令 (inspect 來審查一個 Vue CLI 項目的 webpack config)
CLI 插件
- CLI 插件是向你的 Vue 項目提供可選功能的 npm 包,例如 Babel/TypeScript 轉譯、ESLint 集成、單元測試和 end-to-end 測試等。
- Vue CLI 插件的名字以 @vue/cli-plugin- (內建插件) 或 vue-cli-plugin- (社區插件) 開頭
- 當你在項目內部運行 vue-cli-service 命令時,它會自動解析並加載 package.json 中列出的全部 CLI 插件。
- 插件能夠做爲項目建立過程的一部分,或在後期加入到項目中。
————————————————————————————————————————————————————————————
安裝
- Vue CLI 須要 Node.js 8.9 或更高版本 (推薦 8.11.0+)
- 可使用 nvm 或 nvm-windows 在同一臺電腦中管理多個 Node 版本。
- 安裝以後,你就能夠在命令行中訪問 vue 命令。
- 能夠用這個命令來檢查其版本是否正確
vue --version
—— 返回@vue/cli的版本號
————————————————————————————————————————————————————————————
基礎
————————————————————————————————————————————————————————————
快速原型開發
- 可使用 vue serve 和 vue build 命令對單個 *.vue 文件進行快速原型開發
- 須要先額外安裝一個全局的擴展
npm install -g @vue/cli-service-global
(不必定須要全局安裝)
vue serve
- 在開發環境模式下零配置爲 .js 或 .vue 文件啓動一個服務器,用法:
vue serve [options] [entry]
- Options:
- -o, --open 打開瀏覽器
- -c, --copy 將本地 URL 複製到剪切板
- -h, --help 輸出用法信息
- vue serve 使用了 vue create 的默認設置 (webpack、Babel、PostCSS 和 ESLint)。
- 入口能夠是 main.js、index.js、App.vue 或 app.vue 中的一個,在命令
vue serve
執行的當前目錄下
- 能夠顯式地指定入口文件
vue serve MyComponent.vue
或vue serve ccc/first.vue
,從命令行執行的位置起
- 能夠提供一個 index.html —— 放在命令運行目錄下或其public內,若是沒有將使用標準html做爲模板
- 能夠提供一個 package.json
- 能夠安裝並使用本地依賴
- 能夠經過相應的配置文件配置 Babel、PostCSS 和 ESLint
vue build
- 在生產環境模式下零配置將目標文件構建成一個生產環境的包並用來部署(一個 .js 或 .vue 文件),用法:
vue build [options] [entry]
,例如:vue build MyComponent.vue
(更多路徑書寫方法見vue serve)
- 也提供了將組件構建成爲一個庫或一個 Web Components 組件的能力。(對於4種構建目標的區別將在後文進行研究)
- Options:
- -t, --target <target> 構建目標 (app | lib | wc | wc-async, 默認值:app)
- -n, --name <name> 庫的名字或 Web Components 組件的名字 (wc 和 wc-async 默認值:入口文件名,並要求必須有連字符) (lib 時默認值是package.json 中的 "name" 字段)
- -d, --dest <dir> 輸出目錄 (默認值:dist)
- -h, --help 輸出用法信息
————————————————————————————————————————————————————————————
建立一個項目
vue create
- 建立一個由
vue-cli-service
提供支持的新項目,用法create [options] <app-name>
,例如:vue create hello-world
- 在 Windows 上經過 minTTY 使用 Git Bash,交互提示符並不工做 ——?
- 經過 winpty vue.cmd create hello-world 啓動
vue create hello-world
這個命令
- 能夠經過在 ~/.bashrc 文件中添加如下行來爲命令添加別名
alias vue='winpty vue.cmd'
來支持vue create hello-world
,須要從新啓動 Git Bash 終端會話以使更新後的 bashrc 文件生效
- 在操做提示的最後你能夠選擇將已選項保存爲一個未來可複用的 preset
- 被保存的 preset 將會存在用戶的 home 目錄下一個名爲 .vuerc 的 JSON 文件裏。保存多套,操做提示的最後會讓你輸入每套配置的名稱,已被未來選擇
- 在項目建立的過程當中,你也會被提示選擇喜歡的包管理器或使用淘寶 npm 鏡像源以更快地安裝依賴。
- 選項:
- -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 命令以圖形化界面建立和管理項目
拉取 2.x 模板 (舊版本)
- Vue CLI 3 和舊版使用了相同的 vue 命令,因此 Vue CLI 2 (vue-cli) 被覆蓋了。
- 能夠全局安裝一個橋接工具,使用舊版本的 vue init 功能
npm install -g @vue/cli-init
?
————————————————————————————————————————————————————————————
插件和Preset
插件
- 插件能夠修改 webpack 的內部配置,也能夠向 vue-cli-service 注入命令
- 在項目建立的過程當中,絕大部分列出的特性都是經過插件來實現的
- 特性:好比使用ESLint管理狀態就是其中一種特性
- 能夠經過 vue ui 命令使用 GUI(圖形界面) 安裝和管理插件
在現有的項目中安裝插件
- 每一個 CLI 插件都會包含一個生成器和一個運行時插件
- 生成器用來建立文件的(應該是指從npm上安裝對應的模塊,例如Eslint)
- 運行時插件用來調整 webpack 核心配置和注入命令的(運行時是指?注入命令是指? )
- 使用 vue create 來建立一個新項目的時候,有些插件會根據你選擇的特性被預安裝
- 在一個已經被建立好的項目中安裝一個插件,可使用 vue add 命令
vue add @vue/eslint
- 和
vue add @vue/cli-plugin-eslint
等價
- 這個命令將 @vue/eslint 解析爲完整的包名 @vue/cli-plugin-eslint,而後從 npm 安裝它,調用它的生成器。(依然可以向項目中插入插件定義的命令,例如
vue add @vue/eslint
後會在package中新增"lint": "vue-cli-service lint"
命令)
- 若是不帶 @vue 前綴,該命令會換做解析一個 unscoped 的包。例如如下命令會安裝第三方插件 vue-cli-plugin-apollo:
vue add apollo
- 能夠基於一個指定的 scope(範圍) 使用第三方插件。例如若是一個插件名爲 @foo/vue-cli-plugin-bar,你能夠這樣添加它:
vue add @foo/bar
- 能夠向被安裝的插件傳遞生成器選項 (這樣作會跳過命令提示):
vue add @vue/eslint --config airbnb --lintOn save
- vue-router 和 vuex 的狀況比較特殊——它們並無本身的插件,可是你仍然能夠這樣添加它們:
vue add router
vue add vuex
- 若是一個插件已經被安裝,你可使用 vue invoke 命令跳過安裝過程,只調用它的生成器。?
- 若是出於一些緣由你的插件列在了該項目以外的其它 package.json 文件裏,你能夠在本身項目的 package.json 裏設置 vuePlugins.resolveFrom 選項指向包含其它 package.json 的文件夾。?
// 若是你有一個 .config/package.json 文件
{
"vuePlugins": {
"resolveFrom": ".config"
}
}
- 推薦在運行 vue add 以前將項目的最新狀態提交,由於該命令可能調用插件的文件生成器並頗有可能更改你現有的文件。
項目本地的插件 ?
- 在項目裏直接訪問插件 API 而不須要建立一個完整的插件 ?
- 能夠經過 vuePlugins.ui 選項添加像 UI 插件同樣工做的文件 ?
- 該章節涉及插件開發和高級應用,暫時看不懂 ?
Preset(預設.vuerc文件)
- Vue CLI preset 是一個包含建立新項目所需預約義選項和插件的 JSON 對象
- 在 vue create 過程當中保存的 preset 會被放在你的 home 目錄下的一個配置文件中 (~/.vuerc)
- Preset 的數據會被插件生成器用來生成相應的項目文件(Preset中保存這插件以及和這個插件相關的提示符選項因此可以被插件生成器生成相應的項目文件)
- 能夠爲集成工具添加配置:這些額外的配置將會根據 useConfigFiles 的值被合併到 package.json 或相應的配置文件中。(當有多個項目通用自定義vue.config.js配置時,能夠在這裏編輯,方便建立項目時不用重複配置)
{
"useConfigFiles": true, // 當 "useConfigFiles": true 的時候,configs 的值將會被合併到 vue.config.js 中
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}
Preset 插件的版本管理
- 能夠顯式地指定用到的插件的版本
- 對於官方插件來講這不是必須的
- 推薦爲 preset 列出的全部第三方插件提供顯式的版本範圍
{
"plugins": {
"@vue/cli-plugin-eslint": {
"version": "^3.0.0",
// ... 該插件的其它選項
}
}
}
容許插件的命令提示
{
"plugins": {
"@vue/cli-plugin-eslint": {
// 讓用戶選取他們本身的 ESLint config
"prompts": true
}
}
}
———————————————————————————
遠程 Preset ?
- 能夠經過發佈 git repo 將一個 preset 分享給其餘開發者。這個 repo 應該包含如下文件:
- preset.json: 包含 preset 數據的主要文件(必需)。
- generator.js: 一個能夠注入或是修改項目中文件的 Generator(生產者)。
- prompts.js 一個能夠經過命令行對話爲 generator 收集選項的 prompts(提示) 文件。
- 能夠在建立項目的時候經過 --preset 選項使用這個遠程的 preset
# 從 GitHub repo 使用 preset(GitLab 和 BitBucket 也是支持的)
# GitHub、GitLab、BitBucket都是倉庫管理系統
vue create --preset username/repo my-project
- 若是要從私有 repo 獲取,請確保使用 --clone 選項
vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project
————————————————————————————
加載文件系統中的 Preset
- 若是 --preset 選項的值是一個相對或絕對文件路徑,或是以 .json 結尾,則 Vue CLI 會加載本地的 preset
# ./my-preset 應當是一個包含 preset.json 的文件夾
vue create --preset ./my-preset my-project
# 或者,直接使用當前工做目錄下的 json 文件:
vue create --preset my-preset.json my-project
————————————————————————————————————————————————————————————
CLI服務
使用命令
- Vue CLI 項目中,@vue/cli-service 安裝了一個名爲 vue-cli-service 的命令
- 能夠在 npm scripts 中以 vue-cli-service訪問這個命令(npm scripts 在默認 preset 的項目的 package.json 中已經配置好了)
- 或者從終端中以 ./node_modules/.bin/vue-cli-service 訪問這個命令 ?
- 能夠經過 vue ui 命令使用 GUI(視圖界面) 運行更多的特性腳本
vue-cli-service serve
- vue-cli-service serve 命令會啓動一個開發服務器 (基於 webpack-dev-server) 並附帶開箱即用的模塊熱重載 (Hot-Module-Replacement)。
- 用法
vue-cli-service serve [options] [entry]
- options選項:
- --open 在服務器啓動時打開瀏覽器
- --copy 在服務器啓動時將 URL 複製到剪切版
- --mode 指定環境模式 (默認值:development)
- --host 指定 host (默認值:0.0.0.0)
- --port 指定 port (默認值:8080)
- --https 使用 https (默認值:false)
- 除了經過命令行參數,你也可使用 vue.config.js 裏的 devServer 字段配置開發服務器。(待擴展)
vue-cli-service build
- vue-cli-service build 會在 ./dist/ 目錄產生一個可用於生產環境的包,帶有 JS/CSS/HTML 的壓縮,和爲更好的緩存而作的自動的 vendor chunk splitting(供應商塊拆分)。
- 它的 chunk manifest(塊清單) 會內聯在 HTML 裏。
- 用法: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" 字段(lib庫時)或入口文件名(Web Components 模式時))
- --no-clean 在構建項目以前不清除目標目錄
- --report 生成 report.html 以幫助分析包內容的大小
- --report-json 生成 report.json 以幫助分析包內容的大小
- --watch 監聽文件變化(會生成一個熱打包的服務)
"build": "vue-cli-service build --target lib ./src/components/HelloWorld.vue"
vue-cli-service inspect
- 使用 vue-cli-service inspect 來審查一個 Vue CLI 項目的 webpack config
- 用法:vue-cli-service inspect [options] [...paths] 例如:
npx vue-cli-service inspect configureWebpack
用來檢查webpack中configureWebpack選項的值
- 選項:
- --mode 指定環境模式 (默認值:development)
查看全部的可用命令
- 有些 CLI 插件會向 vue-cli-service 注入額外的命令
- 能夠運行如下命令查看全部注入的命令:
npx vue-cli-service help
- 能夠這樣學習每一個命令可用的選項:
npx vue-cli-service help [command]
緩存和並行處理
- cache-loader 會默認爲 Vue/Babel/TypeScript 編譯開啓。文件會緩存在 node_modules/.cache 中——若是你遇到了編譯方面的問題,記得先刪掉緩存目錄以後再試試看。
- thread-loader 會在多核 CPU 的機器上爲 Babel/TypeScript 轉譯開啓。
——————————————————————————————————————
Git Hook ?
- @vue/cli-service 會安裝 yorkie,它會讓你在 package.json 的 gitHooks 字段中方便地指定 Git hook:
- Git hook(Git 鉤子)能在特定的重要動做發生時觸發自定義腳本。
- yorkie 是husky的一個自定義分支和將來版本的husky不兼容
{
"gitHooks": {
"pre-commit": "lint-staged"
}
}
——————————————————————————————————————
配置時無需 Eject
- 經過 Vue CLI 建立的項目讓你無需 eject(計算機命令) 就可以配置工具的幾乎每一個角落
————————————————————————————————————————————————————————————
開發
————————————————————————————————————————————————————————————
瀏覽器兼容性
browserslist
- package.json 文件裏的 browserslist 字段 (或一個單獨的 .browserslistrc 文件),指定了項目的目標瀏覽器的範圍
- 這個值會被 @babel/preset-env 和 Autoprefixer 用來肯定須要轉譯的 JavaScript 特性和須要添加的 CSS 瀏覽器前綴
Polyfill(是一塊代碼,用來爲舊瀏覽器提供它沒有原生支持的較新的功能。)
useBuiltIns: 'usage'(@vue/babel-preset-env 的配置)
- 一個默認的 Vue CLI 項目會使用 @vue/babel-preset-app,它經過 @babel/preset-env 和 browserslist 配置來決定項目須要的 polyfill
- 默認狀況下,它會把 useBuiltIns: 'usage' 傳遞給 @babel/preset-env,這樣它會根據源代碼中出現的語言特性自動檢測須要的 polyfill。這確保了最終包裏 polyfill 數量的最小化。
- 若是其中一個依賴須要特殊的 polyfill,默認狀況下 Babel 沒法將其檢測出來
- 依賴須要 polyfill,你有幾種選擇
- 若是該依賴交付 ES5 代碼,但使用了 ES6+ 特性且沒有顯式地列出須要的 polyfill (例如 Vuetify):請使用 useBuiltIns: 'entry' 而後在入口文件添加 import '@babel/polyfill'。會根據 browserslist 目標導入全部 polyfill
- Vuetify:一種 vue 移動端的組件庫
- Vuetify應該交付了遵循ES5語法的代碼(例如:使用var而不是let,cont),可是卻用了ES5不支持的對象或對象方法,因此不須要再對該依賴進行語法轉換,而只須要導入 polyfill用來支持ES6+ 的新特性
- 但第二種方法也能實現這個功能,並且更好,爲何要採用這種呢?
- 若是該依賴基於一個目標環境不支持的 ES 版本撰寫: 將其添加到 vue.config.js 中的 transpileDependencies 選項。這會爲該依賴同時開啓語法語法轉換和根據使用狀況檢測 polyfill
- 若是該依賴交付了 ES5 代碼並顯式地列出了須要的 polyfill: 你可使用 @vue/babel-preset-app 的 polyfills 選項預包含所須要的 polyfill。(以下在 babel.config.js配置)
- es6.promise 將被默認包含,由於如今的庫依賴 Promise 是很是廣泛的。
- 推薦以這種方式添加 polyfill 而不是在源代碼中直接導入它們,由於若是這裏列出的 polyfill 在 browserslist 的目標中不須要,則它會被自動排除。
module.exports = {
transpileDependencies: [
'webpack-dev-server/client',
],
}
// babel.config.js
module.exports = {
presets: [
['@vue/app', {
polyfills: [
'es6.promise',
'es6.symbol' // 一種新的數據類型,表示獨一無二的對象
]
}]
]
}
構建庫或是 Web Component 時的 Polyfills
- 當使用 Vue CLI 來構建一個庫或是 Web Component 時,推薦給 @vue/babel-preset-env 傳入 useBuiltIns: false 選項。這可以確保你的庫或是組件不包含沒必要要的 polyfills。一般來講,打包 polyfills 應當是最終使用你的庫的應用的責任。
現代模式
vue-cli-service build --modern
會產生兩個應用的版本:一個現代版的包,面向支持 ES modules 的現代瀏覽器,另外一箇舊版的包,面向不支持的舊瀏覽器。
- 現代版的包會經過 <script type="module"> 在被支持的瀏覽器中加載;
- <script type="module"> 代碼會被看成JavaScript模塊
- 須要配合始終開啓的 CORS 進行加載,這意味着服務器必須返回諸如 Access-Control-Allow-Origin: * 的有效的 CORS 頭。(模塊加載都是經過CORS得到的因此始終須要服務器返回)
- 若是須要經過認證來獲取腳本,能夠將script標籤的 crossorigin 選項設置爲 use-credentials(文檔中爲了獲取該JS文件而發起的請求會帶cookie,經過 vue.config.js的 crossorigin 配置)
<script type="module">
import message from './message.js'
console.log(message) // hello world
</script>
<script nomodule>
alert('your browsers can not supports es modules! please upgrade it.')
</script>
<script src="" crossorigin="use-credentials"></script>
- 它們還會使用 <link rel="modulepreload" href=''> 讓瀏覽器優先加載模塊
- modulepreload的行爲相似於preload
- preload可以指明哪些資源是在頁面加載完成後即刻須要的。對於這種即刻須要的資源在頁面加載的生命週期的早期階段就開始獲取,在瀏覽器的主渲染機制介入前就進行預加載。
- 舊版的包會經過 <script nomodule> 加載,並會被支持 ES modules 的瀏覽器忽略。(這是由於瀏覽器默認只解析 type="text/javascript"的腳本,而若是不填寫type屬性則默認爲text/javascript。這樣就實現了向前兼容)
- 一個針對 Safari 10 中 <script nomodule> 的修復會被自動注入(使用一段內聯腳原本避免 Safari 10 重複加載腳本包)。
- 若是你在使用一套嚴格的 CSP(內容安全策略),你須要這樣顯性地容許內聯腳本:
Content-Security-Policy: script-src 'self' 'sha256-4RS22DYeB7U14dra4KcQYxmwt5HkOInieXK1NUMBmQI='
- 內聯腳本是指
<script src=''>
和嵌入式腳本進行區分
- Content-Security-Policy:一種響應報頭。本來頁面上帶src的元素資源是不受同源限制的,Content-Security-Policy是改變這種現狀的新安全策(內容安全政策)
- script-src表明是一個指令,指示瀏覽器你只能加載我屁股後面那些規則下的js代碼,其餘的都一概拒絕。
- 'self' 表示與當前來源(而不是其子域)匹配。
- 最後的base64字符串是一份白名單,和script的特定屬性配合使用,標明哪些內聯js容許經過(白名單)
- Content-Security-Policy(內容安全策略還有其餘應用方式,將在專題中深刻)
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa src=''></script>
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' // 指明瞭屬性名爲nonce
————————————————————————————————————————————————————————————
HTML和靜態資源
HTML
Index 文
public/index.html
文件是一個會被 html-webpack-plugin 處理的模板。在構建過程當中,資源連接會被自動注入。
- 會自動注入 resource hint 資源提示(preload/prefetch、manifest 和圖標連接 (當用到 PWA 插件時) 以及構建過程當中處理的 JavaScript 和 CSS 文件的資源連接。
- manifest:屬性規定文檔的緩存 manifest 的位置。是一個簡單的文本文件,列舉出了瀏覽器用於離線訪問而緩存的資源。
- 每一個指定了 manifest 的頁面在用戶對其訪問時都會被緩存。也能夠在文件中聲明要緩存的頁面
- manifest 文件的建議的文件擴展名是:".appcache"。(具體將在在緩存章節整理)
- 圖標連接 (當用到 PWA 插件時) ?
<!DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>
插值
- 由於 index 文件被用做模板,因此你可使用 lodash 的 template 語法插入內容: ?
- lodash:一個一致性、模塊化、高性能的 JavaScript 實用工具庫。
<%= VALUE %>
用來作不轉義插值;
<%- VALUE %>
用來作 HTML 轉義插值;
<% expression %>
用來描述 JavaScript 流程控制。
// 不轉義插值
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<p><%= 'abc' %></p>
// HTML 轉義插值
// 用來描述 JavaScript 流程控制
<% for (var index in htmlWebpackPlugin.options.title) { %>
<p><%= htmlWebpackPlugin.options.title[index] %></p>
<% } %>
- 可使用被 html-webpack-plugin 暴露的默認值 ()
- vue.config.js 內 pages 各個頁面的參數?
- 全部客戶端環境變量也能夠直接使用 (後文介紹到,在.env文件中設置,必須以 VUE_APP_ 開頭)
Preload
<link rel="preload">
是一種 resource hint(資源提示),用來指定頁面加載後很快會被用到的資源
- 默認狀況下,一個 Vue CLI 應用會爲全部初始化渲染須要的文件自動生成 preload 提示。
- 這些提示會被 @vue/preload-webpack-plugin 注入,而且能夠經過 chainWebpack 的 config.plugin('preload') 進行修改和刪除(詳情見下文)
Prefetch
<link rel="prefetch">
是一種 resource hint,用來告訴瀏覽器在頁面加載完成後,利用空閒時間提早獲取用戶將來可能會訪問的內容。
- 默認狀況下,一個 Vue CLI 應用會爲全部做爲 async chunk 生成的 JavaScript 文件自動生成 prefetch 提示。(import()方法導入的異步模塊,詳見模塊導入導出)
- 這些提示會被 @vue/preload-webpack-plugin 注入,而且能夠經過 chainWebpack 的 config.plugin('prefetch') 進行修改和刪除。
- 刪除後,異步模塊依然會被單獨打包,可是 webpack 的運行時不會在父級區塊被加載以後注入
// 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 的內聯註釋手動選定要提早獲取的代碼區塊,webpack 的運行時會在父級區塊被加載以後注入 prefetch 連接
- 若是你的應用很大且有不少 async chunk,而用戶主要使用的是對帶寬較敏感的移動端,那麼你可能須要關掉 prefetch 連接並手動選擇要提早獲取的代碼區塊。
- 在webpack提供的註釋中並無這個選項;被禁用是指上文提到的移除這個插件嗎?
import(/* webpackPrefetch: true */ './someAsyncComponent.vue')
————————————————————————————————————————
不生成 index
- 當基於已有的後端使用 Vue CLI 時,你可能不須要生成 index.html,這樣生成的資源能夠用於一個服務端渲染的頁面
- 硬編碼的文件名不利於實現高效率的緩存控制。(什麼是服務端渲染?組件在服務端渲染後還須要緩存嗎?)
- 硬編碼的文件名也沒法很好的進行 code-splitting (代碼分段),由於沒法用變化的文件名生成額外的 JavaScript 文件。?
- 硬編碼的文件名沒法在現代模式下工做。?
- 應該考慮換用 indexPath 選項將生成的 HTML 用做一個服務端框架的視圖模板。
// vue.config.js
module.exports = {
// 去掉文件名中的 hash,服務端引用能夠寫死
filenameHashing: false,
// 刪除 HTML 相關的 webpack 插件
chainWebpack: config => {
config.plugins.delete('html') // 僅僅刪除html會致使preload和prefetch注入時報錯
config.plugins.delete('preload')
config.plugins.delete('prefetch')
}
}
————————————————————————————————————————
構建一個多頁應用
- Vue CLI 支持使用 vue.config.js 中的 pages 選項構建一個多頁面的應用。
- 構建好的應用將會在不一樣的入口之間高效共享通用的 chunk 以得到最佳的加載性能。
// vue.config.js配置
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板來源
template: 'public/index.html',
// 在 dist/index.html 的輸出
// 也能夠寫爲`'index/index.html'`這樣,html會被打包到index目錄內,可是引用的其餘資源不會概括到一塊兒。感受沒有任何意義
// 若是須要部署到根目錄如下的次一級目錄中,應當修改 process.env.BASE_URL 值,並修改全部絕對引用。因此使用絕對引用時,應當以 process.env.BASE_URL 爲前綴。見下文 public 文件夾 的詳細說明
filename: 'index.html',
// 當使用 title 選項時,
// template 中的 title 標籤須要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: 'Index Page',
// 在這個頁面中包含的塊,默認狀況下會包含
// 提取出來的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
one: {
entry: 'src/one/main.js',
template: 'public/index.html',
filename: 'one.html',
title: 'one Page',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
// 當使用只有入口的字符串格式時,
// 模板會被推導爲 `public/subpage.html`
// 而且若是找不到的話,就回退到 `public/index.html`。
// 輸出文件名會被推導爲 `subpage.html`。
subpage: 'src/subpage/main.js'
}
}
// 每一個單頁面的路由
export default new Router({
mode: 'history',
// 會依據基路由的path去服務器上獲取對應名稱的html,而後才調用該頁面的路由實行渲染。例如,這裏會先獲取one.html頁面,而後加載之上的路由實現渲染。
// 搜索範圍可能包括`/one.html``/one/index.html``/one/one.html`
base: `${process.env.BASE_URL}one`,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
// route level code-splitting 路由級代碼拆分
// this generates a separate chunk (about.[hash].js) for this route 這將爲此路由生成一個單獨的塊 about.[hash].js
// which is lazy-loaded when the route is visited. 當路線被訪問時,它被延遲加載
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
}
]
})
// 經過a標籤在頁面中實現跨頁面跳轉
<a href="/one/about">one About</a>
處理靜態資源
- 在 JavaScript 被導入或在 template/CSS 中經過相對路徑被引用。這類引用會被 webpack 處理。
- 在 JavaScript 被導入
- babel 語法轉換和引入polyfill
- chunk:分爲供應商塊(經過npm安裝的塊)、通用塊(項目內自定義公共組件到達必定的代碼級別才獨立打包,小型的公共組件會被獨立打包到各個異步塊中)、異步塊、app塊(bundle 塊)
- base64文件名,實現優化緩存
- template 中經過相對路徑被引用,例如
<img src="...">
- base64文件名,實現優化緩存
- 圖片轉爲data內嵌
- CSS 中經過相對路徑被引用
- 圖片轉爲data內嵌
- 本地環境css都是被內嵌的
- 依據目標瀏覽器添加前綴
- base64文件名,實現優化緩存
- css中的引用也會被處理,例如
background-image: url(./assets/bg.gif);
- 本地開發環境服務時css樣式都是嵌入式的,而且都不作base64文件名處理
- 放置在 public 目錄下或經過絕對路徑被引用。這類資源將會直接被拷貝,而不會通過 webpack 的處理。
從相對路徑導入
- 在 JavaScript、CSS 或 *.vue 文件中使用相對路徑 (必須以 . 開頭) 引用一個靜態資源時,該資源將會被包含進入 webpack 的依賴圖中。
- 經過webpack設置的@路徑,本質上也是相對路徑引用
- ../ 表明上一級目錄,也是以.開頭的
- 在其編譯過程當中,全部諸如 <img src="...">、background: url(...) 和 CSS @import 的資源 URL 都會被解析爲一個模塊依賴。
- @import url("fineprint.css");
<img src="./image.png">
// 將會被編譯爲:
h('img', { attrs: { src: require('./image.png') }})
- 在其內部,咱們經過 file-loader 用版本哈希值和正確的公共基礎路徑來決定最終的文件路徑(公共基礎路徑是指,例如打包好的js會被統一放到dist\js文件夾中,那麼html內部的引用也要隨之改變)
- 再用 url-loader 將小於 4kb 的資源內聯,以減小 HTTP 請求的數量。
- 能夠經過 chainWebpack 調整內聯文件的大小限制。例如,下列代碼會將其限制設置爲 10kb:
// 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 是一個絕對路徑 (例如 /images/foo.png),它將會被保留不變。例如:
<img alt="Vue logo" src="/assets/logo.png">
(該路徑指向的資源及路徑自己不會被處理,即html被加載後依然向 /assets/去請求logo.png這個圖片)
- 若是 URL 以 . 開頭,它會做爲一個相對模塊請求被解釋且基於你的文件系統中的目錄結構進行解析。
- 若是 URL 以 ~ 開頭,其後的任何內容都會做爲一個模塊請求被解析。這意味着你甚至能夠引用 Node 模塊中的資源(只發現 css下的用法,不明白這句什麼含義?)
- 若是 URL 以 @ 開頭,它也會做爲一個模塊請求被解析。它的用處在於 Vue CLI 默認會設置一個指向
<projectRoot>/src
的別名 @。僅做用於模版中?(並不僅在模板中被使用,JS中也可使用,CSS比較特殊請參考後文)
public 文件夾
- 任何放置在 public 文件夾的靜態資源都會被簡單的複製,而不通過 webpack。你須要經過絕對路徑來引用它們。(會被直接複製到 /dist 目錄下)
- 咱們推薦將資源做爲你的模塊依賴圖的一部分導入,這樣它們會經過 webpack 的處理並得到以下好處:
- 腳本和樣式表會被壓縮且打包在一塊兒,從而避免額外的網絡請求。
- 文件丟失會直接在編譯時報錯,而不是到了用戶端才產生 404 錯誤。
- 最終生成的文件名包含了內容哈希,所以你沒必要擔憂瀏覽器會緩存它們的老版本。
- 會自動生成合適的引用路徑,沒必要擔憂部署問題
- public 目錄提供的是一個應急手段,當你經過絕對路徑引用它時,留意應用將會部署到哪裏。若是你的應用沒有部署在域名的根部,那麼你須要爲你的 URL 配置 publicPath 前綴:
- 絕對路徑引用時必須以 process.env.BASE_URL 爲前綴,這是爲了方便項目的往後維護
- 能夠把process.env.BASE_URL視爲項目部署時的前綴目錄
// 在 public/index.html 或其它經過 html-webpack-plugin 用做模板的 HTML 文件中,你須要經過 <%= BASE_URL %> 設置連接前綴:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
// 在模板中,你首先須要向你的組件傳入基礎 URL:
data () {
return {
publicPath: process.env.BASE_URL
}
}
<img :src="`${publicPath}my-image.png`">
什麼時候使用 public 文件夾
- 你須要在構建輸出中指定一個文件的名字。?
- 你有上千個圖片,須要動態引用它們的路徑 ?
- 有些庫可能和 webpack 不兼容,這時你除了將其用一個獨立的 <script> 標籤引入沒有別的選擇。
————————————————————————————————————————————————————————————
CSS相關
- Vue CLI 項目天生支持 PostCSS、CSS Modules 和包含 Sass、Less、Stylus 在內的預處理器
引用靜態資源
- 全部編譯後的 CSS 都會經過 css-loader 來解析其中的 url() 引用,並將這些引用做爲模塊請求來處理。
- 能夠根據本地的文件結構用相對路徑來引用靜態資源
- 若是你想要引用一個 npm 依賴中的文件 ?,或是想要用 webpack alias(別名),則須要在路徑前加上 ~ 的前綴來避免歧義。例如:
// 用 webpack alias(別名)
background-image: url(~@/one/assets/logo.png);
預處理器
- 能夠在建立項目的時候選擇預處理器 (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'),
],
})
}
PostCSS
- 能夠經過 .postcssrc 或任何 postcss-load-config 支持的配置源來配置 PostCSS
- package.json (vue create初始化項目時能夠選擇)
- .postcssrc.json 或 .postcssrc.yml 或 .postcssrc.js
- postcss.config.js (腳手架默認)
- 也能夠經過 vue.config.js 中的 css.loaderOptions.postcss 配置 postcss-loader。
- 咱們默認開啓了 autoprefixer。在生產環境構建中,Vue CLI 會優化 CSS 並基於目標瀏覽器拋棄沒必要要的瀏覽器前綴規則。
- 若是要配置目標瀏覽器,可以使用 package.json 的 browserslist 字段或 .browserslistrc 這個文件
CSS Modules
- 能夠經過 <style module> 以開箱即用的方式在 *.vue 文件中使用 CSS Modules。
- 已經默認經過向 css-loader 傳入 modules: true 開啓
- CSS Modules 把 CSS 類名的集合做爲計算屬性 $style 綁定到 VUE 實例上
- 即便是嵌套中的類名都會進行處理,例以下例中的 bold
- 這是一個計算屬性,因此它支持 :class 的對象/數組語法綁定,也能夠經過 JavaScript 訪問到它
- CSS Modules 默認基於文件名和類名生成標識符,例如:App_app_7GWKZ
- CSS Modules 和 scoped CSS 的區別在於前者是動態生成 CSS類名,然後者是經過添加特性配合CSS屬性選擇器使用
<style module>
.red {
color: red;
.bold {
font-weight: bold;
}
}
</style>
<template>
<p :class="$style.red">
This should be red
</p>
</template>
- 在 .vue 中你能夠定義不止一個 <style>,爲了不被覆蓋,你能夠經過設置 module 屬性來爲它們定義注入後計算屬性的名稱。
<style module="a"> // 經過this.a來訪問
/* 注入標識符 a */
</style>
<style module="b"> // 經過this.b來訪問
/* 注入標識符 b */
</style>
- 在 JavaScript 中做爲 CSS Modules 導入 CSS 或其它預處理文件,該文件應該以 .module.(css|less|sass|scss|styl) 結尾
import styles from './foo.module.css' // 導入的文件必須帶有module,返回一個對象,做爲計算屬性的返回使用
// 全部支持的預處理器都同樣工做
import sassStyles from './foo.module.scss'
- 若是你想去掉文件名中的 .module,能夠設置 vue.config.js 中的 css.modules 爲 true
// vue.config.js
module.exports = {
css: {
modules: true
}
}
- 若是你但願自定義生成的 CSS Modules 模塊的類名,能夠經過 vue.config.js 中的 css.loaderOptions.css 選項來實現。全部的 css-loader 選項在這裏都是支持的,例如 localIdentName 和 camelCase
// vue.config.js
module.exports = {
css: {
loaderOptions: {
css: {
localIdentName: '[name]-[hash]',
camelCase: 'only' // 駝峯式?
}
}
}
}
向預處理器 Loader 傳遞選項
- 向 webpack 的預處理器 loader 傳遞選項。
// vue.config.js
module.exports = {
css: {
loaderOptions: {
// 給 sass-loader 傳遞選項
sass: {
// @/ 是 src/ 的別名
// 因此這裏假設你有 `src/variables.scss` 這個文件
data: `@import "@/variables.scss";`
}
}
}
}
- 這樣作比使用 chainWebpack 手動指定 loader 更推薦,由於這些選項須要應用在使用了相應 loader 的多個地方。
- Loader 能夠經過 loaderOptions 配置,包括:
- css-loader
- postcss-loader
- sass-loader
- less-loader
- stylus-loader
————————————————————————————————————————————————————————————
webpack相關
簡單的配置方式
- 調整 webpack 配置最簡單的方式就是在 vue.config.js 中的 configureWebpack 選項提供一個對象:
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new MyAwesomeWebpackPlugin()
]
}
}
- 有些 webpack 選項是基於 vue.config.js 中的值設置的,因此不該該直接修改。由於 vue.config.js 中的值會被用在配置裏的多個地方,以確保全部的部分都能正常工做在一塊兒。
- 若是你須要基於環境有條件地配置行爲,或者想要直接修改配置,那就換成一個函數 (該函數會在環境變量被設置以後懶執行)。該方法的第一個參數會收到已經解析好的配置。在函數內,你能夠直接修改配置,或者返回一個將會被合併的對象:
// vue.config.js
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 爲生產環境修改配置...
} else {
// 爲開發環境修改配置...
}
}
}
鏈式操做 (高級)
- Vue CLI 內部的 webpack 配置是經過 webpack-chain 維護的。它容許咱們更細粒度的控制其內部配置。
修改 Loader 選項
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
// 修改它的選項...
return options
})
}
}
- 對於 CSS 相關 loader 來講,咱們推薦使用 css.loaderOptions 而不是直接鏈式指定 loader。這是由於每種 CSS 文件類型都有多個規則,而 css.loaderOptions 能夠確保你經過一個地方影響全部的規則。
添加一個新的 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
// vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// 清除已有的全部 loader。
// 若是你不這樣作,接下來的 loader 會附加在該規則現有的 loader 以後。
svgRule.uses.clear()
// 添加要替換的 loader
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
}
修改插件選項
// vue.config.js
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
return [/* 傳遞給 html-webpack-plugin's 構造函數的新參數 */]
})
}
}
- 將 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 => {
args[0].template = '/Users/username/proj/app/templates/index.html'
return args
})
}
}
審查項目的 webpack 配置
- 全局的 vue 可執行程序一樣提供了 inspect 命令,這個命令只是簡單的把 vue-cli-service inspect 代理到了你的項目中。
- 將其輸出重定向到一個文件以便進行查閱:(輸出的並非一個有效的 webpack 配置文件,而是一個用於審查的被序列化的格式。)
vue inspect > output.js
# 只審查第一條規則
vue inspect module.rules.0
vue inspect --rule vue
vue inspect --plugin html
vue inspect --rules
vue inspect --plugins
以一個文件的方式使用解析好的配置
- 有些外部工具可能須要經過一個文件訪問解析好的 webpack 配置,好比那些須要提供 webpack 配置路徑的 IDE 或 CLI。
// 該文件會動態解析並輸出 vue-cli-service 命令中使用的相同的 webpack 配置,包括那些來自插件甚至是你自定義的配置。
<projectRoot>/node_modules/@vue/cli-service/webpack.config.js
————————————————————————————————————————————————————————————
環境變量和模式
- 能夠替換你的項目根目錄中的下列文件來指定環境變量:
.env # 在全部的環境中被載入
.env.local # 在全部的環境中被載入,但會被 git 忽略
.env.[mode] # 只在指定的模式中被載入,例如生產環境:.env.production
.env.[mode].local # 只在指定的模式中被載入,但會被 git 忽略
FOO=bar
VUE_APP_SECRET=secret
- 被載入的變量將會對 vue-cli-service 的全部命令、插件和依賴可用。
- 爲一個特定模式準備的環境文件的將會比通常的環境文件擁有更高的優先級。
- Vue CLI 啓動時已經存在的環境變量擁有最高優先級,並不會被 .env 文件覆寫。(例如:BASE_URL,Vue CLI 啓動時是指vue-cli-service執行時傳入的參數?已經存在的環境變量是指配置文件的部分參數,例如publicPath(用於配置BASE_URL)?)
- 若是在環境中有默認的 NODE_ENV,你應該移除它或在運行 vue-cli-service 命令的時候明確地設置 NODE_ENV。?
模式
- 一個 Vue CLI 項目有三個模式:
- development 模式用於 vue-cli-service serve
- production 模式用於 vue-cli-service build 和 vue-cli-service test:e2e
- test 模式用於 vue-cli-service test:unit
- 模式不一樣於 NODE_ENV,一個模式能夠包含多個環境變量。每一個模式僅僅只是會將 NODE_ENV 的值設置爲模式的名稱
- 能夠經過爲 .env 文件增長後綴來設置某個模式下特有的環境變量
- 能夠經過傳遞 --mode 選項參數爲命令行覆寫默認的模式。
"dev-build": "vue-cli-service build --mode development"
示例:Staging 模式
- 能夠在系統環境變量中定義 NODE_ENV,這樣能夠實現都使用 production(生產)環境的配置打包,可是傳入不一樣的環境變量
NODE_ENV=production
// 其餘環境變量
在客戶端側代碼中使用環境變量
- 只有以 VUE_APP_ 開頭的變量會被 webpack.DefinePlugin 靜態嵌入到客戶端側的包中(只有嵌入到客戶端側的包中才能被模板使用)
// 能夠在應用的代碼中這樣訪問它們:
console.log(process.env.VUE_APP_SECRET)
- 在構建過程當中,process.env.VUE_APP_SECRET 將會被相應的值所取代。
- 在你的應用代碼中始終可用的還有兩個特殊的變量:
- NODE_ENV - 會是 "development"、"production" 或 "test" 中的一個。(能夠在.env自定義)
- BASE_URL - 會和 vue.config.js 中的 publicPath 選項相符,即你的應用會部署到的基礎路徑。
- 能夠在 vue.config.js 文件中計算環境變量。它們仍然須要以 VUE_APP_ 前綴開頭。(經過 process.env 直接設置環境變量)
// 獲取package.json 中的版本信息,設置爲環境變量
process.env.VUE_APP_VERSION = require('./package.json').version
只在本地有效的變量
- 含有.local的爲本地環境文件,本地環境文件默認會被忽略,且出如今 .gitignore 中。
————————————————————————————————————————————————————————————
構建目標
應用
- index.html 會帶有注入的資源和 resource hint(資源提示)
- 第三方庫會被分到一個獨立包以便更好的緩存(多個打包成一個)
- 小於 4kb 的靜態資源會被內聯在 JavaScript 中
- public 中的靜態資源會被複制到輸出目錄中
庫
- 在庫模式中,項目的 publicPath(基礎路徑) 是根據主文件的加載路徑動態設置的(用以支持動態的資源加載能力)。
- 基礎路徑彷佛只在非模塊引用時須要運用,模塊化圖片和 ‘應用’ 的處理方式一致,非模塊化圖片會保留路徑,可是不會複製 public 文件夾內容到 dist 中
- 這個功能用到了 document.currentScript,而 IE 瀏覽器並不支持這一特性。建議使用庫以前先在頁面上引入 current-script-polyfill。
- document.currentScript 返回其所包含的腳本中正在被執行的 script 元素
- 在庫模式中,Vue 是外置的。這意味着包中不會有 Vue
- 同理依賴 vuex 和 其餘庫編寫的庫都須要引入相應的依賴
- 庫返回的是組件的配置,須要經過 Vue 實例化
- 若是這個庫會經過一個打包器使用,它將嘗試經過打包器以依賴的方式加載 Vue;不然就會回退到一個全局的 Vue 變量。
- 入口能夠是一個 .js 或一個 .vue 文件。若是沒有指定入口,則會使用 src/App.vue
- 構建一個庫會輸出:
- dist/myLib.common.js:一個給打包器用的 CommonJS 包 (不幸的是,webpack 目前還並無支持 ES modules 輸出格式的包)
- 在項目默認配置中使用 require 引用 CommonJS 包時會出現
Cannot assign to read only property 'exports' of object '#<Object>'
報錯,是源於 babel 默認配置不支持在一個文件中同時使用 ES6 和 CommonJS 的導入導出
- dist/myLib.umd.js:一個直接給瀏覽器或 AMD loader 使用的 UMD 包
- AMD loader 瀏覽器異步模塊解決方案
- UMD 通用模塊規範,兼容 AMD 和 CommonJS
- 會暴露一個以庫名爲名稱的全局變量,例如:‘myLib’
- dist/myLib.umd.min.js:壓縮後的 UMD 構建版本
- dist/myLib.css:提取出來的 CSS 文件 (能夠經過在 vue.config.js 中設置 css: { extract: false } 強制內聯)
- css 默認採用 scoped CSS 作爲模塊化方案
Vue vs. JS/TS 入口文件
- 當使用一個 .vue 文件做爲入口時,你的庫會直接暴露這個 Vue 組件自己,由於組件始終是默認導出的內容。
- 當你使用一個 .js 或 .ts 文件做爲入口時,它可能會包含具名導出,因此庫會暴露爲一個模塊。
- 能夠經過 window.yourLib.default 訪問(yourLib爲模塊名)
- 或者在 CommonJS 構建中經過 const myLib = require('mylib').default 訪問
- 若是你沒有任何具名導出並但願直接暴露默認導出,你能夠在 vue.config.js 中使用如下 webpack 配置:
module.exports = {
configureWebpack: {
output: {
libraryExport: 'default'
}
}
}
Web Components 組件
- 這個模式容許你的組件的使用者以一個普通 DOM 元素的方式使用這個 Vue 組件
- 將一個vue組件註冊爲一個自定義元素,不支持 IE11 及更低版本。
- 在 Web Components 模式中,Vue 是外置的。這裏的包會假設在頁面中已經有一個可用的全局變量 Vue。
- 這裏的入口應該是一個 *.vue 文件。
- Vue CLI 將會把這個組件自動包裹並註冊爲 Web Components 組件,無需在 main.js 裏自行註冊。
- 該構建將會產生一個單獨的 JavaScript 文件 (及其壓縮後的版本) 將全部的東西都內聯起來。
- 當這個腳本被引入網頁時,會註冊自定義組件 <my-element>,其使用 @vue/web-component-wrapper 包裹了目標的 Vue 組件。這個包裹器會自動代理屬性、特性、事件和插槽。
<script src="https://unpkg.com/vue"></script>
<script src="path/to/my-element.js"></script>
<!-- 可在普通 HTML 中或者其它任何框架中使用 -->
<my-element></my-element>
註冊多個 Web Components 組件的包
- 當你構建一個 Web Components 組件包的時候,你也可使用一個 glob 表達式做爲入口指定多個組件目標:
- 當你構建多個 web component 時,--name 將會用於設置前綴,同時自定義元素的名稱會由組件的文件名推導得出。好比一個名爲 HelloWorld.vue 的組件攜帶 --name foo 將會生成的自定義元素名爲 <<oo-hello-world>
vue-cli-service build --target wc --name foo 'src/components/*.vue'
異步 Web Components 組件
- 異步 Web Components 模式會生成一個 code-split(代碼分割) 的包,帶一個只提供全部組件共享的運行時,並預先註冊全部的自定義組件小入口文件。一個組件真正的實現只會在頁面中用到自定義元素相應的一個實例時按需獲取:
vue-cli-service build --target wc-async --name foo 'src/components/*.vue'
dist/foo.0.min.js
dist/foo.min.js
dist/foo.1.min.js
dist/foo.js
dist/foo.0.js
dist/foo.1.js
<script src="https://unpkg.com/vue"></script>
<script src="path/to/foo.min.js"></script>
<!-- foo-one 的實現的 chunk 會在用到的時候自動獲取 -->
<foo-one></foo-one>
————————————————————————————————————————————————————————————
部署
通用指南
本地預覽
使用 history.pushState 的路由
CORS
PWA
GitHub Pages
GitLab Pages
Netlify
Amazon S3
Firebase
Now
Stdlib
Heroku
Surge
Bitbucket Cloud