Maison > interface Web > js tutoriel > le corps du texte

Explication détaillée des spécifications du module en JS (CommonJS, AMD, CMD)

php是最好的语言
Libérer: 2018-08-07 09:21:44
original
1905 Les gens l'ont consulté

Répondez-moi d'abord : Pourquoi les modules sont-ils importants ?

Réponse : Grâce aux modules, nous pouvons utiliser le code d'autres personnes plus facilement et charger les modules que nous voulons pour les fonctions que nous voulons.
Cependant, il y a un prérequis pour cela, c'est-à-dire que tout le monde doit écrire le module de la même manière, sinon vous avez votre façon d'écrire, et j'ai ma façon d'écrire, ne le feriez-vous pas c'est le bordel !

Les trois modules suivants ont donc été standardisés, et cet article a également été publié (énoncé {couverture du visage et rire}).

Spécification du module en JS (CommonJS, AMD, CMD), si vous avez entendu parler de la modularisation js, alors vous devriez en avoir entendu parler ou CommonJS ou AMD ou même moi. entendu parler de ces réglementations CMD, mais avant, je me contentais de les écouter. Voyons maintenant ce que sont ces spécifications et ce qu’elles font. Cet article reprend les sources de ces trois spécifications et les principes de leurs produits correspondants.

1. CommonJS

1 Au début, tout le monde pensait que JS était une fille sexy. , c'est inutile. L'API officiellement définie ne peut créer que des applications basées sur un navigateur. Vous vous moquez de moi, c'est trop étroit (un mot haut de gamme est utilisé, charlatan n'en peut plus). les API courantes utilisées par les applications (principalement les applications autres que les navigateurs) comblent cette lacune. Son objectif ultime est de fournir une bibliothèque standard similaire à Python, Ruby et Java. Dans ce cas, les développeurs peuvent utiliser l'API CommonJS pour écrire des applications, puis ces applications peuvent s'exécuter dans différents interpréteurs JavaScript et différents environnements hôtes.

Dans les systèmes compatibles avec CommonJS, vous pouvez utiliser JavaScript pour développer les programmes suivants :

Application JavaScript côté serveur<.>

(2). Outil de ligne de commande
(3) Application d'interface graphique
(4). Titanium ou Adobe AIR)
En 2009, le programmeur américain Ryan Dahl a créé le projet node.js pour utiliser le langage javascript pour la programmation côté serveur. Cela marque la naissance officielle de la « programmation modulaire Javascript ». Parce que pour être honnête, dans un environnement de navigateur, ne pas avoir de modules n'est pas un gros problème. Après tout, la complexité des programmes Web est limitée, mais côté serveur, il doit y avoir des modules pour interagir avec le système d'exploitation et les autres applications. sinon il n'y a aucun moyen de programmer. NodeJS est une implémentation de la spécification CommonJS, et webpack est également écrit sous la forme de CommonJS.

Le système de modules de node.js est implémenté en référence à la spécification CommonJS. Dans CommonJS, il existe une méthode globale require() pour charger les modules. En supposant qu'il existe un module mathématique math.js, il peut être chargé comme suit.

var math = require('math');

Ensuite, vous pouvez appeler la méthode fournie par le module :

var math = require('math');

math.add(2,3); 5

Les modules définis par CommonJS sont divisés en : {référence du module (require)} {définition du module (exports)} {identification du module (module)}

require() est utilisé pour introduire des modules externes ; l'objet exports est utilisé pour exporter des méthodes ou des variables du module actuel, le seul port d'export l'objet module représente le module lui-même.

Bien que Node suive les spécifications de CommonJS, il a fait quelques compromis et ajouté de nouvelles choses.

Cependant, après avoir parlé de CommonJS et également de Node, je pense que nous devons d'abord comprendre NPM. En tant que gestionnaire de packages de Node, NPM n'est pas destiné à aider Node à résoudre le problème d'installation des packages dépendants. Il doit également suivre la spécification CommonJS. Il suit la spécification (ou la théorie) du package. CommonJS WIKI parle de son histoire et présente également des modules, des packages, etc.

Parlons du principe et de la mise en œuvre simple de commonJS :

1. Parcourir La raison fondamentale pour laquelle le serveur n'est pas compatible avec CommonJS est le manque de quatre variables d'environnement Node.js.

module
  • exportations
  • exiger
  • mondial
Tant que ces quatre variables sont fournies, le navigateur peut charger le module CommonJS.

Voici un exemple simple.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">var module <span class="token operator">= <span class="token punctuation">{<br> exports<span class="token punctuation">: <span class="token punctuation">{<span class="token punctuation">}<br><span class="token punctuation">}<span class="token punctuation">;<br><br><span class="token punctuation">(<span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">) <span class="token punctuation">{<br> exports<span class="token punctuation">.multiply <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(n<span class="token punctuation">) <span class="token punctuation">{ <span class="token keyword">return n <span class="token operator">* <span class="token number">1000 <span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">(module<span class="token punctuation">, module<span class="token punctuation">.exports<span class="token punctuation">)<span class="token punctuation">)<br><br><span class="token keyword">var f <span class="token operator">= module<span class="token punctuation">.exports<span class="token punctuation">.multiply<span class="token punctuation">;<br><span class="token function">f<span class="token punctuation">(<span class="token number">5<span class="token punctuation">)<span class="token comment"> // 5000 <br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Copier après la connexion
Le code ci-dessus fournit deux variables externes, module et exports, à une fonction d'exécution immédiate, et le module est placé ici pour une exécution immédiate à l’intérieur de la fonction. La valeur de sortie du module est placée dans module.exports, réalisant ainsi le chargement du module.

2. Implémentation de BrowserifySi vous connaissez le principe, vous pouvez faire outils . Browserify est actuellement l'outil de conversion de format CommonJS le plus couramment utilisé.

Veuillez voir un exemple où le module main.js charge le module foo.js.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><span class="token comment"><br>// foo.js<br>module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token comment"><br>// main.js<br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Copier après la connexion
Utilisez la commande suivante pour convertir main.js dans un format utilisable par le navigateur.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browserify main<span class="token punctuation">.js <span class="token operator">> compiled<span class="token punctuation">.js<br/></span></span></span></code></span>
Copier après la connexion
Que fait exactement Browserify ? Installez le décompresseur du navigateur et vous pourrez voir clairement.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ npm install browser<span class="token operator">-unpack <span class="token operator">-g<br/></span></span></code></span>
Copier après la connexion
Ensuite, décompressez le compile.js généré précédemment.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browser<span class="token operator">-unpack <span class="token operator">< compiled<span class="token punctuation">.js<br/><br/><span class="token punctuation">[<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"module.exports = function(x) {\n console.log(x);\n};"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token punctuation">}<br/><span class="token punctuation">}<span class="token punctuation">,<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">2<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"var foo = require(\"./foo\");\nfoo(\"Hi\");"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token string">"./foo"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">}<span class="token punctuation">,<br/><span class="token string">"entry"<span class="token punctuation">:<span class="token boolean">true<br/><span class="token punctuation">}<br/><span class="token punctuation">]<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span>
Copier après la connexion
Comme vous pouvez le voir,browerify place tous les modules dans un tableau, l'attribut id est le numéro du module et le L'attribut source est le code source du module, l'attribut deps est la dépendance du module.

Comme foo.js est chargé dans main.js, l'attribut deps précise ./foo correspondant au module n°1. Pendant l'exécution, lorsque le navigateur rencontre l'instruction require('./foo'), il exécute automatiquement l'attribut source du module n°1 et génère la valeur de l'attribut module.exports exécuté.

3. Petit navigateur requis

Bien que Browserify soit très puissant, il ne peut pas être utilisé dans le navigateur, ce qui est parfois très gênant.

J'ai créé un chargeur de module CommonJS pour navigateur pur tiny-browser-require basé sur l'implémentation interne de mocha. Il n'y a pas du tout besoin de ligne de commande, il suffit de la mettre directement dans le navigateur. Le code entier ne fait que plus de 30 lignes.

La logique est très simple, c'est-à-dire que le module est lu dans le tableau et que le chemin de chargement est l'identifiant du module.

<code class="language-javascript"><span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-javascript"><br/><span class="token keyword">function <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">var path <span class="token operator">= require<span class="token punctuation">.<span class="token function">resolve<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var mod <span class="token operator">= require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">]<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">) <span class="token keyword">throw <span class="token keyword">new <span class="token class-name">Error<span class="token punctuation">(<span class="token string">&#39;failed to require "&#39; <span class="token operator">+ p <span class="token operator">+ <span class="token string">&#39;"&#39;<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">.exports<span class="token punctuation">) <span class="token punctuation">{<br/> mod<span class="token punctuation">.exports <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br/> mod<span class="token punctuation">.<span class="token function">call<span class="token punctuation">(mod<span class="token punctuation">.exports<span class="token punctuation">, mod<span class="token punctuation">, mod<span class="token punctuation">.exports<span class="token punctuation">, require<span class="token punctuation">.<span class="token function">relative<span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<br/><span class="token keyword">return mod<span class="token punctuation">.exports<span class="token punctuation">;<br/><span class="token punctuation">}<br/><br/>require<span class="token punctuation">.modules <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.resolve <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">var orig <span class="token operator">= path<span class="token punctuation">;<br/><span class="token keyword">var reg <span class="token operator">= path <span class="token operator">+ <span class="token string">&#39;.js&#39;<span class="token punctuation">;<br/><span class="token keyword">var index <span class="token operator">= path <span class="token operator">+ <span class="token string">&#39;/index.js&#39;<span class="token punctuation">;<br/><span class="token keyword">return require<span class="token punctuation">.modules<span class="token punctuation">[reg<span class="token punctuation">] <span class="token operator">&& reg<br/><span class="token operator">|| require<span class="token punctuation">.modules<span class="token punctuation">[index<span class="token punctuation">] <span class="token operator">&& index<br/><span class="token operator">|| orig<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.register <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">, fn<span class="token punctuation">)<span class="token punctuation">{<br/> require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">] <span class="token operator">= fn<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.relative <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(parent<span class="token punctuation">) <span class="token punctuation">{<br/><span class="token keyword">return <span class="token keyword">function<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;.&#39; <span class="token operator">!<span class="token operator">= p<span class="token punctuation">.<span class="token function">charAt<span class="token punctuation">(<span class="token number">0<span class="token punctuation">)<span class="token punctuation">) <span class="token keyword">return <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var path <span class="token operator">= parent<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var segs <span class="token operator">= p<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">;<br/> path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br/><br/><span class="token keyword">for <span class="token punctuation">(<span class="token keyword">var i <span class="token operator">= <span class="token number">0<span class="token punctuation">; i <span class="token operator">< segs<span class="token punctuation">.length<span class="token punctuation">; i<span class="token operator">++<span class="token punctuation">) <span class="token punctuation">{<br/><span class="token keyword">var seg <span class="token operator">= segs<span class="token punctuation">[i<span class="token punctuation">]<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;..&#39; <span class="token operator">== seg<span class="token punctuation">) path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">else <span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;.&#39; <span class="token operator">!<span class="token operator">= seg<span class="token punctuation">) path<span class="token punctuation">.<span class="token function">push<span class="token punctuation">(seg<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<br/><br/><span class="token keyword">return <span class="token function">require<span class="token punctuation">(path<span class="token punctuation">.<span class="token function">join<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Copier après la connexion

使用的时候,先将上面的代码放入页面。然后,将模块放在如下的立即执行函数里面,就可以调用了。

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-html"><br/><script src="require.js" /><br/><br/><script><br/>require.register("moduleId", function(module, exports, require){<br/> // Module code goes here<br/>});<br/>var result = require("moduleId");<br/></script><br/></code></span>
Copier après la connexion

还是以前面的 main.js 加载 foo.js 为例。

<code class="language-javascript"><span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-javascript"><br/>require<span class="token punctuation">.<span class="token function">register<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">, <span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">, require<span class="token punctuation">)<span class="token punctuation">{<br/> module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br/> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;<br/><br/><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Copier après la connexion

注意,这个库只模拟了 require 、module 、exports 三个变量,如果模块还用到了 global 或者其他 Node 专有变量(比如 process),就通过立即执行函数提供即可。

二、AMD

基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上面的代码,如果在浏览器中运行,会有一个很大的问题,你能看出来吗?

  var math = require('math');

  math.add(2, 3);

第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到 require 是同步的。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

  require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:

  require(['math'], function (math) {

    math.add(2, 3);

  });

math.add() et le chargement du module mathématique ne sont pas synchronisés et le navigateur ne se fige pas. Alors évidemment, AMD est plus adapté à l’environnement navigateur. Actuellement, il existe deux bibliothèques Javascript principales qui implémentent la spécification AMD : require.js et curl.js.

RequireJS implémente la spécification AMD.

Résumé détaillé : Ce qui suit utilise RequireJS comme exemple pour illustrer la spécification AMD

1. Pourquoi utiliser require .js ?

Au début, tous les codes Javascript étaient écrits dans un seul fichier, et il suffisait de charger ce seul fichier. Plus tard, il y a eu de plus en plus de codes, et un seul fichier ne suffisait plus. Il fallait le diviser en plusieurs fichiers et les charger séquentiellement. Je pense que beaucoup de gens ont vu le code de page Web suivant

 
 
 
 

Ce code charge plusieurs fichiers js en séquence.

Cette façon d'écrire présente de gros inconvénients. Tout d'abord, lors du chargement, le navigateur cessera de restituer la page Web. Plus il y a de fichiers chargés, plus la page Web perdra de réponse. Deuxièmement, en raison des dépendances entre les fichiers js, l'ordre de chargement doit être strictement garanti (tel que). comme dans l'exemple ci-dessus) 1.js doit être devant 2.js), et le module avec la plus grande dépendance doit être chargé en dernier. Lorsque les dépendances sont complexes, l'écriture et la maintenance du code deviendront difficiles.

require.js est né pour résoudre ces deux problèmes :

 

 (1) Implémenter le chargement asynchrone des fichiers js pour éviter que les pages Web ne perdent de réponse

 (2) Gestion entre modules Les dépendances facilitent l'écriture de code ; et l'entretien.

2. Chargement de require.js

Utiliser require.js La première étape consiste à se rendre sur le site officiel pour télécharger la dernière version.

Après le téléchargement, on suppose que vous le placez dans le sous-répertoire js et qu'il peut être chargé.

 

Certaines personnes peuvent penser que le chargement de ce fichier peut également entraîner une perte de réponse de la page Web. Il y a deux solutions, l'une est de le charger en bas de la page web, et l'autre est de l'écrire comme suit :

 < ;script src=" js/require.js" defer async="true" >

L'attribut async indique que ce fichier doit être chargé de manière asynchrone pour éviter que la page Web ne réponde. IE ne prend pas en charge cet attribut et ne prend en charge que defer, donc defer est également écrit.

Après avoir chargé require.js, l'étape suivante consiste à charger notre propre code. Supposons que notre propre fichier de code soit main.js et soit également placé dans le répertoire js. Ensuite, écrivez-le simplement comme suit :

 

Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!