rollup打包js庫

前言

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

需求

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

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

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

tree.png

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

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

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

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

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

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

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


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

e.在根目錄下創(chuàng)建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",

執(zhí)行npm run build
一個簡單的rollup打包項(xiàng)目完成了。
使用ts
為什么使用ts呢,ts是靜態(tài)類型,js是動態(tài)類型;靜態(tài)類型對閱讀代碼是友好的;同時IDE提供的大量便捷支持和TS本身的語法檢查和代碼提示自動補(bǔ)全讓開發(fā)者提高效率,方便重構(gòu)等。當(dāng)然,TypeScript 只是為 JavaScript 中本身就存在的使用方式提供了對應(yīng)的類型標(biāo)注,所有在 TypeScript 中能夠使用的開發(fā)模式,在 JavaScript 中一定是本身就存在的。
a. 安裝依賴庫
typescript:編譯 typescript 語法的基礎(chǔ)庫
rollup-plugin-typescript2:結(jié)合 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",// 編譯目標(biāo)
    "module":"es2015",// 模塊類型
    "lib": ["es2015", "es2016", "es2017"],// 導(dǎo)入庫類型定義
    "strict": true,// 嚴(yán)格模式
    "sourceMap": true,// 生成定義sourceMap
      "strictNullChecks": true, // 不允許把null、undefined賦值給其他類型的變量
    "declaration": true,// 生成定義文件
    "declarationDir": "dist/types",//類型聲明文件位置 自動創(chuàng)建聲明文件(.d.ts)
    "noUnusedLocals": true, // 未使用變量報錯
    "outDir": "./dist",  // 編譯輸出目錄 
    "typeRoots": [ //typeRoots 用來指定默認(rèn)的類型聲明文件查找路徑,默認(rèn)為 node_modules/@types
      "node_modules/@types"
    ]
  }
}

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

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

b.創(chuàng)建 .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.創(chuàng)建.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',
 
};

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

  • husky:git hook 輔助工具
  • lint-staged:監(jiān)測變動文件并執(zhí)行命令
  • @commitlint/cli:commitlint 核心工具庫
  • @commitlint/config-conventional:一些 commitlint 規(guī)則預(yù)設(shè)
npm i husky lint-staged -D
npm i @commitlint/cli @commitlint/config-conventional -D

b.創(chuàng)建huskyrc.js

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

c.創(chuàng)建 lint-staged.config.js

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

d.創(chuàng)建commitlint.config.js

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

**jest測試
**Jest 是用來創(chuàng)建、執(zhí)行和構(gòu)建測試用例的一個 JavaScript 測試 庫??梢栽谌魏雾?xiàng)目中安裝使用它,如 Vue/React/Angular/Node/TypeScript 等。
簡單總結(jié)一下,Jest 具有以下優(yōu)點(diǎn):

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

a.安裝依賴

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

b.創(chuàng)建 jest.config.js


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

c.在根目錄下創(chuàng)建 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" **
**

總結(jié)

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容