0x00 前言
本文將從結構、功能等方面講解下專案 vue-code-view
的搭建過程,您可以瞭解以下內容:
- 使用
vue cli 4
從0搭建一個元件庫及細緻配置資訊。 - 專案的多環境構建配置。
- 專案網站的釋出部署、持續整合。
- 專案NPM包釋出。
- 專案元件的自定義
Markdown
解析loader
。
本文算是 ?Element 2 原始碼學習系列 的擴充篇內容,通過之前的文章瞭解了開源元件庫的結構原理後,自己也搭建個元件專案怎麼辦?接下來就是實踐的過程,算是"知行合一"了吧! 耐心讀完,相信會對您有所幫助!
0x01 專案概述
建立專案
本專案使用 Vue CLI 4.x
進行專案建立。
// 安裝環境
npm install -g @vue/cli
// 建立專案
vue create vue-code-view
在終端中輸入命令後,按照以下步驟操作建立專案:
- 選擇手動選擇功能
Manually select features
。 - 選中
Babel
,Router
,CSS Pre-processors
,Linter / Formatter
等功能 。 - 選擇
vue
版本2.X
- 選擇路由是否使用
history
模式,預設yes
。 - 選擇CSS 前處理器
Sass/SCSS(with node-sass)
。 - 選擇程式碼風格、格式校驗
linter / formatter
配置ESLint + Prettier
。 - 選擇校驗時機儲存時檢測
Lint on save
- 選擇
Babel
,ESLint
等配置檔案存放在專用配置檔案中In dedicated config files
。
配置多環境變數
在專案根目錄中新建 .env
, .env.deploy
,.env.production
等檔案。
以 VUE_APP
開頭的變數會被 webpack.DefinePlugin
靜態嵌入到客戶端側的包中,程式碼中可以通過 process.env.VUE_APP[xxx]
訪問。
NODE_ENV
和BASE_URL
是兩個特殊變數,在程式碼中始終可用。
.env
vue-cli-service serve
預設的本地開發環境配置
NODE_ENV = development
VUE_APP_PUBLIC_PATH = /
.env.production
vue-cli-service build
預設的環境配置(正式伺服器)
NODE_ENV = production
VUE_APP_PUBLIC_PATH = /
VUE_APP_ENV = pub
.env.deploy
用於 github pages 構建部署的環境配置。VUE_APP_PUBLIC_PATH
設定 /vue-code-view
用於虛擬目錄。
NODE_ENV = production
VUE_APP_PUBLIC_PATH = /vue-code-view
VUE_APP_ENV = deploy
目錄結構調整
預設的 src
目錄下存放專案原始碼及需要引用的資原始檔。根目錄下新建 examples
資料夾用於專案示例網站,將src
目錄下檔案移至 examples
檔案 。src
目錄存放專案元件原始碼。
調整後根目錄檔案結構如下:
├── examples // 專案示例網站
| ├── App.vue
| ├── assets
| ├── components
| ├── main.js
| ├── router
| └── views
├── src // 專案元件原始碼
| ├── fonts
| ├── index.js
| ├── locale
| ├── mixins
| ├── src
| ├── styles
| └── utils
├── public
├── package.json
配置基礎 vue.config.js
專案預設入口./src/main.js
,配置如下:
{
entry: {
app: [
'./src/main.js'
]
}
}
在根目錄下建立 vue.config.js
修改預設配置。
const path = require("path");
const resolve = (dir) => path.join(__dirname, dir);
module.exports = {
configureWebpack: (config) => {
// 專案入口
config.entry.app = "./examples/main.js";
},
chainWebpack: (config) => {
// 新增別名
config.resolve.alias
.set("vue$", "vue/dist/vue.esm.js")
.set("@", resolve("examples"))
.set("@assets", resolve("examples/assets"))
.set("@src", resolve("src"))
.set("@views", resolve("examples/views"))
.set("@router", resolve("examples/router"))
.set("@store", resolve("examples/store"));
},
};
執行 npm run serve
, 專案網站正常執行。
0x02 專案構建
npm scripts 配置
調整 package.json
裡的 scripts
配置指令碼,並新增 --mode xxx
來選擇不同環境配置。
"scripts": {
// 開發環境 啟動專案示例網站
"dev": "vue-cli-service serve ",
// 元件庫構建
"dist": "vue-cli-service build --mode production --target lib --name vue-code-viewer --dest lib src/index.js",
// 專案示例網站構建
"deploy:build": "vue-cli-service build --mode deploy"
}
元件構建
元件庫構建通過指定入口檔案src/index.js
、設定引數選項。
用法:vue-cli-service build [options] [entry|pattern]
引數選項:
--mode 指定環境模式 (預設值:production)
--dest 指定輸出目錄 (預設值:dist)
--target app | lib | wc | wc-async (預設值:app)
--name 庫或 Web Components 模式下的名字 (預設值:package.json 中的 "name" 欄位或入口檔名)
構建一個庫會輸出:
lib/vue-code-viewer.common.js
:一個給打包器用的 CommonJS 包 。lib/vue-code-viewer.umd.js
:一個直接給瀏覽器或 AMD loader 使用的 UMD 包。lib/vue-code-viewer.umd.min.js
:壓縮後的 UMD 構建版本。lib/vue-code-viewer.css
:提取出來的 CSS 檔案。
元件NPM包釋出
配置 package.json
檔案中屬性值用於npm 釋出。
- name: 包名,該名字是唯一的。需要去npm registry檢視名字是否已被使用。
- version: 包版本號,版本號規則參考《語義化版本 2.0.0》。每次釋出至 npm 需要修改版本號,不能和歷史版本號相同。
- description: 包的描述,描述這個包的主要功能以及用途。
- main: 入口檔案,該欄位需指向專案編譯後的包檔案。
- unpkg: UMD模式入口包檔案
- keyword:關鍵字,陣列、字串。
- author:包的作者。
- private:是否私有,需要修改為 false 才能釋出到 npm
- license: 開源協議。
- repository:包的Git Repo資訊,包括type和URL。
- homepage:專案官網的url。
更新 package.json
檔案內容:
{
"name": "vue-code-view",
"version": "0.3.9",
"description": "A code editor component based on Vue.js 2 ",
"main": "lib/vue-code-viewer.common.js",
"unpkg": "lib/vue-code-viewer.umd.js",
"scripts": {},
"dependencies": {},
"peerDependencies": {},
"devDependencies": {},
"keywords": [
"vue",
"components",
"codemirror",
"code editor"
],
"repository": {
"type": "git",
"url": "git+https://github.com/andurils/vue-code-view.git"
},
"author": "andurils",
"license": "MIT",
"homepage": "https://andurils.github.io/vue-code-view"
}
加 .npmignore
檔案,設定忽略釋出檔案。釋出到 npm 中檔案,只保留有的 lib 目錄、package.json、README.md。
# 忽略目錄
examples/
node_modules/
public/
build/
src/
dist/
deploy/
# 忽略指定檔案
.browserslistrc
.eslintignore
.prettierignore
.env
.env.*
*.js
接下來 npmjs.com
上註冊賬號登入後,執行 npm publish
命令完成元件包釋出操作。
釋出成功後,進入元件的NPM首頁 npm/vue-code-view, 可以看到上面的專案配置資訊 。
專案示例網站構建
更新 vue.config.js
,執行 npm run deploy:build
構建專案示例網站輸出至 deploy
目錄下。
const path = require("path");
const resolve = (dir) => path.join(__dirname, dir);
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV);
module.exports = {
publicPath: process.env.VUE_APP_PUBLIC_PATH || "/",
productionSourceMap: false,
outputDir: process.env.VUE_APP_ENV === "deploy" ? "deploy" : "dist",
configureWebpack: (config) => {
// 專案入口
config.entry.app = "./examples/main.js"
},
...
};
持續整合
使用 Travis CI
的持續整合服務自動構建專案示例網站並部署至 gh-pages
分支 。
根目錄下新增 .travis.yml
檔案,指定了 Travis 的行為。通過設定一旦程式碼倉庫有新的 Commit,Travis 就會去找這個檔案,執行裡面的命令(執行構建、部署等操作)。
y
sudo: false
language: node_js
node_js: 14
install:
- yarn
script: npm run deploy:build
after_script:
- mkdir temp_web
- cd temp_web
- git clone --depth 1 -b gh-pages --single-branch https://${TravisCI_Token}@${GH_REF} && cd vue-code-view
- echo 'copy && commit'
- rm -rf js fonts
- cp -rf ../../deploy/** .
- git config user.name "${U_NAME}"
- git config user.email "${U_EMAIL}"
- git add -A .
- git commit -m ":construction_worker:- Build & Deploy by Travis CI"
- git push origin gh-pages
- echo "DONE, Bye~"
- exit 0
Travis CI
專案構建後臺:
開啟構建壓縮
安裝相關外掛。
# gzip webpack 4.x 對應 6.x版本
npm i compression-webpack-plugin@6.1.1 -D
# 程式碼壓縮
npm i uglifyjs-webpack-plugin -D
配置 vue.config.js
,開啟外掛。
...
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV);
// gzip壓縮 webpack 4.x 對應 6.x版本 cnpm i compression-webpack-plugin@6.1.1 --save-dev
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
// 程式碼壓縮
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
...
configureWebpack: (config) => {
const plugins = [];
// 生產環境相關配置
if (IS_PROD && process.env.VUE_APP_ENV === "pub") {
plugins.push(
new CompressionWebpackPlugin({
filename: "[path][base].gz",
algorithm: "gzip",
minRatio: 0.99,
test: productionGzipExtensions,
deleteOriginalAssets: false,
})
);
plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
// 刪除註釋
output: {
comments: false,
},
// 刪除console debugger
compress: {
drop_debugger: true,
drop_console: true, // console
pure_funcs: ["console.log"], // 移除console
},
// 刪除警告
warnings: false,
},
sourceMap: false,
parallel: true, //使用多程式並行執行來提高構建速度。預設併發執行數:os.cpus().length - 1。
})
);
}
config.plugins = [...config.plugins, ...plugins];
},
};
元件說明文件
參考element 2
的實現,自定義 build/md-loder
對 Markdown
檔案進行解析渲染,將 examples\docs\zh-CN\example.md
編譯為 HTML。已在前文 04.封裝元件封裝、編寫說明文件 中詳細說明,不再過多贅述。
配置 vue.config.js
,新增 .md
文件的自定義 Markdown Loader
。
module.exports = {
...
configureWebpack: (config) => {
config.resolveLoader.modules = ["node_modules", "./build/"]; // 自定義loader
},
chainWebpack: (config) => {
// Markdown Loader
config.module
.rule("md")
.test(/\.md/)
.use("vue-loader")
.loader("vue-loader")
.end()
// 自定義loader
.use("md-loader")
.loader("md-loader")
.end();
},
};
examples\router\index.js
配置路由:
const routes = [
{
path: "/md",
name: "Markdown",
component: (r) =>
require.ensure([], () => r(require("../docs/zh-CN/example.md"))),
},
];
0x03 結尾
本篇幅主要按照專案從簡到繁的順尋逐步講解了各操作項及細節配置。下文將就元件實現原理詳細講解。
未完待續~