Gatsby3(Webpack5环境)下导入countdown库返回空对象问题求助
问题根因
Webpack 5 默认开启了严格 CommonJS 模块解析规则,和旧版本的核心差异是:当第三方 UMD 包内部手动声明了顶层var module;未赋值变量时,Webpack 5 不会再优先注入打包运行时的module对象,而是会将库内部声明的undefined值的module传入闭包,导致module && module.exports的判断不成立,模块不会正常导出到module.exports,所以你import的时候拿到空对象。
可落地的解决思路
方法1:修正 imports-loader 配置(推荐)
你之前的 imports-loader 配置没有正确指向要注入的变量,改成以下配置即可:
// 如果是原生webpack项目,写在webpack.config.js的module.rules里 // 如果是Gatsby项目,需要写在gatsby-node.js的onCreateWebpackConfig钩子中 { test: /countdown\.js$/, use: [ { loader: 'imports-loader', options: { // 强制注入webpack运行时的module对象,覆盖库内部声明的var module additionalCode: 'var module = require("module");' } } ] }
方法2:用 exports-loader 直接指定导出内容
这个库运行后会把countdown对象挂载到window上,可以直接指定导出全局对象,不需要走库本身的导出逻辑:
{ test: /countdown\.js$/, use: ['exports-loader?exports=default window.countdown'] }
方法3:针对countdown关闭Webpack 5的严格CommonJS解析
直接修改模块解析规则,回退到Webpack 4的兼容逻辑:
{ test: /countdown\.js$/, parser: { commonjs: { strictExports: false, strictModuleExceptionHandling: false } } }
方法4:Gatsby场景下的特殊配置注意
Gatsby不支持直接修改webpack.config.js,需要在项目根目录的gatsby-node.js中添加以下代码注入配置:
exports.onCreateWebpackConfig = ({ actions }) => { actions.setWebpackConfig({ module: { rules: [ // 上面三种方法任选一种的rule放在这里 ] } }) }
临时兜底方案
直接通过CDN引入countdown库,在项目的gatsby-browser.js中引入CDN资源,然后在ts类型声明文件中添加declare const countdown: any,不需要import就可以直接调用全局countdown对象。
内容的提问来源于stack exchange,提问作者Chayemor
相关产品推荐
相关产品推荐

