美文网首页让前端飞前端开发那些事程序员
基于rollup打造前端工具库的实践

基于rollup打造前端工具库的实践

作者: zlxbuzz | 来源:发表于2018-01-28 11:38 被阅读183次

    老生常谈工具库,每个公司都应该需要一个工具库去处理一些公共重复的代码,比如公共函数,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 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.jsrollup的主要配置文件,这里我主要将代码打包成浏览器直接使用的umd格式和打包工具使用的esm格式。
    最终会生成

    lib
      z.esm.js  webpack等工具import,支持tree shaking按需加载
      z.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'})
          })
        })
      })
    

    测试结果:

    clipboard.png

    测试覆盖率:

    clipboard.png

    文档

    为了使文档能够自动化生成,主要采用了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) {
      }
    
    clipboard.png

    总结

    这里我主要总结了我开发工具库所用到的一些实践,参考了不少开源的项目,写的比较匆忙,有些细节可以参考源代码,如果有不合理的地方尽情吐槽,共同进步。

    项目地址:地址
    开发环境: MacOS

    相关文章

      网友评论

        本文标题:基于rollup打造前端工具库的实践

        本文链接:https://www.haomeiwen.com/subject/orvnixtx.html