MODIFIER : Il s'agit pas de grosses flèches. Il ne s'agit pas non plus de passer ceci à un IIFE . C'est une question liée au transpilateur.
J'ai donc créé un sous-pub simple pour une petite application sur laquelle je travaille. Je l'ai écrit dans ES6 pour utiliser spread/rest et éviter quelques maux de tête. Je l'ai installé avec npm et gulp pour le transpiler mais ça me rend fou.
J'en ai fait une bibliothèque de navigateur mais j'ai réalisé qu'elle pouvait être utilisée n'importe où, j'ai donc décidé de la rendre compatible Commonjs et AMD.
Voici une version réduite de mon code:
(function(root, factory) {
if(typeof define === 'function' && define.AMD) {
define([], function() {
return (root.simplePubSub = factory())
});
} else if(typeof module === 'object' && module.exports) {
module.exports = (root.simplePubSub = factory())
} else {
root.simplePubSub = root.SPS = factory()
}
}(this, function() {
// return SimplePubSub
});
Mais peu importe ce que j'essaye (comme faire cette une variable et la passer), elle la définit undefined .
}(undefined, function() {
Cela a probablement quelque chose à voir avec Babel ne sachant pas ce que cela sera et le transpiler, mais y a-t-il une autre approche que je peux adopter?
UPDATE : En passant }((window || module || {}), function() {
au lieu de cela semble travail. Je ne suis pas sûr que ce soit la meilleure approche.
Le code ES6 a deux modes de traitement:
<script>
, ou tout autre moyen standard ES5 de charger un fichierDans Babel 7.x, les fichiers sont analysés comme "module" par défaut. Ce qui vous pose problème, c'est que dans un module ES6, this
est undefined
, tandis que dans le "script"
cas, cela varie selon l'environnement, comme window
dans un script de navigateur ou exports
dans le code CommonJS. De même, "module"
les fichiers sont automatiquement stricts, Babel insérera donc "use strict";
.
Dans Babel 7, vous devrez indiquer à Babel de quel type est votre fichier si vous souhaitez éviter ce comportement. L'option la plus simple serait d'utiliser le "sourceType"
option pour définir sourceType: "unambiguous"
dans vos options Babel, qui indique essentiellement à Babel de deviner le type (scripts vs module), en fonction de la présence des instructions import
et export
. Le principal inconvénient étant qu'il est techniquement correct d'avoir un module ES6 qui n'utilise pas import
ou export
, et ceux-ci seraient traités à tort comme des scripts. D'un autre côté, ce n'est vraiment pas si courant.
Vous pouvez également utiliser Babel 7 "overrides"
option pour définir des fichiers spécifiques en tant que scripts, par exemple.
overrides: [{
test: "./vendor/something.umd.js",
sourceType: "script",
}],
L'une ou l'autre approche permet à Babel de savoir que certains fichiers sont de type script
et ne devraient donc pas avoir this
convertis en undefined
.
Le code ES6 a deux modes de traitement:
<script>
, ou tout autre moyen standard ES5 de charger un fichierLorsque vous utilisez Babel 6 et babel-preset-es2015
(ou Babel 5), Babel suppose par défaut que les fichiers qu'il traite sont des modules ES6. Ce qui vous pose problème, c'est que dans un module ES6, this
est undefined
et les fichiers sont tous stricts, tandis que dans le cas "script", this
varie selon l'environnement, comme window
dans un script de navigateur ou exports
dans le code CommonJS.
Si vous utilisez Babel, l'option la plus simple consiste à écrire votre code sans le wrapper UMD, puis à regrouper votre fichier à l'aide de quelque chose comme Browserify pour ajouter automatiquement le wrapper UMD pour vous. Babel fournit également un babel-plugin-transform-es2015-modules-umd
. Les deux sont orientés vers la simplicité, donc si vous voulez une approche UMD personnalisée, ils peuvent ne pas être pour vous.
Alternativement, vous devrez lister explicitement tous les plugins Babel dans babel-preset-es2015 , en veillant à exclure le module-processing babel-plugin-transform-es2015-modules-commonjs
brancher. Notez que cela arrêtera également l'ajout automatique de use strict
puisque cela fait également partie de la spécification ES6, vous voudrez peut-être rajouter babel-plugin-transform-strict-mode
pour garder votre code strict automatiquement.
À partir du [email protected]
les préréglages peuvent prendre des options, vous pouvez donc
{
"presets": [
[ "es2015", { "modules": false } ]
]
}
dans votre configuration Babel (.babelrc
) utiliser babel-preset-es2015
avec le traitement du module désactivé.
Le préréglage "es2015" encapsule la sortie Babel dans un wrapper commonJs par défaut. Utilisez le "babel-preset-es2015-script" (vous devez npm install --save babel-preset-es2015-script
premier) pour sortir pour "script" (pas de modules). Cela faisait des ravages sur d'autres bibliothèques que je terminais en utilisant Babel.
Le préréglage: https://www.npmjs.com/package/babel-preset-es2015-script