Maison  >  Article  >  interface Web  >  Comment la modularité est-elle implémentée dans JS ?

Comment la modularité est-elle implémentée dans JS ?

小云云
小云云original
2018-01-09 17:01:532176parcourir

En raison du positionnement initial de Js (je ne m'attendais pas à ce qu'il soit utilisé dans des scénarios trop complexes au début), il ne fournit pas de système de modules. À mesure que les applications deviennent plus complexes, la modularisation devient un problème qui doit être résolu. Conformément aux principes approfondis de Feimai, il est nécessaire de lever le voile de la modularisation. Cet article présente principalement comment la modularisation dans Js est implémentée en détail, et présente en détail le fonctionnement de la modularisation, qui a une certaine valeur de référence. Ceux qui sont intéressés peuvent en savoir plus, j'espère que cela pourra aider tout le monde.

1. Problèmes qui doivent être résolus par la modularisation

Pour mener une analyse approfondie de quelque chose, il est nécessaire de l'examiner dans un but précis. Le problème à résoudre par la modularisation peut être résumé en une phrase

Mieux organiser le code projet sans pollution globale

Pour donner un exemple simple, nous avons désormais le Code suivant :

function doSomething () {
 const a = 10;
 const b = 11;
 const add = function (a + b) {
  return a + b
 }
 add (a + b)
}

Dans des scénarios d'application réels, doSomething peut devoir faire beaucoup, beaucoup de choses, et la fonction d'ajout peut être plus complexe et peut être réutilisée, nous espérons donc rendre la fonction d'ajout indépendante dans un fichier séparé, puis :

// doSomething.js 文件
const add = require('add.js');
const a = 10;
const b = 11;
add(a+ b);
// add.js 文件
function add (a, b) {
 return a + b;
}
module.exports = add;

Le but de ceci est évident, pour mieux organiser le code du projet, remarquez le require et module.exports dans les deux fichiers, désormais Dieu D'un point de vue, cela vient de les mots-clés de la spécification CommonJS (il y aura un chapitre dédié à la spécification plus tard), qui représentent respectivement l'importation et l'exportation. Quelle que soit la spécification, il s'agit en fait d'un problème qui doit être résolu sur la voie de la modularisation. De plus, bien que le module add doive être réutilisé, nous ne voulons pas provoquer de pollution globale lors de l'introduction de add

2 Comment exécuter le module importé

Dans l'exemple ci-dessus, nous avons. Le code est divisé en deux fichiers de module. Comment pouvons-nous implémenter require pour que le code de l'exemple puisse s'exécuter normalement sans provoquer de pollution globale ?

En ignorant le processus de chargement du code du fichier du module, en supposant que require peut déjà lire la chaîne de code du fichier du module, alors require peut être implémenté comme ceci

function require (path) {
  // lode 方法读取 path 对应的文件模块的代码字符串
  // let code = load(path);
  // 不考虑 load 的过程,直接获得模块 add 代码字符串
  let code = 'function add(a, b) {return a+b}; module.exports = add';
  // 封装成闭包
  code = `(function(module) {$[code]})(context)`
  // 相当于 exports,用于导出对象
  let context = {};
  // 运行代码,使得结果影响到 context
  const run = new Function('context', code);
  run(context, code);
  //返回导出的结果
  return context.exports;
}

Il existe plusieurs clés points :

1) Afin de ne pas provoquer de pollution mondiale, la chaîne de code doit être encapsulée sous la forme d'une fermeture et le mot-clé module.exports doit être exporté. Module est le seul support. pour le contact avec le monde extérieur et doit être utilisé comme Les paramètres d'entrée de la fonction anonyme de fermeture sont associés au contexte transmis par le référent

2) Utilisez new Function pour exécuter la chaîne de code. On estime que la plupart des étudiants ne sont pas familiers avec new Function Car en général, il n'est pas nécessaire de le faire lors de la définition d'une fonction. Vous devez savoir que vous pouvez créer directement une fonction en utilisant la classe Function.

var function_name = new function(arg1, arg2, ..., argN, function_body)

Dans le formulaire ci-dessus, chaque argument est un paramètre, et le dernier paramètre est le corps de la fonction (le code à exécuter). Ces paramètres doivent être des chaînes. En d'autres termes, vous pouvez l'utiliser pour exécuter du code chaîne, similaire à eval, et par rapport à eval, vous pouvez également transmettre les valeurs de certaines variables dans le code chaîne sous forme de paramètres

3) Si vous vous êtes déjà demandé pourquoi le mot-clé standard export est uniquement exports mais que nous utilisons module.exports en utilisation réelle (cela devrait être familier à ceux qui ont écrit du code Node), alors vous pouvez trouver la réponse dans ce code, si vous utilisez uniquement les exports pour recevoir du contexte, alors la réaffectation des exports n'aura aucun impact sur le contexte (l'adresse du paramètre est transmise). Si vous n'y croyez pas, modifiez le code sous la forme suivante et exécutez-le. encore une fois :

Résultats de la démonstration

3. La méthode de chargement du code

résout le problème de l'exécution du code et doit également résoudre le problème. problème de chargement du code du fichier du module. D'après l'exemple ci-dessus, notre objectif est de charger le code du fichier du module sous la forme d'une chaîne

Dans le conteneur Node, tous les fichiers du module sont locaux. pour lire le fichier de module à partir du disque local pour charger le code de chaîne, puis suivez les étapes ci-dessus. Le processus se déroule bien. Les faits ont prouvé que la méthode de chargement et d'exécution des modules non intégrés, de base et C++ de Node est à peu près la même (bien qu'il ne s'agisse pas d'une nouvelle fonction, c'est une méthode similaire)

Dans le RN/ Conteneur Weex, vous devez charger un Pour bundle.js distant, vous pouvez demander un fichier js distant via les capacités natives, puis le lire dans un code de chaîne et le charger (selon cette logique, il semble que Node puisse lire un fichier distant js, bien que dans la plupart des cas nous n'aurons pas besoin de le faire la prochaine fois)

Dans l'environnement du navigateur, tous les modules Js doivent être lus à distance. Ce qui est embarrassant, c'est que, limité par les capacités fournies par. le navigateur, il ne peut pas être diffusé via ajax sous forme de fichiers. Lisez le fichier js distant directement dans le code de chaîne. Si les conditions préalables ne peuvent pas être remplies, la stratégie opérationnelle ci-dessus ne fonctionnera pas et nous ne pouvons trouver qu'un autre moyen

C'est pourquoi il existe une spécification CommonJs, et pourquoi il existe également une spécification AMD/CMD

Alors Comment faire sur le navigateur ? Pour charger dynamiquement un fichier de module Js distant via le contrôle Js dans le navigateur, vous devez insérer dynamiquement un nœud