Maison  >  Article  >  interface Web  >  Principe et implémentation de l'utilisation du module webpack pour empaqueter la bibliothèque

Principe et implémentation de l'utilisation du module webpack pour empaqueter la bibliothèque

亚连
亚连original
2018-05-31 13:53:281842parcourir

Cet article présente principalement le principe et la mise en œuvre de la bibliothèque d'empaquetage du module d'organisation webpack. Maintenant, je le partage avec vous et le donne comme référence.

Un article précédent a analysé les principes de base du packaging des modules JS par Webpack. Le cas présenté est la situation la plus courante, c'est-à-dire que plusieurs modules JS et un module d'entrée sont regroupés dans un fichier bundle, qui peut être directement exécuté. par un navigateur ou autre moteur JavaScript, cela équivaut à une compilation directe pour générer un fichier exécutable complet. Cependant, il existe une autre situation très courante : nous souhaitons créer et publier une bibliothèque JavaScript. Par exemple, si vous publiez votre propre bibliothèque dans la communauté npm, Webpack a besoin d'une configuration correspondante et le code compilé sera légèrement différent. .

Comme l'article précédent, cet article analyse principalement le code généré de Webpack, et le combine pour expliquer le rôle spécifique des options de configuration de la bibliothèque de Webpack lors de la compilation de la bibliothèque. La documentation officielle correspondante est ici.

Bibliothèque pour écrire du JS

Commençons par un cas simple Nous écrivons simplement une bibliothèque simple util.js :

import $ from 'jquery'

function sayHello() {
 console.log("Hello");
}

function hideImages() {
 $('img').hide();
}

export default {
 sayHello: sayHello,
 hideImages: hideImages
}

fournit deux fonctions. Bien sûr, elles n'ont rien à voir l'une avec l'autre et ne sont en réalité d'aucune utilité. Elles sont uniquement à titre de référence pédagogique. . .

Écrivez ensuite la configuration de Webpack :

// 入口文件
entry: {
 util: './util.js',
}

// 输出文件
output: {
 path: './dist',
 filename: '[name].dist.js'
}

Mais cela seul ne suffit pas, le fichier de sortie sera exécuté immédiatement, la fonction sera renvoie enfin les exportations de util.js En vous référant à l'analyse de l'article précédent, la structure finale du code du bundle généré ressemble à ceci :

(function(modules) {
 var installedModules = {};
 
 function webpack_require(moduleId) {
   // ...
 }

 return webpack_require('./util.js');
}) ({
 './util.js': generated_util,
 '/path/to/jquery.js': generated_jquery
});

. S'il est exécuté, c'est fini. Il renvoie uniquement la partie export de util.js. Ce dont nous avons besoin est de donner cette valeur de retour au module.export du fichier compilé, afin que le fichier compilé devienne une bibliothèque pouvant être utilisée. importés par d'autres. Le fichier compilé que nous espérons obtenir devrait donc ressembler à ceci :

module.exports = (function(modules) {
 var installedModules = {};
 function webpack_require(moduleId) {
   // ...
 }
 return webpack_require('./util.js');
}) ({
 './util.js': generated_util,
 '/path/to/jquery.js': generated_jquery
});

Pour obtenir un tel résultat, les informations de la bibliothèque doivent être ajoutées à la sortie. fait partie de la configuration du Webpack :

// 入口文件
output: {
 path: './dist',
 filename: '[name].dist.js',

 library: 'util',
 libraryTarget: commonjs2
}

La chose la plus importante ici est libraryTarget. Si nous utilisons maintenant le format commonjs2, nous obtiendrons le résultat de compilation ci-dessus. , ce qui signifie que Webpack bibliothèquera la dernière La sortie est exportée sous forme de CommonJS, réalisant ainsi la sortie d'une bibliothèque.

Autres formats de publication

En plus de commonjs2, libraryTarget propose d'autres options :

var (默认值,发布为全局变量)
commonjs
commonjs2
amd
umd

Utiliser différentes options, Les fichiers compilés peuvent être utilisés dans différents environnements d'exécution JavaScript. Ici, nous regardons directement la sortie du format umd d'huile de serpent :

(function webpackUniversalModuleDefinition(root, factory) {
 if(typeof exports === 'object' && typeof module === 'object') // commonjs2
  module.exports = factory();
 else if(typeof define === 'function' && define.amd)
  define("util", [], factory); // amd
 else if(typeof exports === 'object')
  exports["util"] = factory(); // commonjs
 else
  root["util"] = factory(); // var
}) (window, function() {
 return (function(modules) {
  var installedModules = {};
  function webpack_require(moduleId) {
    // ...
  }
  return webpack_require('./util.js');
 }) ({
  './util.js': generated_util,
  '/path/to/jquery.js': generated_jquery
 });
}

C'est beaucoup plus compliqué que la situation précédente commonjs2 car elle nécessite des poignées diverses cas différents, mais en fait les parties suivantes sont les mêmes. Les plus importantes sont les premières lignes. C'est la manière standard d'écrire le module umd. Il exécute la fonction d'usine transmise, qui est en fait la fonction qui charge le module, puis transmet le résultat renvoyé à l'objet correspondant en fonction des différents environnements d'exploitation. Par exemple, var définira le résultat comme une variable globale, qui est utilisée par le navigateur pour importer directement le fichier JS via la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a est un environnement AMD, il sera également utilisé en écriture AMD standard. De cette manière, la bibliothèque JS publiée peut être utilisée par d'autres dans n'importe quel environnement.

targetExport contrôle le contenu de sortie

Si vous utilisez le format umd pour empaqueter, il peut y avoir un écueil auquel vous devez faire attention si le code source de votre bibliothèque est exporté au format ES6. export default, comme ci-dessus Prenez util.js comme exemple Si vous placez le fichier de bibliothèque JS compilé directement dans le navigateur et que vous l'utilisez, il peut s'agir de <script> ou RequireJS, mais vous n'obtiendrez peut-être pas les résultats souhaités. En effet, l'objet que votre fichier JS vous renvoie ressemble à ceci : <p><p class="jb51code"><pre class="brush:js;">{ &amp;#39;default&amp;#39;: { sayHello: sayHello, hideImages: hideImages } }</pre><p> au lieu de ce à quoi vous vous attendiez : <p> <p class="jb51code"><pre class="brush:js;">{ sayHello: sayHello, hideImages: hideImages }</pre><p>Ce problème se produira également non seulement dans les navigateurs, mais également dans les systèmes de modules qui ne prennent pas en charge ES6, car ils ne comprennent pas les paramètres par défaut. Ainsi, votre fichier JS compilé ne devrait en fait afficher que la valeur par défaut, qui doit être contrôlée par targetExport dans la configuration du Webpack : <p>library : 'util',<p>libraryTarget : umd,<br/>targetExport : 'default' <br/>De cette façon, la fabrique de fonctions de chargement de module ci-dessus ajoutera un ['default'] après la valeur de retour, afin que seule la partie par défaut des exports soit renvoyée. <p>Ce piège est en fait assez simple à surmonter au format umd. Par exemple, si vous publiez un composant Vue, la partie JavaScript du fichier .vue exporte généralement l'objet Component dans le format d'exportation par défaut, comme. Comme ceci : <p><p class="jb51code"><pre class="brush:js;">export default { name: &amp;#39;xxx&amp;#39;, data: { return // ... }, props: { // ... } methods: { // ... } }</pre><p>Si vous exécutez le fichier JS compilé directement dans le navigateur et que vous le chargez via 3f1c4e4b6b16bbbd69b2ee476dc4f83a que Vue ne peut pas reconnaître ce composant car l'objet que vous obtenez a une couche par défaut inutile. <p><p>Vous pouvez demander si je modifie le contenu de sortie par défaut, cela affectera-t-il l'utilisation de ce module dans l'environnement ES6 ? De manière générale non. Comme mentionné dans un article précédent, lorsque le code généré par Webpack introduit un module, il définira et déterminera s'il s'agit d'une exportation au format ES6 via une valeur appelée __esModule. Désormais, si seule la partie par défaut est exportée, alors cet objet est considéré comme non-. ES6 car il ne contient pas __esModule. De cette façon, lorsque d'autres modules introduisent ce module via l'importation, l'objet entier sera importé, ce qui équivaut en fait à importer uniquement la partie d'exportation par défaut du module d'origine déguisée. <p>Bien sûr, le principe de la discussion ci-dessus est que tout le contenu que vous devez exporter est par défaut. Si vous disposez à la fois d'une exportation par défaut et d'une exportation normale, il n'est évidemment pas possible que le fichier compilé exporte uniquement la partie par défaut. <p>Ce qui précède est ce que j'ai compilé pour vous. J'espère que cela vous sera utile à l'avenir. <p>Articles connexes : <p><a href="http://www.php.cn/js-tutorial-399225.html" target="_blank">200 lignes de code pour implémenter la blockchain Explication détaillée des exemples de blockchain<br/><p><a href="http://www.php.cn/js-tutorial-399226.html" target="_blank">Vue utilise Facebook Twitter pour partager des exemples<br/><p><a href="http://www.php.cn/js-tutorial-399224.html" target="_blank">react crée un projet basé sur create-react-app<br/><p><p class="clearfix"><span class="jbTestPos"></script>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn