web-dev-qa-db-fra.com

JavaScript - babel-preset-env ne transfère pas les fonctions de flèche pour IE11

J'ai de la difficulté à configurer Babel pour transpiler du code compréhensible par IE11, notamment les fonctions de flèche. Exécuter npx webpack --mode=development avec ma configuration ne convertit pas les fonctions de flèche dans mon code: dans l'instruction eval() du code généré, je peux voir que toutes les instances ne sont pas converties.

Contrairement à la sortie de la console citée dans cette question , la mention "Utilisation de cibles" ou "Utilisation de préréglages" n'est pas mentionnée dans la mine. Que ce soit avec l'utilisation de npx webpack plutôt que de npm run build je ne sais pas.

Voici la partie Babel de mon 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"
        ]
      }
    }
  }
}

Mon webpack.config.js ressemble à:

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
        ])
    ]
};

Je suis arrivé à ce point après avoir lu d'autres questions ici sur les configurations de Babel et les docs babel-preset-env ainsi que le très maigre babel-plugin-transform-es2015-arrow-function-docs . Les réponses à cette question très similaire (pas de réponse acceptée) ne mentionnent pas du tout ce plugin, et on suggère d'utiliser un polyfill, ce qui semble impliquer le chargement d'une bibliothèque dans votre code actuel plutôt qu'à ce stade?

Je suis très novice en travaillant avec Webpack en général et je ne comprends pas quelle est la différence entre "env" (qui est mentionné dans de nombreuses questions) et "@babel/preset-env". Ou vraiment ce que le premier implique en général; si vous cliquez sur "env" dans la navigation de la documentation, vous accédez à la page pour @babel/preset-env.

Qu'est-ce que je fais mal?

5
Scott Martin

Babel est en soi une bibliothèque de transformation, mais elle ne s'intégrera pas dans un outil spécifique. Pour utiliser Babel avec Webpack, vous aurez envie d'installer le paquet babel-loader et de le configurer dans votre configuration Webpack en utilisant quelque chose du type:

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

En plus de la réponse de loganfsmyth qui a résolu le problème, je tiens à signaler à tous les débutants qui lisent ceci que je me suis simplifié la vie par la suite en déplaçant la configuration de Babel de package.json dans un .babelrc.

J'ai aussi découvert que les plugins dont j'avais besoin, comme celui que j'ai mentionné ci-dessus, babel-plugin-transform-es2015-arrow-functions, ont des versions plus récentes avec un schéma de nommage différent - pour cet exemple, @babel/plugin-transform-arrow-functions. Les pages de documentation des anciennes versions ne le mentionnent pas.

La partie module de mon webpack.config.js ressemble maintenant à:

module: {
    rules: [
        {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader",
                options: {
                    presets: ["@babel/preset-env"],
                    plugins: [
                        require("@babel/plugin-transform-async-to-generator"),
                        require("@babel/plugin-transform-arrow-functions"),
                        require("@babel/plugin-transform-modules-commonjs")
                    ]
                }
            }
        }
    ]
}

Mon .babelrc ressemble à:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "ie": "11"
                },
                "useBuiltIns": "entry"
            }
        ]
    ],
    "plugins": [
        "@babel/transform-async-to-generator",
        "@babel/transform-arrow-functions",
        "@babel/transform-modules-commonjs"
    ],
    "env": {
        "development": {
            "plugins": [
                "@babel/transform-async-to-generator",
                "@babel/transform-arrow-functions",
                "@babel/transform-modules-commonjs"
            ]
        },
        "test": {
            "plugins": [
                "@babel/transform-async-to-generator",
                "@babel/transform-arrow-functions",
                "@babel/transform-modules-commonjs"
            ]
        },
        "production": {
            "plugins": [
                "@babel/transform-async-to-generator",
                "@babel/transform-arrow-functions",
                "@babel/transform-modules-commonjs"
            ]
        }
    }
}
1
Scott Martin