前言
最近在寫一個前端工具庫,剛開始用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就是其中一種方法,通過它減少在項目里沒有使用的代碼,來減少我們打開頁面的時間。
我們再來看看對于相同的代碼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 是代碼格式化工具。它通過解析代碼并使用自己的規則重新打印它,并考慮最大行長來強制執行一致的樣式,并在必要時包裝代碼。支持 JavaScript
、 Flow
、 TypeScript
、 CSS
、 SCSS
、 Less
、 JSX
、 Vue
、 GraphQL
、 JSON
、 Markdown
等語言,可以結合 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