web-dev-qa-db-fra.com

Webpack 3, Babel et Tree shaking ne fonctionnent pas

J'essaie de trouver un moyen de secouer l'arborescence de mes modules et d'utiliser Babel avec Webpack.

Si je prends l'exemple de code de la documentation du webpack ( https://webpack.js.org/guides/tree-shaking/ ) et l'exécute, les modules/fonctions/autres exports qui ne sont pas utilisés sont marqués comme des exportations d'harmonie inutilisées, ce qui est le résultat attendu. Après avoir exécuté webpack avec l'argument -p (production), webpack utilise UglifyJS pour supprimer le code mort et inutilisé (pour secouer l'arborescence).

Maintenant, si j'ajoute babel-loader à mon fichier de configuration webpack, mes modules ES2015 sont transpilés mais ne sont plus marqués comme exportations inutilisées.

Ainsi, par exemple:

math.js

export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}

app.js (mon fichier d'entrée)

import {square} from './math.js'

En exécutant ceci via webpack [~ # ~] sans [~ # ~] babel-loader, la fonction cube sera marquée comme inutilisée et supprimé après compilation pour la production (-p).

En exécutant ceci via webpack [~ # ~] avec [~ # ~] babel-loader, la fonction cube ne sera pas marquée comme inutilisé et restera dans le bundle compilé.

Qu'est-ce que je rate?

Éditer

Voici un dépôt de démonstration qui peut reproduire la situation

https://github.com/Milanzor/babel-and-treeshaking-question

Mettre à jour

Si j'ajoute un .babelrc:

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "entry",
      "debug": true,
      "targets": {
        "browsers": ["last 2 versions"]
      }
    }]
  ]
}

J'obtiens le même résultat, mais si j'ajoute modules: false aux options preset-env, Babel ne compile pas les modules vers ES5 et Webpack marque les modules comme inutilisés à nouveau.

Conclusion

Je dois trouver un moyen de dire à Webpack que mes modules sont transposés avec Babel, ou je dois trouver un moyen de dire à Babel de rechercher lui-même les codes inutilisés.

12
Milanzor

L'agitation d'arbre intégrée de Webpack fonctionne uniquement avec la syntaxe du module ES6. Si vous utilisez les paramètres par défaut de Babel, Babel compilera les modules ES6 en modules CommonJS, ne laissant rien à Webpack pour fonctionner.

Généralement, les utilisateurs de Webpack voudront passer modules: false au préréglage qu'ils utilisent pour ES6 (probablement preset-env?), faisant ainsi

{
  presets: [
    ['env', { modules: false }],
  ],
}

alternativement, vous pouvez envisager d'utiliser un plugin comme https://github.com/indutny/webpack-common-shake pour activer le tremblement d'arbre pour les modules CommonJS.

Mettre à jour

Si vous utilisez Babel 7 (et donc @babel/preset-env), l'option modules est désormais automatiquement false lorsqu'elle est utilisée dans Webpack, cette configuration explicite ne devrait donc plus être nécessaire.

29
loganfsmyth