配置报错possible exports: __esModule是什么意思

733 阅读1分钟

我正在参加「掘金·启航计划」

对babel配置还不熟悉的,先看这篇文章:我掌握的Babel配置

报错内容:

export 'default' (imported as '_Object$keys') was not found in '@babel/runtime-corejs2/core-js/object/keys' (possible exports: __esModule)

image.png

列出配置内容

babel.config.js

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 2,
        modules: false,
      },
    ],
  ],
  plugins: [
    [
      "@babel/plugin-transform-runtime",
      {
        corejs: 2,
        // useESModules: true,
      },
    ],
  ],
};

webpack.config.js

const webpack = require("webpack");

/**
 * @type {webpack.Configuration}
 */
module.exports = {
  mode: "production",
  module: {
    rules: [
      {
        test: /\.jsx?/,
        use: ["babel-loader"],
      },
    ],
  },
};

解决

排除掉node_modules就行了

module: {
    rules: [
      {
        test: /\.jsx?/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
    ],
  },

正常来说,webpack打包不应该报错,这是个警告,本可以忽略,但是咱还是要追究清楚。

从解决方法就可以看出,是babel把node_modules的内容也编译了,造成了这个问题,所以不编译node_modules就没提醒了,我们可以设定所有node_modules的包都是已经编译成es5了的,都不需要再次编译

扩展开来__esModule是什么

__esModule是用来解决commonjs和esm对应关系的

__esModule是用来解决commonjs和esm对应关系的,比如a.js用commonjs导出,b.js用esm导入a.js,下面这些情况,如果能正确回到console.log输出,那就理解了__esModule作用

// a.js 
module.exports.a = 1
module.exports.b = 2

// b.js
import A1 from './b.js'
console.log(A1)

那么这里输出什么呢? 输出:{a:1,b:2}

// a.js 
module.exports.a = 1
module.exports.b = 2
module.exports.default = 3

// b.js
import A2 from './b.js'
console.log(A2)

那么这里输出什么呢? 输出:{a:1,b:2,default:3}

// a.js 
module.exports.a = 1
module.exports.b = 2
module.exports.default = 3
module.exports.__esModule = true

// b.js
import A3 from './b.js'
console.log(A3)

那么这里输出什么呢? 输出:A3=3

// a.js 
module.exports.a = 1
module.exports.b = 2
module.exports.default = 3
module.exports.__esModule = false

// b.js
import A4 from './b.js'
console.log(A4)

那么这里输出什么呢? 输出:{a:1,b:2,default:3,__esModule:false}

// a.js 
module.exports.a = 1
module.exports.b = 2
module.exports.__esModule = true

// b.js
import A5 from './b.js'
console.log(A5)

那么这里输出什么呢? 输出: undefined

结论

esm在导入的commonjs导出时,会根据__esModule来判断 import 默认值是到底取什么

  • commonjs 的 module.exports.__esModule = true 时,esm的import会查找是否存在 module.exports.default,如果不存在就是undefined,如果存在就导出

  • commonjs 的 module.exports.__esModule = false 或者 没设置 module.exports.__esModule 时,esm的import就是 module.exports 对象

所以我们再看webpack打包警告信息: 报错内容:

export 'default' (imported as '_Object$keys') was not found in '@babel/runtime-corejs2/core-js/object/keys' (possible exports: __esModule)

在 babel.config.js 中,我们设置了 module: false ,那么原本是用require引入core-js的方式,改为了 import导入 core-js

就能明白了这里触发了commonjs和esm的转换关系,使用了__esModule = true 属性,但是core-js中没有写 module.exports.default,会默认就导出了undefined 所以才有警告了

presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 2,
        modules: false,
      },
    ],
  ],

所以,解决方法就是在loader中exclude:/node_module/,不babel去触发node_modules中的commonjs和esm转换。

完毕!