打包的“零配置極速方案”)
一、引言如果你曾用TypeScript編寫過(guò)一個(gè)npm包一定經(jīng)歷過(guò)這樣的糾結(jié)用tsc只能輸出JS無(wú)法打包用Rollup配置復(fù)雜光是讓TypeScript、CommonJS和ES Module和平共處就要折騰半天用Webpack又太重殺雞用牛刀。2025年如果你去問(wèn)一個(gè)開源庫(kù)作者“TypeScript庫(kù)用什么打包”十有八九會(huì)得到一個(gè)答案——tsup。這個(gè)由EGOIST開發(fā)的打包工具基于esbuild構(gòu)建以“零配置、極速構(gòu)建、多格式輸出”著稱周下載量超過(guò)270萬(wàn)。從shadcn/ui到React-Redux從Turborepo示例項(xiàng)目到無(wú)數(shù)個(gè)人開源庫(kù)tsup已成為TypeScript庫(kù)打包的事實(shí)標(biāo)準(zhǔn)。二、tsup是什么tsup是一個(gè)基于esbuild的TypeScript庫(kù)打包工具官方定位是“最簡(jiǎn)單、最快的TypeScript庫(kù)打包方式”。2.1 它解決了什么問(wèn)題寫一個(gè)TypeScript npm包通常面臨三個(gè)核心需求TS轉(zhuǎn)譯把.ts/.tsx源碼轉(zhuǎn)成JavaScript雙模式兼容同時(shí)輸出ESMES Module和CJSCommonJS兩種格式讓用戶無(wú)論用import還是require都能使用類型聲明生成輸出.d.ts文件提供TypeScript類型支持傳統(tǒng)方案需要組合使用tsc、Rollup、rollup-plugin-dts等多個(gè)工具配置繁瑣且容易出錯(cuò)。tsup的價(jià)值就在于——一個(gè)工具、一條命令、一次搞定。三、核心特性3.1 零配置開箱即用tsup最核心的設(shè)計(jì)理念是“no config”——提供合理的默認(rèn)值讓大多數(shù)TypeScript庫(kù)項(xiàng)目無(wú)需配置文件即可工作。最簡(jiǎn)單的用法只有一條命令tsup src/index.ts這條命令自動(dòng)完成TypeScript/JavaScript打包、輸出到./dist目錄、自動(dòng)排除node_modules依賴。3.2 極速構(gòu)建tsup底層基于esbuild——一個(gè)用Go語(yǔ)言編寫的打包器構(gòu)建速度比傳統(tǒng)工具Webpack、Rollup快10-100倍。速度差異在大型項(xiàng)目中尤為明顯。一個(gè)中等規(guī)模的TypeScript庫(kù)tsc編譯可能需要幾秒而tsup通常在毫秒級(jí)完成。這種速度優(yōu)勢(shì)讓開發(fā)時(shí)的“修改→構(gòu)建→測(cè)試”循環(huán)幾乎無(wú)感。3.3 多格式輸出tsup可以在一次構(gòu)建中同時(shí)生成多種模塊格式格式擴(kuò)展名適用場(chǎng)景cjs.js/.cjsNode.js CommonJSesm.mjs/.js現(xiàn)代ES Module環(huán)境iife.global.js瀏覽器全局變量這意味著你只需要一次配置就能同時(shí)兼容所有主流使用場(chǎng)景。3.4 智能依賴外置tsup會(huì)自動(dòng)將package.json中的dependencies和peerDependencies標(biāo)記為外部依賴避免將node_modules打包進(jìn)庫(kù)中——這對(duì)Node.js庫(kù)來(lái)說(shuō)通常是正確做法。3.5 雙引擎策略tsup采用了一個(gè)精妙的設(shè)計(jì)用esbuild打包JavaScript用Rollup打包類型聲明。esbuild負(fù)責(zé)JS極速構(gòu)建、原生TS支持、內(nèi)置壓縮和Tree-shakingRollup負(fù)責(zé).d.ts將分散的類型聲明文件合并為單一入口處理復(fù)雜的類型依賴關(guān)系這種“各取所長(zhǎng)”的策略讓tsup在速度和正確性之間取得了最佳平衡。3.6 TypeScript類型聲明生成通過(guò)--dts參數(shù)tsup可以自動(dòng)生成合并后的.d.ts類型聲明文件tsup src/index.ts--dts輸出產(chǎn)物中會(huì)包含index.d.ts用戶安裝你的包后即可獲得完整的TypeScript類型支持。四、實(shí)際應(yīng)用場(chǎng)景4.1 主要適用場(chǎng)景tsup最擅長(zhǎng)的場(chǎng)景是TypeScript npm包的構(gòu)建具體包括純JS/TS工具庫(kù)如lodash、dayjs這類通用工具函數(shù)庫(kù)React/Vue組件庫(kù)需要同時(shí)輸出ESM和CJS并保留類型聲明CLI工具支持Shebang自動(dòng)添加#!/usr/bin/env nodeMonorepo中的共享包與Turborepo等工具配合實(shí)現(xiàn)高效的包間構(gòu)建4.2 shadcn/ui開源組件庫(kù)的標(biāo)桿案例shadcn/ui是當(dāng)前最流行的React組件庫(kù)之一其構(gòu)建工具正是tsup。通過(guò)tsupshadcn/ui實(shí)現(xiàn)了同時(shí)輸出ESM和CJS兩種格式完整的TypeScript類型支持極快的構(gòu)建速度保障了頻繁發(fā)布的效率4.3 React-Redux大型項(xiàng)目的構(gòu)建優(yōu)化React-Redux作為Redux官方的React綁定庫(kù)其構(gòu)建配置直接影響了數(shù)百萬(wàn)項(xiàng)目的開發(fā)體驗(yàn)。React-Redux團(tuán)隊(duì)選擇tsup作為構(gòu)建工具實(shí)現(xiàn)了環(huán)境分離打包通過(guò)NODE_ENV區(qū)分開發(fā)和生產(chǎn)環(huán)境生成不同產(chǎn)物多格式輸出同時(shí)輸出CJS和ESM格式按需加載優(yōu)化利用tsup的Tree-shaking能力4.4 個(gè)人組件庫(kù)與設(shè)計(jì)系統(tǒng)無(wú)數(shù)個(gè)人開發(fā)者和團(tuán)隊(duì)使用tsup構(gòu)建自己的組件庫(kù)和設(shè)計(jì)系統(tǒng)。一個(gè)典型的配置會(huì)將react、antd等運(yùn)行時(shí)依賴標(biāo)記為peerDependencies并通過(guò)--external排除同時(shí)生成ESM、CJS和.d.ts類型聲明利用watch模式實(shí)現(xiàn)開發(fā)時(shí)的實(shí)時(shí)構(gòu)建4.5 Monorepo中的共享包在Turborepo等Monorepo方案中tsup常被用于構(gòu)建各個(gè)共享包。配合--watch模式可以實(shí)現(xiàn)“修改共享包→自動(dòng)重新構(gòu)建→上層應(yīng)用熱更新”的流暢開發(fā)體驗(yàn)。五、開發(fā)實(shí)踐指南5.1 安裝在項(xiàng)目根目錄執(zhí)行npminstalltsup-D# 或yarnaddtsup--dev# 或pnpmaddtsup-D5.2 基礎(chǔ)配置創(chuàng)建tsup.config.ts配置文件import{defineConfig}fromtsupexportdefaultdefineConfig({entry:[src/index.ts],// 入口文件format:[esm,cjs],// 同時(shí)輸出ESM和CJSdts:true,// 生成類型聲明文件sourcemap:true,// 生成sourcemapclean:true,// 構(gòu)建前清空dist目錄minify:false,// 開發(fā)環(huán)境不壓縮splitting:false,// 庫(kù)打包不需要代碼分割target:es2020,// 轉(zhuǎn)譯目標(biāo)})5.3 在package.json中配置腳本{scripts:{build:tsup,dev:tsup --watch,prepublishOnly:npm run build}}5.4 React組件庫(kù)的典型配置對(duì)于React組件庫(kù)需要將React等運(yùn)行時(shí)依賴排除import{defineConfig}fromtsupexportdefaultdefineConfig({entry:[src/index.ts],format:[esm,cjs],dts:true,external:[react,react-dom],sourcemap:true,clean:true,})5.5 CLI工具的配置如果構(gòu)建的是命令行工具需要開啟shebang選項(xiàng)exportdefaultdefineConfig({entry:[src/cli.ts],format:[cjs],shebang:true,// 自動(dòng)添加 #!/usr/bin/env nodedts:true,})5.6 實(shí)踐建議類型檢查與構(gòu)建分離tsup默認(rèn)不做類型檢查為了速度建議在CI或pre-commit中單獨(dú)運(yùn)行tsc --noEmit。善用watch模式開發(fā)時(shí)使用tsup --watch修改源碼后自動(dòng)重新構(gòu)建。按需使用minify庫(kù)代碼通常不需要壓縮交給應(yīng)用層做保持可讀性更有利于調(diào)試。注意CSS支持tsup的CSS支持仍處于實(shí)驗(yàn)階段復(fù)雜樣式方案建議配合其他工具。六、與其他工具的對(duì)比工具優(yōu)勢(shì)適用場(chǎng)景tsup零配置、極速、雙格式輸出、類型聲明大多數(shù)TypeScript庫(kù)tsdownRolldown引擎、更快、更低內(nèi)存新項(xiàng)目、Vite生態(tài)Rollup最強(qiáng)Tree-shaking、插件生態(tài)豐富復(fù)雜構(gòu)建需求unbuildRollup底層、Nuxt生態(tài)Nuxt/UnJS項(xiàng)目esbuild最底層的極速引擎需要完全自定義的場(chǎng)景tsup是目前最主流、最成熟的選擇周下載量達(dá)270萬(wàn)。tsdown作為新興工具值得關(guān)注但對(duì)現(xiàn)有tsup項(xiàng)目無(wú)需急于遷移。七、總結(jié)tsup之所以能成為TypeScript庫(kù)打包的“默認(rèn)答案”核心在于它精準(zhǔn)地解決了庫(kù)作者的三個(gè)核心痛點(diǎn)配置復(fù)雜→ 零配置開箱即用構(gòu)建太慢→ 基于esbuild毫秒級(jí)構(gòu)建格式兼容→ 一次構(gòu)建同時(shí)輸出ESM、CJS、類型聲明它不試圖做所有事而是把TypeScript庫(kù)打包這件事做到極致。無(wú)論你是在開發(fā)一個(gè)開源工具庫(kù)、一個(gè)React組件庫(kù)還是一個(gè)CLI工具tsup都能讓你把精力放在寫代碼上而不是配置構(gòu)建工具上。正如社區(qū)所言“tsup wraps esbuild with library defaults, while raw esbuild leaves declaration files and package output conventions to you.”——tsup就是那個(gè)幫你搞定所有“約定俗成”的打包工具。