webpack中globalObject配置
自己写了个npm的包,并且配置了webpack中的libraryTarget配置,使其能够用umd的方式去生成js文件,这样使得包既可以npm的方式引入又可以script标签的方式去引入。但是当包在SSR渲染的应用中import时,就会出现报错。
问题
直接import
包后,会提示window is not defined
的提示。
因为SSR的应用中,服务端会提前执行掉这些全局的代码,并且组件的创建dom以及之前的生命周期也会被执行,然而在node
中是没有window
顶层对象的,所以报错了。
原以为是代码中的window
直接调用导致,后做了if
检测,但实际仍报错,后在development
模式下看了下代码,发现有个传入的参数居然是window对象,
对比看了下umd
书写的规范,此参数应该传入的是指向当前环境的this
。
处理方案
在webpack的文档上看到globalObject配置:
To make UMD build available on both browsers and Node.js, set output.globalObject option to 'this'.
由于他默认是window
,所以我们需要修改成this
,在webpack中修改output中的配置,加入globalObject
配置:
//....
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
libraryExport: 'default',
library: '[name]',
globalObject: 'this', // here
libraryTarget: 'umd'
}
//....
注:
- npm内部还有对window或document等只有浏览器下才有的对象使用时,依旧会报错,可以在代码内部做if判断处理。
- 没有做if处理的话,只在对应的生命周期中使用该npm包中的api,避免报错。
这样的话打包后的文件就可以直接在SSR项目中直接import了。