Maison interface Web js tutoriel Une explication approfondie des principes de base des modules Webpack

Une explication approfondie des principes de base des modules Webpack

May 31, 2018 pm 01:58 PM
web webpack 基本

Cet article présente principalement le principe du module d'organisation du webpack. Maintenant, je le partage avec vous et vous donne une référence.

Il est désormais courant d'utiliser Webpack pour empaqueter JS et d'autres fichiers sur le front-end. Couplée à la popularité de Node, la méthode d'ingénierie front-end devient de plus en plus similaire au back-end. Tout est finalement modularisé et compilé. En raison des mises à jour constantes des versions de Webpack et de diverses options de configuration compliquées, des erreurs mystérieuses se produisent lors de l'utilisation, ce qui rend souvent les gens confus. Il est donc très utile de comprendre comment Webpack organise les modules compilés et comment le code généré est exécuté, sinon ce sera toujours une boîte noire. Bien sûr, je suis un novice en front-end et je viens de commencer récemment à étudier les principes de Webpack, je vais donc prendre quelques notes ici.

Module de compilation

Le mot "compiler" sonne comme une technologie très noire, et le code généré est souvent un gros gâchis de choses incompréhensibles, donc c'est souvent C'est intimidant, mais les principes fondamentaux ne sont en réalité pas difficiles du tout. La soi-disant compilation de Webpack n'est en fait qu'une fois que Webpack a analysé votre code source, y a apporté certaines modifications, puis a organisé tout le code source dans un seul fichier. Enfin, un gros fichier bundle JS est généré, qui est exécuté par le navigateur ou un autre moteur Javascript et renvoie le résultat.

Voici un cas simple pour illustrer le principe du module packaging Webpack. Par exemple, nous avons un module mA.js

var aa = 1;

function getDate() {
 return new Date();
}

module.exports = {
 aa: aa,
 getDate: getDate
}
Copier après la connexion

J'ai défini avec désinvolture une variable aa et une fonction getDate, puis je les ai exportées. Ceci est écrit en CommonJS.

Définissez ensuite un app.js comme fichier principal, toujours dans le style CommonJS :

var mA = require('./mA.js');

console.log('mA.aa =' + mA.aa);
mA.getDate();
Copier après la connexion

Nous avons maintenant deux modules, packagés avec Webpack, et le fichier d'entrée est app js, dépend du module mA.js, Webpack doit faire plusieurs choses :

  1. À partir du module d'entrée app.js, analyser les dépendances de tous les modules, et mettre tous les modules utilisés Lire dans .

  2. Le code source de chaque module sera organisé dans une fonction qui s'exécutera immédiatement.

  3. Réécrivez la syntaxe liée à require et export dans le code du module, ainsi que leurs variables de référence correspondantes.

  4. Établissez un système de gestion de modules dans le fichier bundle finalement généré, qui peut charger dynamiquement les modules utilisés au moment de l'exécution.

On peut jeter un oeil à l'exemple ci-dessus, résultat du packaging Webpack. Le fichier bundle final est généralement une fonction volumineuse qui est exécutée immédiatement. Le niveau organisationnel est relativement complexe et le grand nombre de noms est relativement obscur, j'ai donc apporté quelques réécritures et modifications ici pour le rendre aussi simple et facile à comprendre. possible.

Tout d'abord, répertoriez tous les modules utilisés et utilisez leurs noms de fichiers (généralement des chemins complets) comme identifiants pour créer une table :

var modules = {
 './mA.js': generated_mA,
 './app.js': generated_app
}
Copier après la connexion
Copier après la connexion

La clé est la suivante : Qu'est-ce qui est généré_xxx ? Il s'agit d'une fonction qui enveloppe le code source de chaque module à l'intérieur, ce qui en fait une portée locale, de sorte que les variables internes ne soient pas exposées, et transforme en fait chaque module en une fonction d'exécution. Sa définition est généralement la suivante :

function generated_module(module, exports, webpack_require) {
  // 模块的具体代码。
  // ...
}
Copier après la connexion

Le code spécifique du module fait ici référence au code généré, que Webpack appelle code généré. Par exemple, mA, après réécriture, obtient ce résultat :

function generated_mA(module, exports, webpack_require) {
 var aa = 1;
 
 function getDate() {
  return new Date();
 }

 module.exports = {
  aa: aa,
  getDate: getDate
 }
}
Copier après la connexion

À première vue, cela semble être exactement le même que le code source. En effet, mA ne nécessite ni n'importe d'autres modules, et l'export utilise également le style traditionnel CommonJS, il n'y a donc aucun changement dans le code généré. Cependant, il convient de noter que le dernier module.exports = ..., le module ici est le paramètre module passé de l'extérieur, qui nous indique en fait que lorsque cette fonction est exécutée, le code source du module mA sera exécuté , et enfin Le contenu qui doit être exporté sera enregistré en externe. Cela marque la fin du chargement de mA, et l'élément externe est en fait le système de gestion de modules dont nous parlerons plus tard.

Ensuite, regardez le code généré de app.js :

function generated_app(module, exports, webpack_require) {
 var mA_imported_module = webpack_require('./mA.js');
 
 console.log('mA.aa =' + mA_imported_module['aa']);
 mA_imported_module['getDate']();
}
Copier après la connexion

Comme vous pouvez le voir, la partie concernant le module mA introduit dans le code source de app.js a été modifiée , car ni require/exports ni import/export de style ES6 ne peuvent être directement exécutés par l'interpréteur JavaScript. Il doit s'appuyer sur le système de gestion de modules pour concrétiser ces mots-clés abstraits. En d'autres termes, webpack_require est l'implémentation spécifique de require, qui peut charger dynamiquement le module mA et renvoyer le résultat à l'application.

À ce stade, vous avez peut-être progressivement construit l'idée d'un système de gestion de modules dans votre esprit. Jetons un coup d'œil à la mise en œuvre de webpack_require :

// 加载完毕的所有模块。
var installedModules = {};

function webpack_require(moduleId) {
 // 如果模块已经加载过了,直接从Cache中读取。
 if (installedModules[moduleId]) {
  return installedModules[moduleId].exports;
 }

 // 创建新模块并添加到installedModules。
 var module = installedModules[moduleId] = {
  id: moduleId,
  exports: {}
 };
 
 // 加载模块,即运行模块的生成代码,
 modules[moduleId].call(
  module.exports, module, module.exports, webpack_require);
 
 return module.exports;
}
Copier après la connexion

Faites attention au. mots modules dans l'avant-dernière phrase C'est le code généré de tous les modules que nous avons définis précédemment :

var modules = {
 './mA.js': generated_mA,
 './app.js': generated_app
}
Copier après la connexion
Copier après la connexion

La logique de webpack_require est très clairement écrite. Tout d'abord, vérifiez si le module a été chargé. Si c'est le cas. , renvoie le résultat des exports du module directement depuis le Cache. S'il s'agit d'un tout nouveau module, créez le module de structure de données correspondant et exécutez le code généré de ce module. Ce que cette fonction transmet est l'objet module que nous avons créé et son champ d'exportation. Il s'agit en fait des champs d'exportation et d'exportation dans CommonJS. . L'origine du module. Après avoir exécuté cette fonction, le module est chargé et les résultats qui doivent être exportés sont enregistrés dans l'objet module.

所以我们看到所谓的模块管理系统,原理其实非常简单,只要耐心将它们抽丝剥茧理清楚了,根本没有什么深奥的东西,就是由这三个部分组成:

// 所有模块的生成代码
var modules;
// 所有已经加载的模块,作为缓存表
var installedModules;
// 加载模块的函数
function webpack_require(moduleId);
Copier après la connexion

当然以上一切代码,在整个编译后的bundle文件中,都被包在一个大的立即执行的匿名函数中,最后返回的就是这么一句话:

return webpack_require(‘./app.js');
Copier après la connexion

即加载入口模块app.js,后面所有的依赖都会动态地、递归地在runtime加载。当然Webpack真正生成的代码略有不同,它在结构上大致是这样:

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

 return webpack_require('./app.js');
}) ({
 './mA.js': generated_mA,
 './app.js': generated_app
});
Copier après la connexion

可以看到它是直接把modules作为立即执行函数的参数传进去的而不是另外定义的,当然这和上面的写法没什么本质不同,我做这样的改写是为了解释起来更清楚。

ES6的import和export

以上的例子里都是用传统的CommonJS的写法,现在更通用的ES6风格是用import和export关键词,在使用上也略有一些不同。不过对于Webpack或者其它模块管理系统而言,这些新特性应该只被视为语法糖,它们本质上还是和require/exports一样的,例如export:

export aa
// 等价于:
module.exports['aa'] = aa

export default bb
// 等价于:
module.exports['default'] = bb
Copier après la connexion

而对于import:

import {aa} from './mA.js'
// 等价于
var aa = require('./mA.js')['aa']
Copier après la connexion

比较特殊的是这样的:

import m from './m.js'
Copier après la connexion

情况会稍微复杂一点,它需要载入模块m的default export,而模块m可能并非是由ES6的export来写的,也可能根本没有export default,所以Webpack在为模块生成generated code的时候,会判断它是不是ES6风格的export,例如我们定义模块mB.js:

let x = 3;

let printX = () => {
 console.log('x = ' + x);
}

export {printX}
export default x
Copier après la connexion

它使用了ES6的export,那么Webpack在mB的generated code就会加上一句话:

function generated_mB(module, exports, webpack_require) {
 Object.defineProperty(module.exports, '__esModule', {value: true});
 // mB的具体代码
 // ....
}
Copier après la connexion

也就是说,它给mB的export标注了一个__esModule,说明它是ES6风格的export。这样在其它模块中,当一个依赖模块以类似import m from './m.js'这样的方式加载时,会首先判断得到的是不是一个ES6 export出来的模块。如果是,则返回它的default,如果不是,则返回整个export对象。例如上面的mA是传统CommonJS的,mB是ES6风格的:

// mA is CommonJS module
import mA from './mA.js'
console.log(mA);

// mB is ES6 module
import mB from './mB.js'
console.log(mB);
Copier après la connexion

我们定义get_export_default函数:

function get_export_default(module) {
 return module && module.__esModule? module['default'] : module;
}
Copier après la connexion

这样generated code运行后在mA和mB上会得到不同的结果:

var mA_imported_module = webpack_require('./mA.js');
// 打印完整的 mA_imported_module
console.log(get_export_default(mA_imported_module));

var mB_imported_module = webpack_require('./mB.js');
// 打印 mB_imported_module['default']
console.log(get_export_default(mB_imported_module));
Copier après la connexion

这就是在ES6的import上,Webpack需要做一些特殊处理的地方。不过总体而言,ES6的import/export在本质上和CommonJS没有区别,而且Webpack最后生成的generated code也还是基于CommonJS的module/exports这一套机制来实现模块的加载的。

模块管理系统

以上就是Webpack如何打包组织模块,实现runtime模块加载的解读,其实它的原理并不难,核心的思想就是建立模块的管理系统,而这样的做法也是具有普遍性的,如果你读过Node.js的Module部分的源代码,就会发现其实用的是类似的方法。这里有一篇文章可以参考。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

vue iview组件表格 render函数的使用方法详解

微信小程序实现换肤功能

nodejs实现解析xml字符串为对象的方法示例

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Tutoriel de démarrage VUE3 : empaquetage et création avec Webpack Tutoriel de démarrage VUE3 : empaquetage et création avec Webpack Jun 15, 2023 pm 06:17 PM

Vue est un excellent framework JavaScript qui peut nous aider à créer rapidement des applications Web interactives et efficaces. Vue3 est la dernière version de Vue, qui introduit de nombreuses nouvelles fonctionnalités et fonctionnalités. Webpack est actuellement l'un des packagers de modules et outils de construction JavaScript les plus populaires, qui peut nous aider à gérer diverses ressources dans nos projets. Cet article explique comment utiliser Webpack pour empaqueter et créer des applications Vue3. 1. Installez Webpack

Utilisation de Jetty7 pour le traitement du serveur Web dans le développement d'API Java Utilisation de Jetty7 pour le traitement du serveur Web dans le développement d'API Java Jun 18, 2023 am 10:42 AM

Utilisation de Jetty7 pour le traitement du serveur Web dans le développement JavaAPI Avec le développement d'Internet, le serveur Web est devenu l'élément central du développement d'applications et est également au centre de l'attention de nombreuses entreprises. Afin de répondre aux besoins croissants des entreprises, de nombreux développeurs choisissent d'utiliser Jetty pour le développement de serveurs Web, et sa flexibilité et son évolutivité sont largement reconnues. Cet article explique comment utiliser Jetty7 dans le développement JavaAPI pour We

Protection en temps réel contre les barrages de blocage de visage sur le Web (basée sur l'apprentissage automatique) Protection en temps réel contre les barrages de blocage de visage sur le Web (basée sur l'apprentissage automatique) Jun 10, 2023 pm 01:03 PM

Le barrage de blocage du visage signifie qu'un grand nombre de barrages flottent sans bloquer la personne dans la vidéo, donnant l'impression qu'ils flottent derrière la personne. L'apprentissage automatique est populaire depuis plusieurs années, mais beaucoup de gens ne savent pas que ces fonctionnalités peuvent également être exécutées dans les navigateurs. Cet article présente le processus d'optimisation pratique des barrages vidéo. À la fin de l'article, il répertorie certains scénarios applicables. cette solution, dans l'espoir de l'ouvrir. mediapipeDemo (https://google.github.io/mediapipe/) montre le principe de mise en œuvre du calcul d'arrière-plan du serveur vidéo de téléchargement à la demande du barrage de blocage de visage grand public pour extraire la zone du portrait dans l'écran vidéo et la convertit en stockage SVG client pendant la lecture de la vidéo. Téléchargez svg depuis le serveur et combinez-le avec barrage, portrait.

Comment configurer nginx pour garantir que le serveur frps et le port de partage Web 80 Comment configurer nginx pour garantir que le serveur frps et le port de partage Web 80 Jun 03, 2023 am 08:19 AM

Tout d’abord, vous aurez un doute, qu’est-ce que le frp ? En termes simples, frp est un outil de pénétration intranet. Après avoir configuré le client, vous pouvez accéder à l'intranet via le serveur. Maintenant, mon serveur a utilisé nginx comme site Web et il n'y a qu'un seul port 80. Alors, que dois-je faire si le serveur FRP souhaite également utiliser le port 80 ? Après l'interrogation, cela peut être réalisé en utilisant le proxy inverse de nginx. A ajouter : frps est le serveur, frpc est le client. Étape 1 : Modifiez le fichier de configuration nginx.conf sur le serveur et ajoutez les paramètres suivants à http{} dans nginx.conf, server{listen80

Comment implémenter la validation de formulaire pour les applications Web à l'aide de Golang Comment implémenter la validation de formulaire pour les applications Web à l'aide de Golang Jun 24, 2023 am 09:08 AM

La validation du formulaire est un maillon très important dans le développement d'applications Web. Elle permet de vérifier la validité des données avant de soumettre les données du formulaire afin d'éviter les failles de sécurité et les erreurs de données dans l'application. La validation de formulaire pour les applications Web peut être facilement implémentée à l'aide de Golang. Cet article explique comment utiliser Golang pour implémenter la validation de formulaire pour les applications Web. 1. Éléments de base de la validation de formulaire Avant de présenter comment implémenter la validation de formulaire, nous devons savoir quels sont les éléments de base de la validation de formulaire. Éléments de formulaire : les éléments de formulaire sont

Comment activer l'accès administratif à partir de l'interface utilisateur Web du cockpit Comment activer l'accès administratif à partir de l'interface utilisateur Web du cockpit Mar 20, 2024 pm 06:56 PM

Cockpit est une interface graphique Web pour les serveurs Linux. Il est principalement destiné à faciliter la gestion des serveurs Linux pour les utilisateurs nouveaux/experts. Dans cet article, nous aborderons les modes d'accès à Cockpit et comment basculer l'accès administratif à Cockpit depuis CockpitWebUI. Sujets de contenu : Modes d'entrée du cockpit Trouver le mode d'accès actuel au cockpit Activer l'accès administratif au cockpit à partir de CockpitWebUI Désactiver l'accès administratif au cockpit à partir de CockpitWebUI Conclusion Modes d'entrée au cockpit Le cockpit dispose de deux modes d'accès : Accès restreint : il s'agit de la valeur par défaut pour le mode d'accès au cockpit. Dans ce mode d'accès vous ne pouvez pas accéder à l'internaute depuis le cockpit

Que sont les standards du Web ? Que sont les standards du Web ? Oct 18, 2023 pm 05:24 PM

Les normes Web sont un ensemble de spécifications et de directives développées par le W3C et d'autres organisations associées. Elles incluent la normalisation du HTML, CSS, JavaScript, DOM, l'accessibilité du Web et l'optimisation des performances. En suivant ces normes, la compatibilité des pages peut être améliorée. , maintenabilité et performances. L'objectif des normes Web est de permettre au contenu Web d'être affiché et d'interagir de manière cohérente sur différentes plates-formes, navigateurs et appareils, offrant ainsi une meilleure expérience utilisateur et une meilleure efficacité de développement.

que signifie Internet que signifie Internet Jan 09, 2024 pm 04:50 PM

Le Web est un réseau mondial, également connu sous le nom de World Wide Web, qui est une forme d'application d'Internet. Le Web est un système d'information basé sur l'hypertexte et l'hypermédia, qui permet aux utilisateurs de parcourir et d'obtenir des informations en sautant entre différentes pages Web via des hyperliens. La base du Web est Internet, qui utilise des protocoles et des langages unifiés et standardisés pour permettre l'échange de données et le partage d'informations entre différents ordinateurs.

See all articles