webpack中globalObject配置

2019年10月15日Web前端

自己写了个npm的包,并且配置了webpack中的libraryTarget配置,使其能够用umd的方式去生成js文件,这样使得包既可以npm的方式引入又可以script标签的方式去引入。但是当包在SSR渲染的应用中import时,就会出现报错。

问题

直接import包后,会提示window is not defined的提示。

因为SSR的应用中,服务端会提前执行掉这些全局的代码,并且组件的创建dom以及之前的生命周期也会被执行,然而在node中是没有window顶层对象的,所以报错了。

原以为是代码中的window直接调用导致,后做了if检测,但实际仍报错,后在development模式下看了下代码,发现有个传入的参数居然是window对象,

错误的window参数

对比看了下umd书写的规范,此参数应该传入的是指向当前环境的this

umd打包

处理方案

在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'
}
//....

注:

  1. npm内部还有对window或document等只有浏览器下才有的对象使用时,依旧会报错,可以在代码内部做if判断处理。
  2. 没有做if处理的话,只在对应的生命周期中使用该npm包中的api,避免报错。

这样的话打包后的文件就可以直接在SSR项目中直接import了。