返回

避开前端构建中的雷区:babel-loader如何导致对已编译脚本的二次编译?

前端

前言

前端构建是一项重要的工作,它可以将源代码转换为可在浏览器中运行的代码。在前端构建中,我们经常会使用到babel-loader这个工具,它可以将ES6+代码转换为ES5代码。但是,如果您对已经编译好的脚本使用babel-loader进行二次编译,可能会导致文件执行出错。

问题

为了更形象地说明该问题,这里有一个实际案例:

我打算开发一个小组件库,但是要对已经编译完成的组件库的脚本进行一遍完整的测试。所以,很自然地启动了一个项目,引入了已经编译好的组件库脚本,想着大展伸手,结果。。。遇到了很多让人头疼的警报:

ERROR in ./node_modules/my-component-library/dist/index.js 8:23
Module parse failed: Unexpected token (8:23)
You may need an appropriate loader to handle this file type.
| 
| var main = function(exports, require, module, __filename, __dirname) { /* webpackUniversalModuleDefinition */ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; (function (factory) {
|                                                         ^

问题原因

出现这个问题的原因是,babel-loader在对已经编译好的脚本进行二次编译时,会将这些脚本中的ES5代码再次转换为ES6代码。但是,浏览器并不能识别ES6代码,因此就会导致文件执行出错。

解决方法

为了解决这个问题,我们需要在使用babel-loader进行编译时,将已经编译好的脚本排除在外。我们可以通过在webpack.config.js文件中配置babel-loader的选项来实现。

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            ignore: [
              '**/node_modules/my-component-library/dist/** '
            ]
          }
        }
      }
    ]
  }
};

在上面的配置中,我们使用了exclude属性来排除node_modules目录下的所有文件。这样,babel-loader就不会对这些文件进行编译,从而避免了这个问题。

总结

在前端构建中,使用babel-loader对已经编译好的脚本进行二次编译可能会导致文件执行出错。为了解决这个问题,我们需要在使用babel-loader进行编译时,将已经编译好的脚本排除在外。我们可以通过在webpack.config.js文件中配置babel-loader的选项来实现。