Search code examples
javascriptwebpackbabeljs

JavaScript - babel-preset-env not transpiling arrow functions for IE11


I'm having a hard time trying to configure Babel to transpile code that IE11 can understand, specifically arrow functions. Running npx webpack --mode=development with my configuration doesn't convert the arrow functions in my code: in the eval() statement in the generated code, I can see that all the instances have gone unconverted.

Unlike in the console output quoted in this question, there's no mention in mine of "Using targets" or "Using presets". Whether that's something to do with using npx webpack rather than npm run build I don't know.

Here's the Babel part of my package.json:

{
  // name, version etc. snipped
  "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-async-to-generator": "^7.1.0",
    "@babel/plugin-transform-es2015-arrow-functions": "^6.22.0",
    "@babel/plugin-transform-es2015-modules-commonjs": "^6.26.2",
    "@babel/preset-env": "^7.1.0",
    "ajv": "^6.5.4",
    "copy-webpack-plugin": "^4.5.2",
    "eslint-plugin-jest": "^21.24.1",
    "jest": "^23.6.0",
    "jest-dom": "^2.0.4",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2"
  },
  "babel": {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": {
            "ie": "11"
          }
        }
      ]
    ],
    "env": {
      "development": {
        "plugins": [
          "transform-es2015-arrow-functions",
          "transform-es2015-modules-commonjs"
        ]
      },
      "test": {
        "plugins": [
          "transform-es2015-arrow-functions",
          "transform-es2015-modules-commonjs"
        ]
      }
    }
  }
}

My webpack.config.js looks like:

const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");

module.exports = {
    entry: "./src/thing.js",
    optimization: {
        minimize: false
    },
    output: {
        filename: "thing.js",
        path: path.resolve(__dirname, "dist")
    },
    plugins: [
        new CopyWebpackPlugin([
            // snipped
        ])
    ]
};

I arrived at this point from reading other questions here about Babel configurations, and the babel-preset-env docs and also the very skimpy babel-plugin-transform-es2015-arrow-functions docs. The answers to this very similar question (no accepted answer) don't mention that plugin at all, and one suggests using a polyfill, which seems to involve loading a library in your actual code rather than at this stage?

I'm very new to working with Webpack in general and don't understand what the difference is between "env" (which gets mentioned in a lot of questions) and "@babel/preset-env". Or really what the former implies in general; if you click on "env" in the docs navigation, it takes you to the page for @babel/preset-env.

What am I doing wrong?


Solution

  • Babel itself is a transformation library, but on its own it will not integrate into any specific tooling. To use Babel with Webpack, you'll want to install the babel-loader package and configure it in your Webpack config using something along the lines of

    module: {
      rules: [
        {
          test: /\.m?js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          }
        }
      ]
    }