老生常談工具庫邦马,每個公司都應(yīng)該需要一個工具庫去處理一些公共重復(fù)的代碼,比如公共函數(shù)邻悬,ajax
,微信sdk
础米,本地存儲等等屁桑,目前構(gòu)建工具大行其道蘑斧,我覺得是時候擺脫復(fù)制粘貼的代碼了竖瘾,這里我對基于rollup
構(gòu)建工具庫進(jìn)行了一個總結(jié)(相比webpack
更加配置簡單,代碼也清晰很多吧)扩劝,更多是項目的組織聂示,畢竟具體的代碼每個公司都有自己的業(yè)務(wù)需求鱼喉,希望能夠幫助到大家扛禽。
目錄結(jié)構(gòu)
├── .git
├── .gitignore
├── .npmignore
├── LICENSE 協(xié)議
├── coverage 代碼覆蓋率文件
├── docs 文檔
├── index.html 測試html
├── lib 引用的入口文件
├── node_modules
├── package-lock.json
├── package.json
├── readme.md 說明文檔
├── rollup.config.js rollup配置文件
├── scripts 構(gòu)建腳本
├── src 開發(fā)目錄
├── test 測試用例
└── yarn.lock
這是最終的項目目錄結(jié)構(gòu) 地址
配置
import pkg from './package.json';
import buble from 'rollup-plugin-buble';
import resolve from 'rollup-plugin-node-resolve';
import uglify from 'rollup-plugin-uglify'
import { minify } from 'uglify-es';
export default [
{
input: 'src/main.js',
output: {
name: '_',
file: pkg.browser,
format: 'umd'
},
plugins:[
resolve(),
buble({ // transpile ES2015+ to ES5
objectAssign: 'Object.assign',
exclude: ['node_modules/**']
}),
uglify({},minify)
],
},
{
input: 'src/main.js',
output: { file: pkg.main, format: 'es' },
plugins: [
resolve(),
buble({
objectAssign: 'Object.assign',
exclude: ['node_modules/**']
}),
uglify({},minify)
]
}
]
rollup.config.js
是rollup
的主要配置文件麸恍,這里我主要將代碼打包成瀏覽器直接使用的umd
格式和打包工具使用的esm
格式刻肄。
最終會生成
lib
z.esm.js webpack等工具import敏弃,支持tree shaking按需加載
z.min.js script標(biāo)簽引入
開發(fā)
我這邊將開發(fā)的具體代碼放在src
中麦到,入口為main.js
瓶颠,每個功能模塊是一個目錄,有個入口文件index.js
方便進(jìn)行單元測試桃移,然后只有針對一個方法建立一個文件就可以了借杰,已url
處理功能為例:
src
main.js
reg/
dom/
url/
index.js
getParamByName.js
parseQueryString.js
url/index.js
//暴露處所有的方法
export * from './getParamByName'
export * from './parseQueryString'
url/getParamByName.js
/**
* 獲取url參數(shù)
* ### Example (es imports)
* ```js
* // url www.baidu.com?c=aa
* import {getParamByName} from 'zrutil'
* getParamByName('c') => 'aa'
* ```
*/
export function getParamByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
測試
好的工具庫缺少不了測試缘琅,這里我采用的是jest, 個人認(rèn)為jest
的集成度更高刷袍,語法也簡單呻纹,內(nèi)置的代碼覆蓋率檢查很快就可以上手雷酪。我們只需要對每個功能模塊進(jìn)行測試代碼的編寫就可以了蔗怠。
test/url.test.js
import {parseQueryString, getParamByName} from '../src/url'
describe('url test', ()=>{
const url = 'http://www.baidu.com?a=1&b=aaa'
describe('獲取url參數(shù):getParamByName',()=>{
test(`${url} getParamByName('a',url) 返回 1`, ()=>{
expect(getParamByName('a',url)).toBe('1')
})
test(`${url} getParamByName('b',url) 返回 'aaa'`, ()=>{
expect(getParamByName('b',url)).toBe('aaa')
})
test(`${window.location.href} getParamByName('c') 返回 'ccc'`, ()=>{
expect(getParamByName('c')).toBe('ccc')
})
test(`${window.location.href} getParamByName('b') 返回 null`, ()=>{
expect(getParamByName('b')).toBe(null)
})
})
describe('解析url:parseQueryString',()=>{
test(`${url} 返回 {a:'1',b:'aaa'}`, ()=>{
expect(parseQueryString(url)).toEqual({a:'1',b:'aaa'})
})
test(`${window.location.href} 返回 {c:'ccc'}`, ()=>{
expect(parseQueryString()).toEqual({c:'ccc'})
})
})
})
測試結(jié)果:
測試覆蓋率:
文檔
為了使文檔能夠自動化生成,主要采用了jsdoc-to-markdown
,只需要在每個方法上寫上注釋的代碼桥温,就能自動化的生成對應(yīng)的md
文檔旺韭,非常方便区端。
/**
* 獲取url參數(shù)
* ### Example (es imports)
* ```js
* // url www.baidu.com?c=aa
* import {getParamByName} from 'zrutil'
* getParamByName('c') => 'aa'
* ```
*/
export function getParamByName(name, url) {
}
總結(jié)
這里我主要總結(jié)了我開發(fā)工具庫所用到的一些實(shí)踐遵湖,參考了不少開源的項目延旧,寫的比較匆忙迁沫,有些細(xì)節(jié)可以參考源代碼近弟,如果有不合理的地方盡情吐槽祷愉,共同進(jìn)步。
項目地址:地址
開發(fā)環(huán)境: MacOS