手撸一个js 的npm 包
打包后的格式
commonjs vs esmodule vs AMD vs IIFE vs UMD
- commonjs
早期社区js模块化的一种方式,适用于nodejs端,为了能够在浏览器中运行,可以借助Browserify,将commonjs风格的js 代码转换成可以在浏览器中运行的代码.它的代码风格如下:
var some=require('module');
module.exports={
xxx
}
- AMD (Asychronous Module Definition)
早期浏览器中模块化的一种方式,全名是异步模块定义方式。借助requirejs可以直接在浏览器中运行amd 风格的模块化代码。它的代码风格如下:
define('moduleName',[...dependencies],function(...dependencies){
xxxxx
return modules; // all the export will be returned as an object
})
- esmodule
这个是es6模块化的一种方式,可以直接在代码中使用import/export,目前一些主流的浏览器的最新版都支持了,在nodejs 端可能还不支持。代码风格如下:
import 'xxxx'
export xxx;
- IIFE(Immediately Invoked Function Expresstion)
立即执行的函数表达式,它的好处是不会污染全局上下文,代码风格如下:
(function(){
xxx
})();
- umd (Universal Module Definition)
它其实是一种写法,使得写出的代码同时支持amd,commonjs,以及浏览器中的运行它的写法如下:
(function(root,factory){
// commonjs runtime
if(typeof exports ==='object' && typeof module === 'object'){
module.exports = factory(...require(depency));
}
// requirejs runtime
else if(typeof define === 'function' && define.amd){
define([...dependencies],factory);
}
// run in browser directly
else{
var a = typeof exports === 'object' ?
factory(...require(depency)):
factory(...root[depency]);
for(let i in a){
root[i]=a[i];
}
}
})(this,(...dependencies)=>{
// package Content
})
很显然,UMD是一种很吸引人的打包方式,同时支持CommonJs/AMD/浏览器的方式
打包工具使用与配置
我们可以使用多种工具来实现UMD的打包,
- babel, 一种常用的js转码器,可以借助它的插件来实现UMD的打包。例如,file-saver中利用 @babel/plugin-transform-modules-umd 实现了UMD的打包。命令如下:
// dev
babel -o dist/FileSaver.js --plugins @babel/plugin-transform-modules-umd src/FileSaver.js
// prod
babel -o dist/FileSaver.min.js -s --plugins @babel/plugin-transform-modules-umd --presets minify src/FileSaver.js
- webpack 强大的前端困扎器,功能强大的不要不要的,配置复杂的不要不要的。
module.exports={
output:{
library:{
// 表明最终打包输出为UMD 格式
type:'umd',
}
},
// 指明哪些包是外部的包,打包时不要打包进去
externals:{
lodash:'lodash',
},
// 表示外部的包会以什么格式出现,本包中的对外部包的引用会以依据改配置来
// 生产相应格式的代码
externalTypes:'umd'
}
npm 发布
发布就相对简单多了,
- 首先使用npm login, 登录远端的registry
- npm run build 编译包,这个自己在package.json 中定义编译脚本
- npm publish 就行了, 可以在package.json 的files 节点来定义哪些文件是需要发布的使用的是glob 语法 (**/*).每次发布的version 号要唯一,