js-sdk开发经验总结

427 阅读3分钟

推荐使用rollup打包sdk

一、开发SDK需要考虑到的

  1. 产物: 要考虑你的sdk给别人使用到的场景用途,推荐产出esm模块 + umd。es便于webpack的tree shaking,剔除一些可能用不到的方法。
  2. 兼容性: 要考虑到一些新的语法,框架上需要引用polyfill来支持这些新语法。

因为在使用者那边大都是没开启对node_modules依赖包的解析,例如在webpack配置baber-loader排除了node_modules。

exclude: /node_modules/

如果没有做语法的兼容,可能会导致在低的浏览器上不支持就会出现问题报错 甚至白屏。所以有可能会需要使用者会需要多处理,不把你的sdk包排除,而是把它加入编译。

exclude: /node_modules\/(?![module1|module2])/

3.隐私性: 如果涉及一些公司内的私密关键代码等,就需要进行代码混淆加密。

二、sdk的全程链路

从编写js到其他人引用你的代码,需要经历哪些路程呢?

  1. 打包: 通过build打包你写完后的代码,到文件夹一般是dist
  2. 发布上传: 然后这时候需要通过npm publish发布,发布时候上传到npm的文件有哪些呢。会通过package.json文件中的files字段决定,一般也是写dist,就是你打包好的文件夹。
  3. 包入口: 到这里,也就是已经将写好的代码sdk上传到了npm上面,还缺乏一个关键配置,就是main字段配置,指定别人使用你的包时候的入口文件。 2023.08.09_肖国垚&a71f215278c127cbe09b4caa4f1ad7e5.png 如果是打包es的模块出来则是需要用module来指定入口文件 ,antd为例,在import { Button } from 'antd'时候就是通过这个找到对应的模块入口 image.png

重点知识小计:

你可能会疑惑,为什么node_modules里的模块语句(require、modlue.exports、import、export default)不经过Babel处理也能直接在浏览器上用上?

1、如果是es包,webpack是天生支持es模块语法的,浏览器也是。所以在使用import以及export default时候不需要经过babel处理(但需要经过webpack处理,它做的是处理模块间的依赖关系)。

2、如果是commonjs包,它可以通过require或者import进来,因为所有commonjs规范的包都是自执行函数

以lodash为例它的包是一个自执行函数: 2023.08.11_肖国垚&7486279008c50356f9f344760b0c5590.png 它的最底部会暴露出一个 _ 下划线符号的方法出来,通过该方法得到全部的方法。

// Export lodash.
var _ = runInContext();
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  root._ = _;
  define(function() {
    return _;
  });
}
else if (freeModule) {
  (freeModule.exports = _)._ = _;
  freeExports._ = _;
}
else {
  root._ = _;
}

Tip:

通过 module.exports或者exports导出的 在node上(没有webpack、Babel)支持import导入。如果是webpack的话要处理引用关系 要使用babel配置 sourceType:unambiguous

sourceType有三个值。默认值是module

module:支持import/export

unambiguous:支持混用commonjs、esm的导入导出方法

即使上面这种配置支持了混用,但是如果通过了es6的解构导入机会有问题了。

以lodash为例子:

引用非es模块的lodash文件夹下的map方法(现在新的lodash是支持了es模块,早期的包是umd模块)

// index.js
import { map } from 'lodash'

这样不支持,会报错。

但是 在rollupjs中是可以的,通过esmExternals插件导入commonjs模块

小程序中也是可以这么做的,具体为何没有深究。