老生常谈工具库,每个公司都应该需要一个工具库去处理一些公共重复的代码,比如公共函数,ajax
,微信sdk
,本地存储等等,目前构建工具大行其道,我觉得是时候摆脱复制粘贴的代码了,这里我对基于rollup
构建工具库进行了一个总结(相比webpack
更加配置简单,代码也清晰很多吧),更多是项目的组织,毕竟具体的代码每个公司都有自己的业务需求,希望能够帮助到大家。
目录结构
├── .git
├── .gitignore
├── .npmignore
├── LICENSE 协议
├── coverage 代码覆盖率文件
├── docs 文档
├── index.html 测试html
├── lib 引用的入口文件
├── node_modules
├── package-lock.json
├── package.json
├── readme.md 说明文档
├── rollup.config.js rollup配置文件
├── scripts 构建脚本
├── src 开发目录
├── test 测试用例
└── yarn.lock
这是最终的项目目录结构 地址
配置
import babel from 'rollup-plugin-babel'
import resolve from 'rollup-plugin-node-resolve'
import serve from 'rollup-plugin-serve'
import commonjs from 'rollup-plugin-commonjs'
import { uglify } from 'rollup-plugin-uglify'
import { minify } from 'uglify-es'
const isProd = process.env.NODE_ENV === 'production'
export default [
{
input: 'src/index.js',
output: {
name: '_',
file: 'lib/mat.min.js',
format: 'umd'
},
plugins: [
resolve({
extensions: ['.js']
}),
commonjs({
include: 'node_modules/**'
}),
babel({
extensions: ['.js'],
runtimeHelpers: true,
exclude: ['node_modules/**']
}),
isProd ? uglify({}, minify) : serve()
]
},
{
input: 'src/index.js',
output: {
file: 'lib/mat.esm.js',
format: 'es'
},
plugins: [
resolve({
extensions: ['.js']
}),
commonjs({
include: 'node_modules/**'
}),
babel({
extensions: ['.js'],
runtimeHelpers: true,
exclude: ['node_modules/**']
})
]
}
]
rollup.config.js
是rollup
的主要配置文件,这里我主要将代码打包成浏览器直接使用的umd
格式和打包工具使用的esm
格式。
最终会生成
lib
mat.esm.js webpack等工具import,支持tree shaking按需加载
mat.min.js script标签引入
开发
我这边将开发的具体代码放在src
中,入口为main.js
,每个功能模块是一个目录,有个入口文件index.js
方便进行单元测试,然后只有针对一个方法建立一个文件就可以了,已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参数
* ### 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, 个人认为jest
的集成度更高,语法也简单,内置的代码覆盖率检查很快就可以上手。我们只需要对每个功能模块进行测试代码的编写就可以了。
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参数: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'})
})
})
})
测试结果:
测试覆盖率:
文档
为了使文档能够自动化生成,主要采用了jsdoc-to-markdown
,只需要在每个方法上写上注释的代码,就能自动化的生成对应的md
文档,非常方便。
/**
* 获取url参数
* ### Example (es imports)
* ```js
* // url www.baidu.com?c=aa
* import {getParamByName} from 'zrutil'
* getParamByName('c') => 'aa'
* ```
*/
export function getParamByName(name, url) {
}