Babel不会转译从“node_modules”导入的模块。

16

我在转译从node_modules导入的模块时遇到了问题。由于某些原因,Babel 不会将从 node_modules 导入的模块进行转译,但会转译从 src 导入的模块。

以下是一个示例仓库:https://github.com/NikitaKA/babeltest

main.js

// result code contains const and let, but it shouldn't. :(

index.js

import qs from 'query-string; // not transpiled
import lib from './lib' // transpiled

const query = qs.parse(window.location.search);

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

.babelrc

{
  "presets": [
    ["@babel/preset-env", {
      "modules": false,
      "targets": {
        "chrome": 39
      }
    }],
    ["@babel/preset-stage-1", {
      "modules": false,
      "decoratorsLegacy": true,
      "pipelineProposal": "minimal"
    }]
  ],
  "plugins": [
    "transform-es2015-constants",
    "@babel/plugin-transform-block-scoping",
    "@babel/plugin-transform-runtime"
  ]
}

这通常是应该的做法。您想转译已经存在于node_modules中的分发就绪模块有特殊原因吗? - AKX
顺便提一下,示例存储库缺少 webpack-cli/webpack-command,因此 start 命令无法直接使用。 - AKX
糟糕,看起来我已经全局安装了webpack-cli。 - NikitaK
5
@AKX,node_modules中的库使用const关键字,我希望将其编译为var以支持较低版本的浏览器。 - hanzichi
3个回答

10

在这种情况下的解决方案是再次转译模块,这可以通过修改 webpack 配置中的 exclude 属性来实现:

{
  test: /\.js$/,
  exclude: /node_modules\/(?!(es6-module|another-es6-module)\/).*/,
},

模块es6-moduleanother-es6-module将不再被webpack忽略,并将与您的源代码一起进行转译。

请参见webpack项目上的GitHub问题

使用webpack@3.12.0babel-core@6.26.3babel-core@6.26.3进行测试。


6

针对我的评论进一步解释:

你真的不想将所有的node_modules转换 - 这将需要很长时间,并且那里的大部分代码应该已经是ES5(除非它们实际上是ES6模块,在这种情况下,ES6入口点在package.json清单中被声明为"module")。

query-string@6.x 不是,并且在其README中也说明了:

此模块针对Node.js 6或更高版本以及最新版本的Chrome、Firefox和Safari。如果您想要支持旧版浏览器,请使用版本5:npm install query-string@5


3
我明白你的意思了。你是对的,我不应该转译分布式模块,特别是如果有支持旧版浏览器的版本(我没检查,我的错)。但是,我觉得奇怪的是,为什么你不能将现代库编译成ES5呢?如果没有旧版呢?在我的情况下,需要在旧浏览器下编译项目,很幸运在这个项目中只有一个外部库,并且它有ES5的替代品 :)。 - NikitaK
8
无论如何,是否有一种方法可以转译来自 node_modules 的模块? - NikitaK
3
这段代码是从Webpack的一个问题中提取出来的,用于配置Webpack如何处理JavaScript文件。其中,test表示匹配到的文件需要满足的正则表达式条件,这里是以.js结尾的文件;exclude表示需要排除不处理的文件夹或文件,这里是排除掉除了MY-MODULEANOTHER-ONE以外的所有node_modules文件夹及其子文件。 - Steven Kalt
4
根据我的理解,OP希望转译node_modules(或至少是特定的非规范模块)。你自己提到过模块“应该已经是ES5”(关键词“应该”)。所以有时候模块没有正确打包,我们可能需要手动进行转译...你的回答并没有回答那个问题。 - Dimitry K

1
如果你正在使用Vue,有一个简单的解决方案。只需在transpileDependencies中列出你的模块即可:

vue.config.js

module.exports = {
   publicPath: '',
   outputDir: 'www',
   transpileDependencies: [
    'query-string'
  ],
}

太棒了!这也适用于使用lerna添加的包。 - katinas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接