前端库开发(打包、文档生成、单元测试)

打包

最近把自己的库整理了一下,改成用rollup打包。本来是自己看文档折腾rollup配置的,虽然打包文件出来了,也能用,但babel会提示缺少_typeof之类的,所以后来还是到网上找了一份配置。找的配置地址如下:

https://github.com/jiaoyanlin/npm-library-demo

我只留下了打包相关的:startbuild命令涉及到的配置和包。

文档生成

用的jsdoc来生成文档。具体配置官网有,这里只贴一下我用到的。

// package.json
……
"scripts": {
  "docs": "jsdoc -c jsdoc.json"
}
// 需要安装两个包:"jsdoc": "^3.6.4", "jsdoc-babel": "^0.5.0",
……

// jsdoc.json
{
  "plugins": ["node_modules/jsdoc-babel"],
  "source": {
    "include": ["src"],
    "exclude": [],
    "includePattern": ".+\\.js(doc)?$",
    "excludePattern": "(^|\\/|\\\\)_"
  },
  "opts": {
    "encoding": "utf8",
    "destination": "./docs/", // 文档目录
    "recurse": true
  }
}

// xxx.js--代码文件类似下面这样的注释
/**
 * 数组相关方法
 * @module array
 */

/**
 * 填充数组--返回值是原数组
 * @memberOf module:array
 * @param {Array} arr // 要填充的数组
 * @param {*} value // 要填充的值
 * @param {number} start // 开始填充位置,可选,默认0
 * @param {number} end // 结束填充位置,可选,默认最后一个元素
 * @param {boolean} replace // 是否替换现有值,可选,默认不替换
 */
export function fill(arr, value, start, end, replace) {
  if (!isArray(arr)) {
    error('函数 fill 第一个参数必须是数组')
  }
  const s = isNumber(start) ? start : 0
  const e = isNumber(end) ? end : arr.length
  for (let i = s, len = e; i < len; i++) {
    // 如果元素未定义或为空或可以替换,则填充指定值
    if (isNull(arr[i]) || isUndefined(arr[i]) || replace) {
      arr[i] = value
    }
  }
  return arr
}
……

然后运行npm run docs就可以了。(运行之前手动删除一下文档生成目录下的文件,我还没找到自动删除文件的插件)

单元测试

用 mochajest 之类的测试工具就不要看了,我这里总是报错,所以直接用的chai断言库+手写测试文件。

项目新建test文件夹,测试用例写在这里面。(windows 下 tree 命令可以生成目录树)

// 目录
/test
│  index.html
└─js
    ├─lib
    │      chai.js
    │      lodash.js
    │      tool.js
    └─testScript
            array.fill.js
            array.sort.js
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>xxx.js测试</title>
  <script src=".././dist/index.js"></script>
  <script src="./js/lib/tool.js"></script>
  <script src="./js/lib/chai.js"></script>
  <script src='./js/lib/lodash.js'></script>
</head>
<body>
  <div id="container"></div>
  <script src="./js/testScript/array.fill.js"></script>
  <!-- <script src="./js/testScript/array.sort.js"></script> -->
</body>
</html>
// test/js/lib/tool.js
/**
 * 测试函数
 * @param {string} describe 描述
 * @param {Function} func 要执行的测试函数
 * @param {*} expect 结果
 */
function test(describe, func) {
  let s = Date.now()
  let success = true
  let res = null
  try {
    res = func()
  } catch (e) {
    res = e
    success = false
  }
  let color = res && success ? 'color: lightGreen;' : 'color: red;'
  let str = `%c ${describe}: ${success}, time: ${Date.now() - s}ms`
  console.log(str, color)
  if (!success) {
    console.error(res)
  }
}
// test/js/lib/test/array.fill.js
(() => {
  const T = tinyUtil

  /**
   * 测试数组 fill
   */
  test('数组填充-参数检查', () => {
    const _ = () => {
      return T.array.fill()
    }
    return chai.expect(_).to.throw()
  })

  test('数组填充-不替换', () => {
    const _ = () => {
      return T.array.fill([1, 2, 3, null, ,], 1)
    }
    return chai.expect(_()).to.deep.equal([1, 2, 3, 1, 1])
  })

  test('数组填充-替换', () => {
    const _ = () => {
      return T.array.fill([1, 2, 3, 4, null], 1, null, null, true)
    }
    return chai.expect(_()).to.deep.equal([1, 1, 1, 1, 1])
  })

  test('数组填充-补充不足的元素', () => {
    const _ = () => {
      return T.array.fill([1], 1, null, 5, true)
    }
    return chai.expect(_()).to.deep.equal([1, 1, 1, 1, 1])
  })
})()

然后,浏览器打开index.html文件,控制台就有结果了。