2016-12-22 6 views
24

Avec Rollup, je peux sortir un module ES en réglant simplement l'option format sur 'es'. Comment puis-je faire la même chose avec webpack? Si ce n'est pas possible maintenant, webpack a-t-il des plans pour l'ajouter?Sortie d'un module ES à l'aide du Webpack

La seule chose que j'ai trouvé dans le documentation for output.libraryTarget qui mentionne des modules ES est la suivante:

libraryTarget: "commonjs-module" - Expose à l'aide de l'objet module.exports (output.library est ignoré), __esModule est défini (il est enfilée comme ES2015 Module en mode interop)

Cependant, ce n'est pas très clair pour moi. Est-ce la même chose que libraryTarget: "commonjs2" avec la seule différence que __esModule est définie? Qu'est-ce que le "mode interop"?

Répondre

10

Webpack2 fait n Si vous n'avez pas encore de bibliothèque appropriée, elle ne génère pas de bundles ES6. De l'autre côté Si vous regroupez votre bibliothèque dans CommonJS bundlers ne sera pas en mesure d'exécuter Tree Shaking, ne pas être en mesure d'éliminer les modules inutilisés. Cela est dû au fait que les modules ES sont en cours de développement, donc personne ne livre de bundles ES au navigateur, tandis que webpack est principalement utilisé pour créer des bundles compatibles avec le navigateur. De l'autre côté, si vous publiez une bibliothèque, vous pouvez fournir des cibles CommonJS (umd) et ES, grâce à "module" key in package. json. En fait vous n'avez pas besoin de webpack pour publier la cible ES, tout ce que vous avez à faire est de lancer babel sur chaque fichier pour l'obtenir sur standart es2015, par exemple si vous utilisez réagissez vous pouvez lancer babel avec juste "preset" preset. Si votre source est déjà ES 2015 sans fonctionnalités supplémentaires que vous pouvez pointer le module directement à vos src/index.js:

//package.json 
... 
    "module": "src/index.js" 
    "main": "dist/your/library/bundle.js 
... 

je l'ai trouvé facile à utiliser pour gérer babel export v from 'mod' instructions dans mes index.js principales, donc je avoir 1 fichier de module exportant tous mes modules. C'est fait avec babel-plugin-transform-export-extensions (également inclus dans le preset de stage-1).

Je repère cette approche à partir de la bibliothèque reac-bootstrap, vous pouvez voir les scripts dans leur github (ils sont webpack1). J'ai amélioré leurs scripts un peu dans mon react-sigma repo, ne hésitez pas à copier les fichiers suivants qui feront ce que vous avez besoin:

config/babel.config.js 
scripts/buildBabel.js 
scripts/es/build.js 
scripts/build.js // this is command line controller, if you need just ES you don't need it 

Regardez aussi la cible lib (scripts/lib/build.js et .babelrc), je fournissez des modules lib transpiled pour que les utilisateurs de la bibliothèque puissent inclure uniquement les modules dont ils ont besoin même sans que ES spécifie explicitement require ("react-sigma/lib/Sigma /"), particulièrement utile si votre lib est lourde et modulaire!

+0

Le problème que j'ai trouvé en important directement 'src/index.js' est que cela ne fonctionne pas si la source originale est en train d'importer des images, sass, etc. puisque vos chargeurs dans webpack.config vont normalement exclure' node_modules' pour ces fichiers les types. – row1

+0

node_modules exclus de babel-loader, puisque les bibliothèques expédiées déjà transpilées nous n'avons pas besoin de babel là-bas. Si la source a besoin d'importer des images ou d'autres éléments, la configuration doit être étendue avec un chargeur approprié, par exemple un chargeur de fichiers ou un chargeur sass avec des paramètres pour inclure des modules nodaux si nécessaire. Les images de référence ou les bonnes pratiques css consistent à copier tout le contenu statique dans le dossier statique de votre application. –

9

Tout d'abord, je voudrais dire la différence entre le commonJS et commonJS2

CommonJS ne supporte pas l'utilisation de module.exports = function() {} qui est utilisé par node.js et bien d'autres commonJS mises en œuvre.

Webpack2 utilise le concept de la vente liée le code de la bibliothèque et l'utilisation généralisée de celui-ci et de le rendre compatible de travailler dans des environnements différents, nous utilisons l'option - libraryTarget

Maintenant la partie ici répondra à vos deux questions

Les options de bibliothèque possibles pris en charge dans webpack2 sont

  • libraryTarget: "umd", // enum
  • libraryTarget: "umd-module", // ES2015 module wrapped in UMD
  • libraryTarget: "commonjs-module", // ES2015 module wrapped in CommonJS
  • libraryTarget: "commonjs2", // exported with module.exports
  • libraryTarget: "commonjs", // exported as properties to exports
  • libraryTarget: "amd", // defined with AMD defined method
  • libraryTarget: "this", // property set on this
  • libraryTarget: "var", // variable defined in root scope

Int erlop a la signification suivante

Afin d'encourager l'utilisation des CommonJS et ES6 modules, lors de l'exportation d'un default export sans autre exportsmodule.exports sera mis en plus exports["default"] comme indiqué dans l'exemple suivant

export default test; 
exports["default"] = test; 
module.exports = exports["default"]; 

donc, fondamentalement, cela signifie que le commonJS-module peut être utilisé par exposant comme module.exports en utilisant le interloping avec le module ES2015 enveloppé dans CommonJS

Plus d'informations sur le interloping se trouve dans cette blogpost et le stackoverflow link à lui.

L'idée de base est ES6 exportation d'exécution et les propriétés d'importation ne peut pas être modifié mais commonJScela fonctionne bien comme nécessitent des changements se produisent lors de l'exécution donc il a ES2015 est interloped avec le communJS.

Mise à jour

Webpack 2donne la possibilité de créer la bibliothèque qui peut être empaqueté et inclus.

Si vous souhaitez que votre module soit utilisé dans différents environnements , vous pouvez l'assembler en tant que bibliothèque en ajoutant les options de bibliothèque et en les affichant dans votre environnement spécifique. Procédure mentionnée dans le docs.

Un autre exemple simple sur la façon d'utiliser CommonJS-module

point important à noter ici est babel ajoute exports.__esModule = true à chaque es6 module et sur l'importation qu'elle appelle la _interopRequire pour vérifier cette propriété.

__esModule = true besoin d'être défini uniquement sur bibliothèque exportation. Il doit être défini sur le exports du module d'entrée . Les modules internes n'ont pas besoin de __esModule, c'est juste un hack babel.

Comme indiqué dans la documentation

__esModule est défini (il est filetée comme ES2015 Module en Mode PIA)

Utilisation comme mentionné dans le test cases

export * from "./a"; 
export default "default-value"; 
export var b = "b"; 

import d from "library"; 
import { a, b } from "library"; 
+0

Pourriez-vous répondre à ma question principale: est-il possible de sortir un module ES en utilisant webpack? De même, comment 'commonjs-module' fonctionne avec les exportations nommées? –

+0

Cela ne répond toujours pas à ma question. –

+0

Si vous ne comprenez pas ce que j'ai écrit dans la mise à jour, alors la réponse est oui - en ajoutant l'option de la bibliothèque, et le nom de l'exportation des cas de test comme mentionné ci-dessus. –