DEV Community

Cover image for Vue 3、Tailwind CSS 3、esbuild、rollup.js 開發初始檔
Let's Write
Let's Write

Posted on • Edited on • Originally published at letswrite.tw

1

Vue 3、Tailwind CSS 3、esbuild、rollup.js 開發初始檔

2022.10.10 更新:新增多檔案編譯功能。

本篇要解決的問題

最近開始用 Vue3 在開發,也看了幾個 Youtube 上有關 Vue3 的教學,雖然官網很推薦 SFC(Single-File Component)的開發方式,但前端工程師們應該都會有個狀況:不是每個案子來,都是可以讓我們自由的開始下一個 npm init vue@latest 後就快快樂樂地開發的,有些時候我們是接手之前的人寫的案子,這些案子如果沒意外,大部份是後端渲染的方式,也就是我們可能會收到 .php、.cshtml、.aspx …… etc.

這時用 SFC 就有點不切實際,但如果我們又要用 Vue 來開發呢?就得用 CDN 的方式,或是把 Vue 給 import 進一個 JS 檔裡。

這時候又會產生另一個問題,就是當我們 import 了 Vue、Pinia,再加上其它我們需要的 JS 檔後,編譯工具的編譯速度會愈來愈慢。

這陣子 August 得用 Windows 開發,改用 Prepros 這套工具開發時,編譯 JS 檔需要到十幾秒,暈,那我整個專案改完,等待的編譯時間加起來都夠我看完一本哈利波特第一集了。

所以囉,有問題就要去解決問題,而不是去解決之前的工程師 XD,就決定做一個可以加快開發速度的初始檔,剛好前陣子看到了 esbuild 這套速度快到飛高高的編譯工具,就拿它來開發時使用。

本篇最後完成的初始檔,共有以下設定:

之所以打包時不用 esbuild 而用 rollup.js,是因為 esbuild 還不支援將 JS 編譯成 ES5 的版本,為了讓專案可以支援大部份瀏覽器,在打包時還是改用 rollup.js。

之所以開發時不直接用 rollup.js,是因為經 August 人體實驗證明,rollup.js 裡的 rollup-plugin-esbuild 這個套件使用時,編譯速度是可以縮到一秒多,但直接用 esbuild 卻可以不到一秒,在這個超高音速導彈都已經被製作出來的時代,還是愈快愈好。

本篇的初始檔有放上 GitHub,取用前麻煩分享本篇,或是 GitHub 上打個星星,你的小小動作對本站都是大大的鼓勵。

https://github.com/letswritetw/vue3_tailwind3_esbuild_rollup


安裝、使用

GitHub 下載整包檔案後,必備的檔案如下:

  • dist/
  • src/
  • .babelrc
  • esbuild.config.js
  • package.json
  • rollup.config.js
  • tailwind.config.js

除了以上的資料夾及檔案,其它的都可以刪掉沒關係。

esbuild.config.js、rollup.config.js 這二個檔案裡有寫了輸入、輸出的 JS 檔案路徑,預設如下:

  • 輸入:./src/main.js
  • 輸出:./dist/main.min.js

Tailwind 的路徑是寫在 package.json 的 dev-tailwindbuild-tailwind 二行裡,預設如下:

  • 輸入:./src/tailwind.css
  • 輸出:./dist/tailwind.min.css

準備使用時,先輸入指令安裝 package:

$ npm install
$ yarn
Enter fullscreen mode Exit fullscreen mode

package.json 裡的 scripts 部份有寫了指令碼。

開發 時,編譯 main.js 的指令為:

$ npm run dev-js
或
$ yarn dev-js
Enter fullscreen mode Exit fullscreen mode

編譯 tailwind.css 的指令為:

$ npm run dev-tailwind
或
$ yarn dev-tailwind
Enter fullscreen mode Exit fullscreen mode

打包 時,編譯 main.js 的指令為:

$ npm run build-js
或
$ yarn build-js
Enter fullscreen mode Exit fullscreen mode

編譯 tailwind.css 的指令為:

$ npm run build-tailwind
或
$ yarn build-tailwind
Enter fullscreen mode Exit fullscreen mode

也有寫上一次打包 JS 跟 Tailwind 的指令:

$ npm run build
或
$ yarn build
Enter fullscreen mode Exit fullscreen mode

同時打包這邊,有多寫了一個 remove-dist-js,會先刪掉 ./dist/main.min.js、./dist/main.min.js.map 這二個檔案,不過寫的 command-line 是用 macOS 的,如果你是用 Windows 的電腦就會失敗,把 yarn remove-dist-js 這行刪掉就行。

另外同時打包的指令用的是 yarn,沒安裝的朋友需事先裝好 Yarn,或是把 build 裡的 yarn 都改成 npm run xxxxx

以上,祝大家使用愉快~~


esbuild 開發時通知

開發時使用的 esbuild 裡,August 有加上通知,分別是執行 esbuild 時、有錯誤時。

執行 yarn dev-js 時,會出現一個通知,像這樣:

esbuild 通知

對,麻煩讓本站偷偷打個小廣告這樣 XD。

如果想要修改通知,就在 esbuild.config.js 這個檔案裡。

除了會跳出訊息通知,在終端機上也可以看到完整的錯誤資訊:

終端機會顯示完整錯誤訊息


Vue 3、Pinia

本專案用的是 Vue 3 + Pinia,裡面附的程式碼是 Composition API 的寫法,對,因為想在同事們之間炫技就做了這個微錯誤的決定(未來有機會會說明 XD),有時間會加上 Options API 用的範例檔。


多檔案編譯

有時候我們無法像 SPA 一樣只產一支 JS 檔就打遍天下,比如接手的專案很舊了,每個頁面的檔案散落在世界各地。

把四散的 JS 併成一支會很花時間,又想到就算完成也沒辦法算進績效裡時,就會睜隻眼閉隻眼的針對每個頁面去寫一支 JS 檔來進行修改。

對,不用掙扎了,實務上案子會一直來一直來,來到天荒地老,如果公司大大大主管沒有想翻新,整個打掉重練程式的話,需求能怎麼解決就怎麼解決。

即便真的花了時間整併 JS,還不一定每個功能都能正常運作,而且真的也無法寫進績裡,所以能用最簡單的方式解決,就用最簡單的方式吧。

現在假設我們有二個頁面:A.html、B.html,裡面各自引用了 a.js、b.js,總不能在改頁面時,改 A 就手動改一次 entryPoints 的路徑,改 B 時再去手動改一次路徑,一天之內又改 A 又改 B,我跳進去了我又跳出來了,可以這樣嗎?而且這還只是改二個頁面而已。

所以囉,我們的實際需求,esbuild 跟 rollup.js 的神人相信也經歷過,看了二邊的文件,有提供同時編譯多個檔案的說明。

esbuild

esbuild 的多檔編譯比較簡單,因為它的 entryPoints 可以寫成陣列,官方文件 範例:

require('esbuild').buildSync({
  entryPoints: ['a.js', 'b.js'],
  bundle: true,
  write: true,
  outdir: 'out',
})
Enter fullscreen mode Exit fullscreen mode

entryPoints 裡寫要編譯的檔案有哪些。

outdir 寫要輸出的資料夾名稱。比方範例寫的是 out,那最後編譯出的檔案就會是:

./outdir/a.js、./outdir/b.js。

如果想要改變輸出的檔名,那就將 entryPoints 從陣列改為物件:

entryPoints: {
    out1: 'a.js',
    out2: 'b.js',
},
Enter fullscreen mode Exit fullscreen mode

輸出的檔案就會變成:

./out/out1.js、./out/out2.js

然後,你們知道的,工程師會有工程師的堅持,一般來說,壓縮過的檔案 August 會習慣加上 *.min.js 的檔名,所以要再加工一下,在原本的 outdir 後再加入一行:

outExtension: { '.js': '.min.js' }
Enter fullscreen mode Exit fullscreen mode

這樣輸出的 .js 就會變成 .min.js 了。

最後在 esbuild 這邊要提的是,官方文件的範例用的是 buildSync,實際開發時會遇到一個錯誤:

Cannot use "watch" with a synchronous build
Enter fullscreen mode Exit fullscreen mode

watch 模式下不能用 buildSync,因此本專案寫的時候是用 build

rollup.js

rollup 的方式稍微麻煩一些些,每編譯一個檔案,就要寫進一個物件裡,所以當有多個檔案要編譯,就要寫多個物件出來,官方文件 範例:

export default [{
    input: 'a.js',
    output: {
        file: 'dist/a.js', format: 'cjs'
    }
},
{
    input: 'b.js',
    output: {
        file: 'dist/b2.js', format: 'es'
    }
}];
Enter fullscreen mode Exit fullscreen mode

如果有用到 plugins,就每一個物件裡都要寫,所以在寫的時候可以把 plugins 命成一個變數,就不必相同的東西一直重複寫。

.env

本篇最後的檔案,開發時用 esbuild,打包時用 rollup.js,為了避免相同的 input、output 分開在二個檔案裡,就引入了 .env 的方式,把 input、output 寫在 .env 檔中,然後二個檔案再各自引用。

.env 用的是 dotenv 這個 package。

以下是 August 在本專案裡的寫法,要編譯的檔案有二個:

  • ./src/main.js
  • ./src/main2.js

目標輸出的檔案是:

  • ./dist/main.min.js
  • ./dist/main2.min.js

.env

ENTRY=./src/main.js,./src/main2.js
OUTPUT=./dist/main.min.js,./dist/main2.min.js
Enter fullscreen mode Exit fullscreen mode

esbuild

require('dotenv').config();

const entry = process.env.ENTRY.split(',');
require('esbuild').build({
  entryPoints: entry,
  bundle: true,
  write: true,
  outdir: './dist/',
  outExtension: { '.js': '.min.js' }
})
Enter fullscreen mode Exit fullscreen mode

rollup.js

require('dotenv').config();

const plugins = [ ... ];

const entry = process.env.ENTRY.split(',');
const output = process.env.OUTPUT.split(',');

const resultArray = [];
for(let i in entry) {
  const item = {
    input: entry[i],
    plugins,
    output: {
      file: output[i],
      format: 'iife'
    }
  }
  resultArray.push(item);
}

export default resultArray;
Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more