rollup打包js庫

前言

最近在寫一個前端工具庫,剛開始用webpack搭建,但是偶然間發現rollup的介紹,發現rollop更滿足我的需求。這篇文章介紹了用rollup搭建一個簡單版的js工具庫。

需求

代碼層面
1.編寫:支持ES6語法(支持異步) 對傳參有要求
2.提交:提交代碼有規范
3.測試:代碼測試-單元測試
4.注釋:生成相應的文檔說明
功能層面:
1.使用:主流瀏覽器使用;eg:chrome,firefox
2.js方法
3.引用:會引用了其它的庫
顯然,在打包時,我們第一時間會想到的就是webpack,但是我在實際中發現有更適合我的需求的打包框架,就是rollup。下面我們來看看他們的區別。
webpack VS Rollup
1.入口文件
webpack和rollup都需要一個配置文件,來指定入口,輸出,插件等

webpack rollup
相對路徑 不支持,使用path.resolve 支持

這只是其中一個簡單的區別,我們再來看看以下幾個區別
2.死代碼消除(tree-shaking)
當我們打開一個網頁,如圖,只有頁面加載完相關資源(eg:js,圖片)頁面才會顯示出來。如果我們需要加載的資源體積越小,當然我們打開頁面的時間就會縮短。如何縮小我們需要資源的大小呢,tree-shaking就是其中一種方法,通過它減少在項目里沒有使用的代碼,來減少我們打開頁面的時間。

tree.png

我們再來看看對于相同的代碼webpack和rollup打包的結果

相同的代碼 webpack rollup
執行時間 71ms 17ms
文件大小 389KB 262KB

主要原因就是rollup使用了tree-shaking,利用了es6模塊特性,促使了mudle進行靜態分析,在uglify階段刪除了無用代碼。
至于什么是es6規范呢,如下:

  • 只能作為模塊頂層的語句出現(import和export語句只能出現在代碼頂層)
  • import的模塊只能是字符串變量,不能使用字符串和變量
  • 引入模塊不能再進行修改
// 情況1 
let str = '只能作為模塊頂層的語句出現';
import {  sum} from 'util' ;

// 情況2
import { 's'+'um'} from 'util';

//情況3
import {sum} from 'util'
sum=1;// Syntax Error : 'a' is read-only;

3.實時加載
webpack:使用webpack-dev-server插件
rollup:rollup-plugin-serve+rollup-plugin-livereload 。
webpack實時加載的定制型更強,比如添加中間件,指定運行使用的文件。
更多的比較可去查看。
總結一下:
webpack
生態圈豐富 (文檔更完整,插件庫豐富)
拆分代碼,按需加載 利用插件支持tree-shaking(webpack 2以上)
webpack會產生很多額外的代碼,
打包文件較大 執行較慢 可讀性弱
適用涉及到css html 靜態資源處理 復雜的代碼拆分合并或者 應用
rollup
插件生態相對較弱 把所有資源放在同一個地方,一次性加載 利用tree-shaking縮小包體積
一般不會產生額外的代碼,執行更快,可讀性更強
rollup多適用于基礎庫
我們再來梳理一下我們的需求:
1.只需要實現js常用方法 --rollup
2.語法:支持類型 --TypeScript
3.規范:編碼規范 --ESLint&Prettier
4.提交:提交有要求 --Husky&commitlint
5.質量:測試用例 --jest
下面開始我們的項目搭建啦
初始化項目
a.創建文件夾 rollup-demo
b.npm init -y 初始化
c.安裝 rollup和每次打包清除dist目錄插件 npm i rollup rollup-plugin-clear -D
d.創建入口文件src/main.js


function fun1(){
  
  function fun2(){
    return 'no'
  }
 return 'yes'
}
fun1()
console.log(fun1())
function Useless(){
  console.log(1111)
}

e.在根目錄下創建rollup.config.js

'use strict';
import clear from 'rollup-plugin-clear';
export default {
  input: 'src/main.ts',
  output: {
    file: 'dist/bundle.js',
    format: 'umd', //打包文件格式
  },
  plugins: [
    clear({targets: ['dist']}), //清除dist目錄
  ],
};

f.在package下添加命令

 "build": "rollup -c rollup.config.js",

執行npm run build
一個簡單的rollup打包項目完成了。
使用ts
為什么使用ts呢,ts是靜態類型,js是動態類型;靜態類型對閱讀代碼是友好的;同時IDE提供的大量便捷支持和TS本身的語法檢查和代碼提示自動補全讓開發者提高效率,方便重構等。當然,TypeScript 只是為 JavaScript 中本身就存在的使用方式提供了對應的類型標注,所有在 TypeScript 中能夠使用的開發模式,在 JavaScript 中一定是本身就存在的。
a. 安裝依賴庫
typescript:編譯 typescript 語法的基礎庫
rollup-plugin-typescript2:結合 rollup 編譯 typescript 的 plugins

npm i rollup-plugin-typescript2 typescript -D

b. rollup.config.js配置

rollup.config.js
import ts from "rollup-plugin-typescript2";
export default {
    input: "./src/main.ts",
    plugins: [
        ts({
            useTsconfigDeclarationDir: true
        }),
    ]
}

useTsconfigDeclarationDir:指定生成聲明文件存放目錄。
c.配置 tsconfig.json

{
  "compilerOptions": {
    "target": "es5",// 編譯目標
    "module":"es2015",// 模塊類型
    "lib": ["es2015", "es2016", "es2017"],// 導入庫類型定義
    "strict": true,// 嚴格模式
    "sourceMap": true,// 生成定義sourceMap
      "strictNullChecks": true, // 不允許把null、undefined賦值給其他類型的變量
    "declaration": true,// 生成定義文件
    "declarationDir": "dist/types",//類型聲明文件位置 自動創建聲明文件(.d.ts)
    "noUnusedLocals": true, // 未使用變量報錯
    "outDir": "./dist",  // 編譯輸出目錄 
    "typeRoots": [ //typeRoots 用來指定默認的類型聲明文件查找路徑,默認為 node_modules/@types
      "node_modules/@types"
    ]
  }
}

** ESLint & Prettier**
ESLint 對應的是代碼語法質量規則,Prettier 對應的是格式化規則。**
ESLint 是一個插件化的 javascript 代碼檢測工具,它可以用于檢查常見的 JavaScript 代碼錯誤,也可以進行代碼風格檢查,這樣我們就可以根據自己的喜好指定一套 ESLint 配置,然后應用到所編寫的項目上,從而實現輔助編碼規范的執行,有效控制項目代碼的質量。
prettier 是代碼格式化工具。它通過解析代碼并使用自己的規則重新打印它,并考慮最大行長來強制執行一致的樣式,并在必要時包裝代碼。支持 JavaScriptFlowTypeScriptCSSSCSSLessJSXVueGraphQLJSONMarkdown 等語言,可以結合 ESLint 和 Prettier,檢測代碼中潛在問題的同時,還能統一團隊代碼風格,從而促使寫出高質量代碼,來提升工作效率。
a.安裝依賴

  • eslint:eslint 核心庫,負責整個 eslint 的調度工作
  • @typescript-eslint/parser:ESLint的解析器,用于解析typescript,從而檢查和規范Typescript代碼
  • @typescript-eslint/eslint-plugin:ESLint插件,包含了各類定義好的檢測 typescript 代碼的規范
  • prettier:prettier 核心庫
  • eslint-config-prettier:解決 ESLint 中的樣式規范和 prettier 中樣式規范的沖突,以 prettier 的樣式規范為準,使 ESLint 中的樣式規范自動失效
  • eslint-plugin-prettier:將 prettier 的規范作為 ESLint 規范來使用
npm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier eslint-plugin-prettier -D

b.創建 .eslintrc.js

module.exports = {
    root: true,
    parser: '@typescript-eslint/parser',
    parserOptions: {
        ecmaVersion: 2019,
        sourceType: 'module', 
   },
       extends: [
        'plugin:@typescript-eslint/recommended',
        'prettier/@typescript-eslint',
        'plugin:prettier/recommended',
    ],
    env: {
        es6: true,
        node: true,
    },
  
    rules: {
        "no-undef": "error",
        "eqeqeq": "error",
          "no-console": "error"
    },
};

c.創建.prettierrc.js


module.exports = {
    arrowParens: 'avoid',
    bracketSpacing: false,
    endOfLine: 'lf',
    jsxBracketSameLine: false,
    jsxSingleQuote: false,
    printWidth: 100,
    proseWrap: 'preserve',
    semi: true,
    singleQuote: true,
    // tabWidth: 4,
    useTabs: false,
    trailingComma: 'es5',
 
};

提交代碼規范 Husky & lint-staged & Commitlint
**Husky **是一個 git hook 輔助工具,能夠在 git 文件狀態變更時,執行一些操作。husky能夠防止不規范代碼被commit、push、merge等等
**lint-staged **能監測到所有提交變動的文件,對其執行一系列命令,如 prettier 對不符合規范的代碼進行 fix。
**commitlint **顧名思義就是進行提交代碼 git commit -m 'xxxxx' 時,檢查提交記錄 message 的,commitlint 能夠抵擋住不符合規范的 message 記錄,如 git commit -m 'add eslint' 這就是一個不符合規范的 commit ,因為他沒有加上對應的 commit type 類別,add eslint 對應的類別應該是 chore (構建過程或輔助工具的變動)
**a.安裝依賴 **

  • husky:git hook 輔助工具
  • lint-staged:監測變動文件并執行命令
  • @commitlint/cli:commitlint 核心工具庫
  • @commitlint/config-conventional:一些 commitlint 規則預設
npm i husky lint-staged -D
npm i @commitlint/cli @commitlint/config-conventional -D

b.創建huskyrc.js

module.exports = {
  hooks: {
    'commit-msg': 'commitlint -e $HUSKY_GIT_PARAMS',
    'pre-commit': 'lint-staged',// 在 pre-commit commit 前的階段,執行 lint-staged 中的命令。
  },
};

c.創建 lint-staged.config.js

module.exports = {
  '{src,test}/**/*.ts': [
    'npm run lint',
    'git add'
  ]
};

d.創建commitlint.config.js

module.exports = {
  extends: [
    "@commitlint/config-conventional"
  ],
  rules: {// 自定義配置
    'subject-case': [2, 'always', ['upper-case']]
  }
};

**jest測試
**Jest 是用來創建、執行和構建測試用例的一個 JavaScript 測試 庫。可以在任何項目中安裝使用它,如 Vue/React/Angular/Node/TypeScript 等。
簡單總結一下,Jest 具有以下優點:

  • 測試用例并行執行,更高效
  • 強大的 Mock 功能
  • 內置的代碼覆蓋率檢查,不需要在引入額外的工具
  • 集成 JSDOM,可以直接進行 DOM 相關的測試
  • 開箱即用,幾乎不需要額外配置
  • 可以直接對 ES Module Import 的代碼測試
  • 有快照測試功能,可對 React 等框架進行 UI 測試

a.安裝依賴

  • jest:集成測試框架
  • @types/jest: jest 的類型定義包,在 typescript 環境下使用 jest 需要用到
  • ts-jest:測試 typescript 代碼的轉換工具
npm i jest @types/jest ts-jest -D

b.創建 jest.config.js


module.exports = {
  // 測試目錄
  roots: ['<rootDir>/test'],
  // 對 ts tsx 文件使用 ts-jest 進行運行測試
  transform: {
    '.(ts|tsx)': 'ts-jest',
  },
  // 測試環境
  testEnvironment: 'node',
  // 測試文件匹配
  testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
  collectCoverage: true,
  // 不計入覆蓋率中
  coveragePathIgnorePatterns: ['/node_modules/', '/test/'],
  // 覆蓋率達標閾值,不達標即測試失敗,拋出 error
  coverageThreshold: {
    global: {
      branches: 90,
      functions: 95,
      lines: 95,
      statements: 95,
    },
  },
};

c.在根目錄下創建 test/main.test.ts

import Sum from '../src/main'
test('sum is right', () => {
    expect(Sum(1, 2)).toBe(10);
});

**d.package.json 加上新的 script 指令 "test": "jest" **
**

總結

本篇文章講解了webpack和rollup的區別,用rollup搭建了一個簡單版js庫,也使用了TS,ESLint和Prettier 規范代碼規范和提交代碼的規范和使用jest來保障代碼的質量。代碼已上傳到github。https://github.com/turning1998/baselib

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容