通常來講,寫完一個第三方庫須要打包出三個文件夾的文件,對應三種不一樣模塊類型javascript
# outputpath ├── dist # umd module ├── es # es module ├── lib # commonjs module
UMD(Universal Module Definition)是 AMD 和 CommonJS 的糅合,跨平臺的解決方案
;(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory() else if (typeof define === 'function' && define.amd) define([], factory) else if (typeof exports === 'object') exports['A'] = factory() else root['A'] = factory() })(window, function() { //... })
CommonJS 模塊是對象,是運行時加載,運行時才把模塊掛載在 exports 之上(加載整個模塊的全部),加載模塊其實就是查找對象屬性。
導出使用 module.exports,也能夠 exports。就是在此對象上掛屬性。exports 指向 module.exports,即 exports= module.exports
module.exports.add = function add() { return } exports.sub = function sub() { return } const a = require('a.js')
ES Module 不是對象,是使用 export 顯示指定輸出,再經過 import 輸入。此法爲編譯時加載,編譯時遇到 import 就會生成一個只讀引用。等到運行時就會根據此引用去被加載的模塊取值。因此不會加載模塊全部方法,僅取所需。
export const m = 1 export { m } import { m } from 'a.js'
若是使用 webpack 來打包 umd 文件,咱們應該配置哪些選項html
const config = { entry, output: { path: './dist', libraryTarget: 'umd', filename: 'index.min.js', library: 'MyLibrary', libraryExport: 'default' }, externals: { react: { root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react' } } }
MyLibrary.default
纔是咱們模塊的返回值。經過設置libraryExport: 'default'
,起到MyLibrary = MyLibrary.default
的效果, 不須要再經過 default
屬性去訪問返回值// webpack 會判斷不一樣的環境,並以不一樣的方式去訪問react ;(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(require('react')) else if (typeof define === 'function' && define.amd) define(['react'], factory) else if (typeof exports === 'object') exports['MyLibrary'] = factory(require('react')) else root['MyLibrary'] = factory(root['React']) })
最後再配置一下 babel-loader,就能生成咱們指望的 umd 文件了java
使用 babel 打包就很簡單了, 先看一下 babelrc 怎麼寫node
{ presets: [['@babel/env', { loose: true, modules: 'cjs' }], '@babel/preset-react'], plugins: [ ['@babel/plugin-transform-runtime', { useESModules: false }], ] }
loose
一句話解釋: true 的時候代碼更現代化代碼量少,false 更兼容代碼量也更多react
modules
設置使用不一樣的模塊類型,commonjs 的話,就設置成'cjs'webpack
babel 會給每一個編譯的文件插入一些輔助方法,若是文件一多的話,就出現了不少重複代碼,這個插件會改成從第三方包引用輔助方法,
須要額外安裝@babel/runtime
git
e.g.github
var _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault')
babel src --out-dir lib
只要把上面裏全部 module 相關的設置改爲 es module 就好了web
{ presets: [['@babel/env', { loose: true, modules: false }], '@babel/preset-react'], plugins: [ ['@babel/plugin-transform-runtime', { useESModules: true }], ] }
babel src --out-dir es
安利一波我的寫的打包庫的工具 build-my-package, js, ts都支持哦!:)shell