構(gòu)建過(guò)程是復(fù)雜的前端項(xiàng)目必不可少的環(huán)節(jié);但 業(yè)務(wù)代碼 與 公用代碼(如:封裝的庫(kù)掠剑、組件屈芜、工具等被復(fù)用的代碼)的構(gòu)建需求是不一樣的;我發(fā)現(xiàn)很多 npm 貢獻(xiàn)者都沒(méi)意識(shí)到這一點(diǎn)朴译,他們用傳統(tǒng)的業(yè)務(wù)項(xiàng)目的 webpack 配置 去打包 公用代碼井佑,雖然能運(yùn)行,但實(shí)際潛藏著許多問(wèn)題眠寿,甚至都不經(jīng)過(guò)編譯構(gòu)建躬翁,直接發(fā)布單純的源碼到 npm 上;由于本人經(jīng)常封裝一些東西盯拱,為了方便盒发,就分別使用 rollup 和 webpack 開(kāi)發(fā)并配置了專門用于構(gòu)建公共代碼的配置模板;本倉(cāng)庫(kù)是 rollup 版本的配置模板狡逢;webpack 版本的配置模板請(qǐng)看 library-webpack-template
目錄
- 1. 簡(jiǎn)介
- 2. 分支介紹
- 3. 使用
- 4. 命令
- 5. 所有可能需要的更改
- 6. 業(yè)務(wù)代碼與公用代碼的構(gòu)建特點(diǎn)
- 7. 構(gòu)建工具的選擇
- 8. 公共代碼構(gòu)建的配置目標(biāo)
- 9. 組織結(jié)構(gòu)
- 10. npm包管理配置文件
- 11. Rollup配置文件
- 12. TypeScript配置文件
- 13. 代碼檢查
- 14. 項(xiàng)目文檔Readme
內(nèi)容
注意:
為了方便下文描述宁舰,我把 業(yè)務(wù)代碼 構(gòu)建出的最終產(chǎn)品稱為 應(yīng)用程序;把 公用代碼 構(gòu)建的出產(chǎn)品稱為 組件甚侣;
1. 簡(jiǎn)介
library-rollup-template 稱為 庫(kù)構(gòu)建模板明吩,又稱 公共代碼構(gòu)建模板 ,是專門用于構(gòu)建 公共代碼(如:封裝的庫(kù)殷费、工具等) 的 rollup 配置模板印荔;針對(duì)不同的開(kāi)發(fā)環(huán)境(如:TypeScript、JavaScript 等等)library-rollup-template 倉(cāng)庫(kù)以分支的方式提供了多種配置模板详羡,當(dāng)需要開(kāi)發(fā)和構(gòu)建公共代碼時(shí)仍律,直接下載相應(yīng)分支,并默認(rèn)在的 src 目錄下開(kāi)發(fā)即可实柠。
具有以下特性:
- 易使用:一般情況下水泉,只需簡(jiǎn)單簡(jiǎn)單更改下
package.json
文件的相關(guān)信息即可; - 可配置去除 公共代碼 的依賴窒盐,除了
iife
格式的包草则,默認(rèn)情況下都去除了 所有node_modules
中的依賴; - 多個(gè)構(gòu)建目標(biāo)可同時(shí)構(gòu)建蟹漓,即:一次構(gòu)建分別生成多個(gè)構(gòu)建目標(biāo)的構(gòu)建包炕横,如:
ESModule
、CommonJS
葡粒、AMD
份殿、UMD
膜钓、自執(zhí)行文件
(可用<script>
標(biāo)簽直接引入) 等等; - 在構(gòu)建的輸出包的頂部會(huì)自動(dòng)注入 包 和 作者的相關(guān)描述信息卿嘲;
- 可快速切換 開(kāi)發(fā)模式 和 生產(chǎn)模式颂斜;
- 支持 JavaScript、JSX拾枣、TypeScript沃疮、TSX 等等;
- 支持 ESLint梅肤;
- 配置文件中有詳細(xì)豐富的注釋說(shuō)明忿磅,學(xué)習(xí)成本低;
詳情請(qǐng)看:
如果您在使用的過(guò)程中遇到了問(wèn)題凭语,或者有好的建議和想法,您都可以通過(guò)以下方式聯(lián)系我撩扒,期待與您的交流:
- 給該倉(cāng)庫(kù)提交 issues
- 給我 Pull requests
- 郵箱:guobinyong@qq.com
2. 分支介紹
針對(duì)不同的開(kāi)發(fā)環(huán)境(如:TypeScript似扔、JavaScript 等等),library-rollup-template 有多種配置模板搓谆,為了后續(xù)維護(hù)升級(jí)方便 和 體現(xiàn)種模板間的差異炒辉,本倉(cāng)庫(kù)采用如下策略來(lái)管理各個(gè)模板:
- 為同類型配置模板創(chuàng)建相同的分支路徑,如:
js/
泉手、ts/
- 為每類配置模板創(chuàng)建公共分支
common
黔寇,如:common
、js/common
斩萌、ts/common
- 每類具體的配置模板配置都是基于 其基礎(chǔ)分支來(lái)創(chuàng)建 或 該類的公共分支
common
- 當(dāng)需要更改某一類下的所有配置模板時(shí)缝裤,需要在該類下的 公共分支
common
中更改,然后將更改合并到其直接子分支颊郎,然后再將直接子分支合并到子分支的直接子分支中憋飞,依次類推;(為了保持分支的線性姆吭、美觀榛做,我使用的是變基rebase的合并方式,如果您們也使用該分支模型内狸,則不建義使用變基的方式進(jìn)行合并检眯,推薦使用 merge)
提示:關(guān)于子分支
、母分支
的概念昆淡,請(qǐng)參看Git并行工作流程規(guī)范
所以锰瘸,本倉(cāng)庫(kù)的分支結(jié)構(gòu)如下:
common # 倉(cāng)庫(kù)的公共分支,即:所有分支的公共分支瘪撇;不能用作公共代碼的構(gòu)建模板获茬;
js/ # 針對(duì) JavaScript 開(kāi)發(fā)環(huán)境的配置模板 都放在這個(gè)路徑下
├── common # 所有 JavaScript 開(kāi)發(fā)環(huán)境配置模板的公共配置港庄;不能用作公共代碼的構(gòu)建模板;基于 common 分支創(chuàng)建恕曲;
├── babel/ # 用 babel 作為 編譯器的配置模板 都放在這個(gè)路徑下
│ ├── base # 僅支持已規(guī)范的特性鹏氧,不支持處于實(shí)驗(yàn)階段的特性;基于 js/common 分支創(chuàng)建佩谣;
│ └── stage # 基于 base 創(chuàng)建把还,支持已規(guī)范的特性 和 處于實(shí)驗(yàn)階段的特性;基于 js/babel/common 分支創(chuàng)建茸俭;
└── buble # 用 buble 作為 編譯器的配置模板
ts/ # 針對(duì) TypeScript 開(kāi)發(fā)環(huán)境的配置模板 都放在這個(gè)路徑下
├── common # 所有 TypeScript 開(kāi)發(fā)環(huán)境配置模板的 公共配置吊履;不能用作公共代碼的構(gòu)建模板;基于 common 分支創(chuàng)建调鬓;
├── babel # 用 babel 作為 編譯器的配置模板艇炎;基于 ts/common 分支創(chuàng)建;
├── tsc # 用 TypeScript編譯器 作為 編譯器的配置模板腾窝;基于 ts/common 分支創(chuàng)建缀踪;
└── tsc-babel # 用 TypeScript編譯器 編譯后 再經(jīng)過(guò) babel編譯器 進(jìn)行編譯 的配置模板;基于 ts/tsc 分支創(chuàng)建虹脯;
3. 使用
- 從 git倉(cāng)庫(kù) 下載相應(yīng)的分支到本地驴娃;
- 將
package.json
文件中library-rollup-template
庫(kù)和作者相關(guān)的信息替換為您期望的信息;注意:files
以上的配置項(xiàng)都是你需要根據(jù)自己的庫(kù)進(jìn)行定制的配置 - 然后默認(rèn)從
src/index
文件開(kāi)始寫代碼循集;
4. 命令
library-rollup-template 項(xiàng)目支持如下構(gòu)建命令:
-
npm run build
: 構(gòu)建項(xiàng)目唇敞; -
npm run dev
: 構(gòu)建項(xiàng)目,并監(jiān)聽(tīng)源文件的改動(dòng)咒彤,如果有改動(dòng)疆柔,便會(huì)重新打包; -
npm run test
: 執(zhí)行test/index
文件蔼紧;
如果已經(jīng)全局安裝了 rollup
命令婆硬,也可以在項(xiàng)目根目錄下執(zhí)行如下命令:
-
rollup -c
: 構(gòu)建項(xiàng)目; -
rollup -c -w
: 構(gòu)建項(xiàng)目奸例,并監(jiān)聽(tīng)源文件的改動(dòng)彬犯,如果有改動(dòng),便會(huì)重新打包查吊;
5. 所有可能需要的更改
5.1. 更改庫(kù)的相關(guān)信息
- 庫(kù)的相關(guān)信息基本上都包含在
package.json
文件中谐区,其中files
以上的配置項(xiàng)應(yīng)該都是你需要根據(jù)自己的庫(kù)進(jìn)行定制的配置; - 作者的相關(guān)信息存在
package.json
和LICENSE
這兩個(gè)文件中逻卖;
技巧:
- 全局將
library-rollup-template
字符串 替換成 你的包名宋列; - 全局將
郭斌勇
字符串替換成 您的名字; - 全局將
guobinyong@qq.com
字符串 替換成 您的郵箱评也;
5.2. 禁止輸出某種模塊的包
library-rollup-template 默認(rèn)構(gòu)建輸出了以下幾種模塊格式的包:
-
es
:ESModule -
cjs
:CommonJS -
amd
:AMD -
umd
: umd -
iife
:自執(zhí)行
輸出的包名的格式是 <包名>.<格式>.js
炼杖,如果不需要輸出某種格式的包灭返,只需將對(duì)應(yīng)格式的配置塊注釋掉即可;
6. 業(yè)務(wù)代碼與公用代碼的構(gòu)建特點(diǎn)
6.1. 業(yè)務(wù)代碼
需要把所有代碼及依賴(包括 公用代碼)都構(gòu)建在一塊坤邪,作為一個(gè)整體來(lái)運(yùn)行熙含;
因?yàn)椋簶I(yè)務(wù)代碼的最終呈現(xiàn)效果是應(yīng)用程序,應(yīng)用程序是一個(gè)完整的代碼邏輯艇纺,任何依賴的缺失都會(huì)導(dǎo)致應(yīng)用程序崩潰怎静。運(yùn)行環(huán)境單一;
業(yè)務(wù)代碼構(gòu)建的應(yīng)用程序要么是運(yùn)行在瀏覽器的黔衡,要么是運(yùn)行在 node 環(huán)境的蚓聘;因?yàn)闃I(yè)務(wù)產(chǎn)品是最終供大眾用戶使用的,在開(kāi)發(fā)業(yè)務(wù)產(chǎn)品(應(yīng)用程序)之初盟劫,就已確定了業(yè)務(wù)產(chǎn)品的運(yùn)行環(huán)境夜牡。構(gòu)建目標(biāo)單一;
在構(gòu)建業(yè)務(wù)代碼時(shí),往往構(gòu)建目標(biāo)是明確的,要么是構(gòu)建瀏覽器應(yīng)用荣挨,要么是構(gòu)建 note 應(yīng)用飞傀,或者其它,總之很少有同時(shí)構(gòu)建多個(gè)目標(biāo)的袋毙,比如同時(shí)構(gòu)建瀏覽器和 note 環(huán)境的應(yīng)用程序型檀。有較強(qiáng)的包體積的限制;
因?yàn)榇蟛糠謶?yīng)用程序是運(yùn)行在瀏覽器的听盖,較大的包體積會(huì)使應(yīng)用程序加載時(shí)間過(guò)長(zhǎng)胀溺,從而影響用戶體驗(yàn),所以皆看,一般應(yīng)用程序都要求包的體積盡可能的胁治搿;業(yè)務(wù)代碼中通常包含 HTML腰吟、CSS无埃、JavaScript 文件;
CSS 和 JavaScript 文件通常都需要在 HTML 文件中引入毛雇;
瀏覽器端的應(yīng)用程序都是以HTML文件為入口的嫉称,通過(guò)HTML加載 CSS 和 JavaScript 文件;
6.2. 公用代碼
需要去除依賴灵疮;
公共代碼的依賴往往也是其它公共代碼或者業(yè)務(wù)代碼的依賴织阅,當(dāng)業(yè)務(wù)代碼中引入公共代碼時(shí),極有可能也引入了該公共代碼的依賴震捣,如果公共代碼中不去除其依賴荔棉,則會(huì)導(dǎo)致業(yè)務(wù)代碼中包含多份公共代碼的依賴闹炉,造成代碼冗余,增大業(yè)務(wù)代碼的體積润樱;運(yùn)行環(huán)境多樣渣触;
公眾代碼是被應(yīng)用程序引用的,應(yīng)用程序的運(yùn)行環(huán)境可能是瀏覽器祥国,也可能是 node 昵观,或者其它 ,所以公共代碼的運(yùn)行環(huán)境是多樣性的舌稀;構(gòu)建目標(biāo)多樣啊犬;
因?yàn)楣泊a的運(yùn)行環(huán)境是多樣的,所以在需要對(duì)公共代碼進(jìn)行構(gòu)建時(shí)壁查,往往需要針對(duì)每個(gè)運(yùn)行環(huán)境分別進(jìn)行構(gòu)建觉至;對(duì)包體積的沒(méi)有特別強(qiáng)列的要求;
公共代碼最終是要被業(yè)務(wù)代碼引用的睡腿,面業(yè)務(wù)代碼構(gòu)建成應(yīng)用程序時(shí)通常需要做包體積的壓縮的语御,所以,對(duì)包體積的壓縮通常會(huì)在業(yè)務(wù)代碼構(gòu)建成應(yīng)用程序時(shí)進(jìn)行席怪,所以应闯,當(dāng)公共代碼構(gòu)建成組件時(shí),大多數(shù)情況下也可不做體積壓縮挂捻;通常不包含 HTML 文件碉纺;
CSS 和 JavaScript 文件通常分開(kāi);
CSS 和 JavaScript 的組織方式往往是由業(yè)務(wù)代碼組織結(jié)構(gòu)和構(gòu)建方案決定刻撒,所以骨田,在公共代碼中,CSS 和 JavaScript 通常是分開(kāi)的声怔,具體怎么組織态贤,由業(yè)務(wù)代碼決定;
7. 構(gòu)建工具的選擇
前端的構(gòu)建工具有很多醋火,像:Webpack悠汽、rollup、Browserify芥驳、Parcel介粘、Grunt、Gulp等等晚树;
目前姻采,對(duì)于構(gòu)建公共代碼的工具較常用的是 rollup,對(duì)于構(gòu)建業(yè)務(wù)代碼,較常用的工具是 Webpack慨亲;不過(guò)婚瓜,Webpack 也是可以用于構(gòu)建公共代碼的,詳見(jiàn)library-webpack-template刑棵。
相比 rollup 巴刻,要構(gòu)建庫(kù)方面,Webpack有以下缺點(diǎn):
- 配置較復(fù)雜
- 不支持構(gòu)建 ESModule 模塊的包(解釋:Webpack 可以編譯 ESModule 模塊的源文件蛉签,但不支持輸出 ESModule 格式的包)胡陪;
所以,推薦使用 rollup 構(gòu)建 庫(kù)碍舍;本項(xiàng)目就是使用 rollup 來(lái)搭建的模板柠座;
如果想用 Webpack 來(lái)構(gòu)建庫(kù),可以使用另一個(gè)模板 library-webpack-template片橡;
8. 公共代碼構(gòu)建的配置目標(biāo)
公共代碼構(gòu)建的配置目標(biāo)其就是實(shí)現(xiàn)上文所述的公共代碼的構(gòu)建特點(diǎn)妈经,總結(jié)如下:
- 去除依賴
- 一次構(gòu)建可分別生成適用于不同環(huán)境的碼包;
比如:分別生成用于 node 和 瀏覽器 環(huán)境的包捧书,或者 不同模塊化方案的包吹泡,如 AMD、CMD经瓷、 CommonJS爆哑、UMD等等; - 能在 開(kāi)發(fā) 和 生產(chǎn) 兩種模式快速切換舆吮;
開(kāi)發(fā) 模式下地在需要更多的調(diào)試信息泪漂,如 Source Map ;而生產(chǎn)模式下需求盡可能地壓縮包的體積歪泳;在開(kāi)發(fā)調(diào)試的過(guò)程中,需要在開(kāi)發(fā)模式下構(gòu)建包露筒;當(dāng)開(kāi)發(fā)完畢呐伞,準(zhǔn)備發(fā)布時(shí),需要在生產(chǎn)模式下構(gòu)建包慎式; - 分離 CSS 和 JavaScript 文件伶氢;
9. 組織結(jié)構(gòu)
模板項(xiàng)目中默認(rèn)包含了一些文件和目錄,它們的組織結(jié)構(gòu)和作用如下所示:
library-rollup-template/ # 構(gòu)建前端庫(kù)的webpack打包配置模板項(xiàng)目根目錄
├── package.json # npm 的包管理配置文件
├── src/ # 默認(rèn)的包含項(xiàng)目源代碼的目錄
│ └── index # 默認(rèn)的構(gòu)建入口文件
├── test/ # 默認(rèn)的包含測(cè)試代碼的目錄
│ └── index # 默認(rèn)的構(gòu)建入口文件
├── dist/ # 默認(rèn)的構(gòu)建輸出目錄
├── LICENSE # 開(kāi)源證可證瘪吏;默認(rèn)是 MIT 許可證
├── tsconfig.json # TypeScript 的配置文件
├── README.md # 項(xiàng)目的說(shuō)明文檔
├── .eslintignore # ESLint 的忽略配置文件
├── .eslintrc.js # ESLint 的配置文件
├── .gitignore # git 的忽略配置文件
└── .npmignore # npm 上傳包時(shí)的忽略配置文件
10. npm包管理配置文件
library-rollup-template 中與 npm 包管理相關(guān)的配置文件有 2 個(gè):
-
.npmignore
: npm 上傳包時(shí)的忽略配置文件癣防;默認(rèn)忽略了 與構(gòu)建配置文件的所有文件和目錄,如:build/
等等掌眠;也忽略了開(kāi)發(fā)環(huán)境默認(rèn)的輸出目錄dev/
蕾盯,還有編輯器相關(guān)的文件和目錄,如:.idea
蓝丙、.vscode
级遭; -
package.json
: npm 的包管理配置文件望拖;同時(shí)也是 通過(guò) npm 上傳、發(fā)布 包 的 配置模板文件挫鸽;
注意: package.json
文件中的如下字段:
-
module
: 該字段是用來(lái)指定以標(biāo)準(zhǔn)模塊暴露的出口文件说敏; -
types
|typings
: 該字段是用來(lái)指定庫(kù)的類型聲明文件;如果庫(kù)沒(méi)有類型聲明文件丢郊,則去除該字段盔沫; -
"sideEffects" : boolean | Array<string>
,可以為布爾枫匾,表示整個(gè)包是否有副作用架诞;也可以是一些有副作用文件的的路徑字符串,路徑支持 相對(duì)路徑婿牍、絕對(duì)路徑和 glob 模式侈贷; 副作用標(biāo)記;表明項(xiàng)目中的哪些文件不是 純的 ES2015 模塊等脂,由此不能安全地刪除文件中未使用的部分俏蛮,"side effect(副作用)" 的定義是,在導(dǎo)入時(shí)會(huì)執(zhí)行特殊行為的代碼上遥,而不是僅僅暴露一個(gè) export 或多個(gè) export搏屑。舉例說(shuō)明,例如 polyfill粉楚,它影響全局作用域辣恋,并且通常不提供 export;詳細(xì)內(nèi)容請(qǐng)見(jiàn) https://webpack.docschina.org/guides/tree-shaking/#將文件標(biāo)記為-side-effect-free-無(wú)副作用-
關(guān)于package.json
文件的詳細(xì)配置信息請(qǐng)參考https://docs.npmjs.com/files/package.json
11. Rollup配置文件
library-rollup-template 中的 Rollup 配置文件是rollup.config.js
模软,里面有詳細(xì)清晰的注釋伟骨,能讓你輕松入手;
關(guān)于 Rollup 的詳細(xì)配置信息請(qǐng)參考https://rollupjs.org
12. TypeScript配置文件
如果你使用的是 TypeScript 的模板燃异,就會(huì)包含一個(gè) TypeScript 配置文件 tsconfig.json
携狭,所以,你也可以直接在項(xiàng)目根目錄下直接使用 TypeScript 的編譯命令 tsc
回俐;
關(guān)于 tsconfig
的詳細(xì)配置信息請(qǐng)參考 https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
13. 代碼檢查
本配置模版默認(rèn)使用 ESLint 作為 JavaScript 和 TypeScript 的代碼檢查工具逛腿;至于為什么 TypeScript 不用 TSLint 作為代碼檢查工具的原因請(qǐng)參看 https://github.com/typescript-eslint/typescript-eslint;
ESLint 相關(guān)的配置文件如下:
-
.eslintrc.js
: ESLint 的配置文件仅颇,可配置 解析器单默、解析選項(xiàng)、規(guī)則 等等忘瓦;默認(rèn)是 TypeScript 代碼檢查配置搁廓; -
.eslintignore
: ESLint 的忽略文件的配置文件;
關(guān)于 ESLint 的詳細(xì)配置信息請(qǐng)參考 http://eslint.cn/docs/user-guide/configuring
14. 項(xiàng)目文檔Readme
作為讓別人作用的項(xiàng)目,一定要有文檔枚抵,優(yōu)化庫(kù)线欲;README.md
是專門用來(lái)介紹項(xiàng)目的說(shuō)明性文檔;
我個(gè)人認(rèn)為汽摹,庫(kù)的文檔至少需要以下幾個(gè):
- 介紹李丰、說(shuō)明性文檔:用于介紹、說(shuō)明項(xiàng)目的文檔逼泣;該文檔一般寫在
README.md
文件中趴泌; - 教程文檔:以易學(xué)、易懂為原則的教學(xué)型文檔拉庶;
- 接口文檔:以規(guī)范嗜憔、全面、方便查找為原則的描述接口的手冊(cè)型文檔氏仗;
其中 README.md
寫在項(xiàng)目的根目錄里吉捶,并建義在 README.md
中留有其它文檔的入口;其它文檔(如:教程文檔皆尔、接口文檔)建義放在 doc/
或 docs/
目錄里呐舔;
我個(gè)人推薦的 README.md
目錄結(jié)構(gòu)如下:
- 簡(jiǎn)介:庫(kù)的簡(jiǎn)單介紹
- 特性簡(jiǎn)介:庫(kù)的特性
- 相關(guān)鏈接:如主頁(yè)、倉(cāng)庫(kù)慷蠕、相關(guān)文檔等等
- 反饋問(wèn)題的各種方式:如:issues珊拼、作者的聯(lián)系方式 等等
- 安裝:庫(kù)的安裝方式
- 簡(jiǎn)單的使用教程:庫(kù)的簡(jiǎn)單使用教程