打包 Vue3 Component Package
tags: Vue
Vite
category: Front-End
description: 打包 Vue3 Component Package
created_at: 2023/02/05 22:00:00
前言的題外話
好久沒寫文章,前陣子吃壞肚子+確診,現在整體比較好了(但還是常常好累)。但一個寒假也就要過了QQ
前言
在寫前端常常有些元件是在各個系統都用的到的 Component
,又或者是某些子功能不想重複做又找不到現成的套件直接用,如果從自己舊的 code
貼過去又感覺很蠢(?),所以就想說包成套件了。
預備知識(寫完之後發現好像沒有也沒差)
- 寫過
Vue3
(廢話) - 用過
Vite
本次目標
- 簡單寫一個
Component
- 在
Local
測試 - 發布到
NPM
上,載回Local
做測試
至於是什麼 Component
呢? 既然是範例當然是萬年 Counter
啦
建立 Vue3
專案
$ npm init vue@latest
之後切進你的專案後用你熟悉的套件管理器去安裝套件。
※提示: 這邊就卡住的話可以參考 Vue3系列文章
整理專案目錄
先留下 App.vue
然後把內容換成
<script setup></script>
<template>Hello World</template>
然後 assets
當中的 CSS
也可以先刪掉,免得後面礙事
※提醒: 如果你是把 assets
整個資料夾刪掉,要記得調整 main.js
的內容
import { createApp } from "vue";
import App from "./App.vue";
// import "./assets/main.css"; <-- 刪掉這行
createApp(App).mount("#app");
之後跑起測試伺服器看看有沒有問題,沒問題應該會看到畫面上有個 Hello World
開始寫 Counter
建立檔案: ./src/components/TheCounter.vue
<script setup></script>
<template>TheCounter</template>
養成好習慣,先在 App.vue
使用他,看看正不正常
<script setup>
import TheCounter from "./components/TheCounter.vue";
</script>
<template>
<h1>App</h1>
<TheCounter />
</template>
沒問題的話就可以開始完成 Counter
的功能了。
簡單的需求
- 一個按鈕,點下去會+1
就這麼單純,畢竟主要練習的不是這個。
<script setup>
import { ref } from "vue";
const count = ref(0);
const increment = () => {
count.value++;
};
</script>
<template>
<button @click="increment">Count is {{ count }}.</button>
</template>
<style scoped>
button {
background-color: #eee;
font-size: 2rem;
padding: 1rem;
border: 1px solid #ccc;
border-radius: 0.5rem;
cursor: pointer;
}
</style>
打包
再來進入打包的環節,可以根據 Vite
的官方文件
修改 vite.config.js
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
build: {
lib: {
entry: resolve(__dirname, "src/index.js"),
name: "SimpleCounter",
fileName: "simple-counter",
},
rollupOptions: {
external: ["vue"],
output: {
globals: {
vue: "Vue",
},
},
},
},
});
如果在開專案的時候有裝 ESLint
,顯示 resolve
有問題的話,可以修改 .eslintrc.cjs
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
// 加入 env 設定
env: {
node: true,
},
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
};
再來要建立上面 build.lib.entry
寫到的檔案,這是未來套件的進入點,所以建立 src/index.js
,把你要 export
的東西寫進去。
import TheCounter from "./components/TheCounter.vue";
export default TheCounter;
再來就可以跑 Build
的指令了,可以用你熟悉的工具去執行,以 npm
來說是
$ npm run build
跑完之後會看到多了一個 dist
資料夾,這個就是之後要發佈到 NPM
上面的東西。
在發布之前要先設定 package.json
。
設定 Package.json
把官方建議的設定貼進來改一下
{
"name": "vue3-simple-counter",
"type": "module",
"files": ["dist"],
"main": "./dist/simple-counter.umd.js",
"module": "./dist/simple-counter.mjs",
"exports": {
".": {
"import": "./dist/simple-counter.mjs",
"require": "./dist/simple-counter.umd.js"
},
"./style.css": {
"import": "./dist/style.css",
"require": "./dist/style.css"
}
},
"version": "0.0.0",
// ...
}
在 Local
測試
在 Local
測試,可以在套件的專案下
$ npm link
然後為了要在 Local
測試,可以再開一個新的 Vue
專案。
建立好且裝好相依套件後,可以在 link
使用我們剛剛做的套件
$ npm link <name>
以剛剛的範例的話就是下
$ npm link vue3-simple-counter
這樣你會發現 node_modules
下有一個捷徑,他連到 vue3-simple-counter
這個專案,而你就可以在 Vue
專案中 import
來測試可不可用。
App.vue
<script setup>
import TheCounter from "vue3-simple-counter";
import "vue3-simple-counter/style.css";
</script>
<template>
<TheCounter />
</template>
理論上可以正常執行,然後畫面上就有剛剛製作的那個 TheCounter
處理 CSS
剛才 Build
出來的結果包含了 style.css
,這樣使用還需要多 import
,有點麻煩,想說把他整併到 js
當中,有個工具可以幫忙達成。
vite-plugin-css-injected-by-js
安裝
$ npm i vite-plugin-css-injected-by-js -D
修改 vite.config.js
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
// ...
export default defineConfig({
plugins: [vue(), cssInjectedByJsPlugin()],
// ...
});
重新 Build
$ npm run build
之後你會看到 dist
當中少了 style.css
,他被搬到了 javascript
當中。
再來修改 package.json
,因為他不再需要 style.css
這個進入點。
{
// ...
"exports": {
".": {
"import": "./dist/simple-counter.js",
"require": "./dist/simple-counter.umd.cjs"
}
},
// ...
}
再來可以回到 Vue
專案中測試,把 css
的引入拿掉,應該可以正常運作,就完成了。
總結
這一篇主要是紀錄如何包裝 Vue3
的 Component
,這樣未來就可以更輕鬆的重複使用自己曾寫過的工具,不過使用 JavaScript
在開發套件上還是有些缺點,下一篇會紀錄如何發布 TypeScript
的版本,且再加入 TailwindCSS
。