筆者兩年前曾寫過一篇文章《Webpack4 搭建 Vue 項目》,後來隨着 webpack5 和 vue3 的面世,一直想升級下我這個 createVue 項目,可是苦於沒有時間(實際上是由於懶),一直拖延至今。搗鼓了好幾天,終於搭建好整個項目,所以僅以此文記錄升級搭建的過程。html
PS: 其實也能夠用官方腳手架搭建的,爲什麼要本身從頭作起呢?有腳手架我不用,我就折騰。哎,就是玩兒~????前端
爲什麼升級?除了折騰外,即是享受新版本帶給咱們的新特性體驗。vue
Webpack5 的新特性node
此文並非從零搭建,而是在 createVue@v1.0.0 的基礎上修改搭建,如若看不懂,能夠先看《Webpack4 搭建 Vue 項目》,跟着一步步搭建,後再看此文升級webpack
建立 createVue 文件夾,進入該文件夾, npm init 初始化項目ios
老規矩,安裝 webpack 四件套npm i webpack webpack-cli webpack-dev-server webpack-merge --save-devgit
當前使用版本:
"webpack": "^5.33.2",
"webpack-bundle-analyzer": "^4.4.1",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3",
webpack5 啓動開發服務器命令與以前有所變化,從 webpack-dev-server 轉變爲 webpack serve, 所以 package.json 中 script 的 start 修改成: "start": "webpack serve --progress --hot --inline --config build/webpack.dev.js"github
與以前沒有太大差別。增長變更的有一下幾點:web
1). 持久化緩存,增長 cache 配置. v5 中緩存默認是 memory,修改設置"filesystem"寫入硬盤vue-router
// webpack.dev.js
module.exports = merge(common, {
cache: {
type: 'filesystem',
}
//...
}
2). 去除插件 clean-webpack-plugin(v5支持),webpack.HashedModuleIdsPlugin(v5更好的 moduleIds & chunkIds),HardSourceWebpackPlugin(v5支持),happypack(v5不兼容)
安裝 vue 核心解析插件
解析插件有所不一樣,從 vue-template-compiler 變成了 @vue/compiler-sfc, vue-loader 保持不變。 npm i vue-loader @vue/compiler-sfc --save-dev
// 當前我使用版本
"vue-loader": "^16.2.0",
"@vue/compiler-sfc": "^3.0.11",
安裝 vue3 及相關庫,添加 vue 類型文件
npm i vue@next vuex@4.0.0-rc.1 vue-router --save
src 文件夾下添加 shims-vue.d.ts 文件,解決 vue 類型報錯
// shims-vue.d.ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
安裝 html 模板解析插件
npm i html-webpack-plugin --save-dev
安裝 typescript 及解析插件
npm i typescript ts-loader --save-dev
配置ts-loader解析:
// webpack.base.js
// rules
{
test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
// 指定特定的ts編譯配置,爲了區分腳本的ts配置
configFile: path.resolve(__dirname, '../tsconfig.loader.json'),
// 對應文件添加個.ts或.tsx後綴
appendTsSuffixTo: [/\.vue$/],
},
},
],
}
ts-loader 爲單進程執行類型檢查和轉譯,所以效率有些慢,能夠用多進程方案:即關閉ts-loader的類型檢查,類型檢查由 fork-ts-checker-webpack-plugin 插件執行。npm i fork-ts-checker-webpack-plugin --save-dev
// webpack.base.js
// rules
{
test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
// 指定特定的ts編譯配置,爲了區分腳本的ts配置
configFile: path.resolve(__dirname, '../tsconfig.loader.json'),
// 對應文件添加個.ts或.tsx後綴
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true, // ? 關閉類型檢查,即只進行轉譯
},
},
],
}
// plugins push
new ForkTsCheckerWebpackPlugin()
至此項目基本能夠跑起來了,那麼有個問題了:Ts 能夠編譯爲指定版本的 js,那麼還須要 babel 麼?
tsc 的 target 只轉譯語法,不集成 polyfill,因此仍是得要 babel。
好比把箭頭函數轉成普通 function、aysnc + await 變成 Promise.then,這是語法轉譯;
但你運行環境裏若是沒有 Promise.prototype.finally,那沒有就仍是沒有。
所以咱們項目裏仍是須要 babel.
Webpack 轉譯 Typescript 現有方案:
綜合考慮性能和擴展性,目前比較推薦的是 babel+fork-ts-checker-webpack-plugin 方案。
在 babel7 以前,是須要同時使用 ts-loader 和 babel-loader 的,其編譯過程 TS > TS 編譯器 > JS > Babel > JS 。可見編譯了兩次js,效率有些低下。可是 babel7 出來以後有了解析 typescript 的能力,有了這一層面的支持,咱們就能夠只使用 babel,而不用再加一輪 ts 的編譯流程了。
在 babel 7 中,咱們使用新的 @babel/preset-typescript 預設,結合一些插件即可以解析大部分的 ts 語法。
那麼,Babel 是如何處理 TypeScript 代碼的呢?
Babel 刪除了全部 TypeScript,將其轉換爲常規的 JavaScript,並繼續以它本身的方式處理。刪除了 typescript 則不須要進行類型檢查,不會有煩人的類型錯誤提醒,所以編譯速度提高,開開心心編程????
固然,類型安全性檢查必不可少,咱們能夠統一在某個時間集中處理,增長 script:
"check-types": "tsc --watch",
添加 babel 解析 typescript
# 安裝如下依賴 --save-dev
# webpack loader
babel-loader
# babel 核心
@babel/core
# 智能轉換成目標運行環境代碼
@babel/preset-env
# 解析 typescript 的 babel 預設
@babel/preset-typescript
# polyfill
@babel/plugin-transform-runtime
# 支持 ts 類的寫法
@babel/plugin-proposal-class-properties
# 支持三點展開符
@babel/plugin-proposal-object-rest-spread
# 安裝如下依賴 --save
@babel/runtime
@babel/runtime-corejs3
"core-js": "^3.11.0",
刪除 ts-loader, 添加 babel-loader
{
test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
},
],
}
項目根目錄添加 babel 配置文件 babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage', // 按需引入 polyfill
corejs: 3,
},
],
[
'@babel/preset-typescript', // 引用Typescript插件
{
allExtensions: true, // 支持全部文件擴展名,不然在vue文件中使用ts會報錯
},
],
],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3,
},
],
'@babel/proposal-class-properties',
'@babel/proposal-object-rest-spread',
],
}
項目中代碼規範集成了 EditorConfig, Prettier, ESLint, Husky, Lint-staged,以及如何解決 Prettier 和 ESLint 的衝突的問題,具體實現能夠參考 《從 0 開始手把手帶你搭建一套規範的 Vue3.x 項目工程環境》這篇文章,講的很詳細這裏再也不贅述。
利用 inquirer 選擇配置好的提交類型,以及配合 commitlint 實現 commit 檢查
npm i inquirer shelljs @commitlint/{cli,config-conventional} -D
添加 package.json 的 script :
"commitlint": "commitlint -e",
"commit": "node commit/git-commit.js"
建立 commit/git-commit.js 文件
const shell = require('shelljs')
const inquirer = require('inquirer')
const prompsConfig = {
ciType: [
{
type: 'list',
name: 'type',
message: '請選擇本次提交的類型:',
choices: [
{
name: '引入新特性',
value: 'feat',
},
{
name: '改進代碼的結構格式/樣式',
value: 'style',
},
{
name: '修復 bug',
value: 'fix',
},
{
name: '提高性能',
value: 'perf',
},
{
name: '刪除代碼或文件',
value: 'delete',
},
{
name: '其餘修改, 好比改變構建流程、或者增長依賴庫、工具等',
value: 'chore',
},
{
name: '重構',
value: 'refactor',
},
{
name: '撰寫文檔',
value: 'docs',
},
{
name: '增長測試',
value: 'test',
},
{
name: '更新打包文件',
value: 'build',
},
{
name: '初次提交',
value: 'init',
},
{
name: '發佈/版本標籤',
value: 'release',
},
{
name: '部署功能',
value: 'deploy',
},
{
name: '代碼回滾',
value: 'revert',
},
{
name: 'CI持續集成修改',
value: 'ci',
},
],
},
],
ciMsg: {
type: 'input',
name: 'msg',
message: '請輸入提交文本:',
validate: function (value) {
if (value) {
return true
}
return '文本必須輸入!'
},
},
}
async function gitCommit() {
let { type } = await inquirer.prompt(prompsConfig.ciType)
let { msg } = await inquirer.prompt(prompsConfig.ciMsg)
shell.exec(`git commit -m "${type}: ${msg}"`, function () {
console.log(`\n提交腳本: git commit -m "${type}: ${msg}"`)
})
}
gitCommit()
配置 commitlint 類型,建立 commitlint.config.js 文件:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'build', 'chore', 'ci', 'feat', 'docs', 'fix', 'perf', 'revert', 'refactor', 'style', 'test', 'init', 'build', 'release', 'delete'
]],
}
};
完成上述操做後,git add 相關文件,執行 npm run commit 便可執行 commit 校驗
Travis CI 是一款構建和測試的自動化工具,不只能夠提升效率,還能使開發流程更可靠和專業化,從而提升軟件的價值。並且,它對於開源項目是免費的,不花一分錢,就能幫你作掉不少事情。詳細介紹能夠查看 阮一峯——《持續集成服務 Travis CI 教程》
首先,訪問官方網站 travis-ci.org,點擊右上角的我的頭像,使用 Github 帳戶登入 Travis CI。
找到對應的倉庫,打開開關添加倉庫
在 github 上 setting/Developer settings/Personal access token 處生成 travis token
點擊對應倉庫的 setting
設置環境變量 GITHUB_TOKEN 爲剛纔 github 處生成的 token
建立 .travis.yml 配置文件:
language: node_js
node_js:
- 12
branchs:
only:
- master
cache:
directories:
- node_modules
install:
- yarn install
scripts:
- yarn build
deploy:
provider: pages
local_dir: dist
skip_cleanup: true
# 在 GitHub 上生成的令牌,容許 Travis 推送代碼到你的倉庫。
# 在倉庫對應的 Travis 設置頁面中配置,用於安全控制。
github_token: $GITHUB_TOKEN
keep_history: true
on:
branch: master
這樣,當你 push 到 master 或者 pr 合併到 master 的時候,就會觸發部署腳本的執行,將生成的 dist 推送至 gh-pages 分支
搗鼓了挺長一段時間,也瞭解了蠻多工程化的東西,雖然不必定能用於實際項目中,但仍是算有所收穫吧!
END
推薦閱讀 點擊標題可跳轉