一、现象与结果
先说结果,要不从问题到结果可能太大相庭径,都看不下去。
结论就是:
- webpack + react 的业务项目,使用了一份由 webpack 打包出来的 umd(不了解 umd 可以看知乎上大佬的文章) 库 library。
- library 源代码是用 es6 语法写的。
- 业务项目 这边对于这个 library 的 import 出来的值只是个空对象,没有源代码导出的东西。
- 在 react 脚手架(create-react-app)创建出来的项目使用 library,却可以得到导出值。
抽丝剥茧后发现是@babel/plugin-transform-runtime
插件,将 library 处理为 es module,导致项目在使用 library 的时候,因为 webpack 自身的包装函数作用,使得 library 使用出现了偏差而有问题。
二、从头看起
上面描述还是有点难理解,需要结合代码来看,否则云里雾里。
起因是需求为,想要把一些 react 组件或者页面打包成一个完整的功能块,发成依赖库。选择了用 webpack 打出 umd 功能的包。
(这里说一下,对于打包库的工具,还是不建议用 webpack,可以选择 rollup 等其他。因为 webpack 为了处理模块化,引入了自身的包装函数,导致代码不太“纯净”。对此需求其实之前已经对 vue 工程有过这样的实操,用 rollup 打包,以路由模块的形式引入。)
同事试了之后,就是没导出值。找我一起探讨,我看到网上说,webpack4 似乎不支持产出 es module 的包,只有 umd 格式的。由此还有相应专门处理的插件,至此,我以为就单纯是 webpack4 不支持而已。
周末时候有时间,我就想确实自己没细细研究过 webpack 到底能不能打出 es module 的库,知道能打出 umd 格式的。之前做工具库的时候,使用的也是 rollup 和 gulp。正好研究下,看看到底打出来的东西有虾米不同。
首先用 webpack5(这里说一下,webpack 4 和 5 差别挺大,包装函数都大大缩小了) 打包出一份 umd 的 library,然后顺手在一个 react 脚手架 cra 创建出来的项目试了,嗯,可以。webpack5 果然可以。
接着换成 webpack4,同样配置,打包输出,还是在刚刚的项目引入,来看看到底为啥…woc?也可以?webpack 4、5 打包出来的 umd library 在 cra 项目都可以。马上换到实际项目一看,还是没有导出值。也就是和 webpack 版本打包出来无关,和具体的使用方项目的配置有关!这就刺激了,因为不知道原因和原理,只能逐一分析对比,没想到又来到大家来找茬环节。