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

Une brève analyse de ce que sont CommonJs et Es Module ? Quelle est la différence ?

青灯夜游
Libérer: 2021-10-08 18:50:21
avant
2709 Les gens l'ont consulté

Que sont CommonJs et Es Module ? Quelle est la différence ? L'article suivant vous expliquera ce que sont CommonJs et Es Module et leurs différences. J'espère qu'il vous sera utile !

Une brève analyse de ce que sont CommonJs et Es Module ? Quelle est la différence ?

Pourquoi existe-t-il des modules CommonJs et Es

Nous savons tous qu'au début, le concept de moduleJavaScripta été introduit via la balisescript. >js code du fichier. Bien sûr, il n'y a rien de mal à écrire ces exigences simples de base, mais lorsque nos projets deviennent de plus en plus grands, plus nous introduisons de fichiersjs, et les problèmes suivants surgiront :JavaScript模块这一概念,都是通过script标签引入js文件代码。当然这写基本简单需求没有什么问题,但当我们的项目越来越庞大时,我们引入的js文件就会越多,这时就会出现以下问题:

  • js文件作用域都是顶层,这会造成变量污染
  • js文件多,变得不好维护
  • js文件依赖问题,稍微不注意顺序引入错,代码全报错

为了解决以上问题JavaScript社区出现了CommonJsCommonJs是一种模块化的规范,包括现在的NodeJs里面也采用了部分CommonJs语法在里面。那么在后来Es6版本正式加入了Es Module模块,这两种都是解决上面问题,那么都是解决什么问题呢。

  • 解决变量污染问题,每个文件都是独立的作用域,所以不存在变量污染
  • 解决代码维护问题,一个文件里代码非常清晰
  • 解决文件依赖问题,一个文件里可以清楚的看到依赖了那些其它文件

那么我们下面来一一了解它们的语法及弊端吧

CommonJs 基本语法

导出

CommonJs中使用module.exports导出变量及函数,也可以导出任意类型的值,看如下案例。

// 导出一个对象 module.exports = { name: "蛙人", age: 24, sex: "male" } // 导出任意值 module.exports.name = "蛙人" module.exports.sex = null module.exports.age = undefined
Copier après la connexion

直接导出

导出也可以省略module关键字,直接写exports导出也可以,看如下案例。

exports.name = "蛙人" exports.sex = "male"
Copier après la connexion

注意:如果使用exports导出单个值之后,就不能在导出一个对象值,这只会修改exports的对象改变,然而修改无效,最终导出还是name,和sex,因为最终的导出是由module.exports决定的。

exports.name = "蛙人" exports.sex = "male" exports = { name: "蛙人" }
Copier après la connexion

上面example中,这种情况会改变对象的引用值则导出无效,所以最后导出的还是namesex

混合导出

混合导出,exportsmodule.exports可以同时使用,不会存在问题。

exports.name = "蛙人" module.exports.age = 24
Copier après la connexion

导入

CommonJs中使用require语法可以导入,如果想要单个的值,可以通过解构对象来获取。

// index.js module.exports.name = "蛙人" module.exports.age = 24 let data = require("./index.js") console.log(data) // { name: "蛙人", age: 24 }
Copier après la connexion

重复导入

不管是CommonJs还是Es Module都不会重复导入,就是只要该文件内加载过一次这个文件了,我再次导入一次是不会生效的。

let data = require("./index.js") let data = require("./index.js") // 不会在执行了
Copier après la connexion

动态导入

CommonJs支持动态导入,什么意思呢,就是可以在语句中,使用require语法,来看如下案例。

let lists = ["./index.js", "./config.js"] lists.forEach((url) => require(url)) // 动态导入 if (lists.length) { require(lists[0]) // 动态导入 }
Copier après la connexion

导入值的变化

CommonJs导入的值是拷贝的,所以可以修改拷贝值,但这会引起变量污染,一不小心就重名。

// index.js let num = 0; module.exports = { num, add() { ++ num } } let { num, add } = require("./index.js") console.log(num) // 0 add() console.log(num) // 0 num = 10
Copier après la connexion

上面example中,可以看到exports导出的值是值的拷贝,更改完++ num值没有发生变化,并且导入的num的值我们也可以进行修改

总结

CommonJs解决了变量污染,文件依赖等问题,上面我们也介绍了它的基本语法,它可以动态导入(代码发生在运行时),不可以重复导入。

Es Module 基本语法

导出

Es Module中导出分为两种,单个导出(export)、默认导出(export default),单个导出在导入时不像CommonJs一样直接把值全部导入进来了,Es Module中可以导入我想要的值。那么默认导出就是全部直接导入进来,当然Es Module中也可以导出任意类型的值。

// 导出变量 export const name = "蛙人" export const age = 24 // 导出函数也可以 export function fn() {} export const test = () => {} // 如果有多个的话 const name = "蛙人" const sex = "male" export { name, sex }
Copier après la connexion

混合导出

可以使用exportexport default

  • La portée des fichiers js est de premier niveau, ce qui entraînera une pollution variable.
  • Il y a trop de fichiers js, ce qui rend la maintenance difficile.
  • Le problème de la dépendance des fichiers js, un peu de négligence peut introduire des erreurs, tous les codes signalent des erreurs

Afin de résoudre les problèmes ci-dessus, la communauté JavaScriptest apparue CommonJs, CommonJsest une sorte de modularisation. Les spécifications, y compris l'actuel NodeJs, utilisent également une partie de la syntaxe CommonJs. Puis plus tard, la version Es6a officiellement ajouté le module Es Module. Ces deux éléments résolvent les problèmes ci-dessus, alors quels problèmes résolvent-ils.

  • Résoudre le problème de la pollution variable, chaque fichier a une portée indépendante, donc il n'y a pas de pollution variable
  • Résoudre le problème de la maintenance du code, le code dans un fichier est très clair< /li>< li>En résolvant le problème de dépendance de fichier, vous pouvez voir clairement quels autres fichiers dépendent d'un fichier
Apprenons ensuite leur syntaxe et leurs inconvénients un par un

Syntaxe de base de CommonJsExportCommonJsutilisemodule.exportspour exporter des variables et des fonctions, et vous peut également exporter n’importe quel type de valeur, voir le cas suivant.
export const name = "蛙人" export const age = 24 export default { fn() {}, msg: "hello 蛙人" }
Copier après la connexion
Exportation directeVous pouvez également omettre le mot-clémodulepour l'exportation, ou vous pouvez écrire directement des exportations à exporter. Voir le cas suivant.
// index,js export const name = "蛙人" export const age = 24 import { name, age } from './index.js' console.log(name, age) // "蛙人" 24 // 如果里面全是单个导出,我们就想全部直接导入则可以这样写 import * as all from './index.js' console.log(all) // {name: "蛙人", age: 24}
Copier après la connexion
Copier après la connexion
Remarque : Si vous utilisez les exportations pour exporter une seule valeur, vous ne pouvez pas exporter une valeur d'objet. Cela modifiera uniquement le changement d'objet des exportations. Cependant, la modification finale est toujours le nom et le sexe. , car l'exportation finale est déterminée par module.exports.
// index,js export const name = "蛙人" export const age = 24 export default { msg: "蛙人" } import msg, { name, age } from './index.js' console.log(msg) // { msg: "蛙人" }
Copier après la connexion
Copier après la connexion
Dans l'exemple ci-dessus, cette situation changera la valeur de référence de l'objet et l'exportation sera invalide, donc l'exportation finale est toujoursnom,sexe. Export hybrideL'export hybride, exportsetmodule.exportspeuvent être utilisés en même temps sans problème.
// index,js export const name = "蛙人" export const age = 24 export default { msg: "蛙人" } import { default as all, name, age } from './index.js' console.log(all) // { msg: "蛙人" }
Copier après la connexion
Copier après la connexion
ImportCommonJspeut être importé en utilisant la syntaxerequireSi vous souhaitez une valeur unique, vous pouvez l'obtenir en déstructurant l'objet.
// index.js export let num = 0; export function add() { ++ num } import { num, add } from "./index.js" console.log(num) // 0 add() console.log(num) // 1 num = 10 // 抛出错误
Copier après la connexion
Copier après la connexion
Importation répétéePeu importe qu'il s'agisse deCommonJsou deEs Module, il ne sera pas importé à plusieurs reprises Tant que le fichier a été chargé une fois, je. l'importera à nouveau. Cela ne prendra pas effet une seule fois.
if (true) { import xxx from 'XXX' // 报错 }
Copier après la connexion
Copier après la connexion
L'importation dynamiqueCommonJsprend en charge l'importation dynamique. Qu'est-ce que cela signifie ? Vous pouvez utiliser la syntaxerequiredans une instruction. cas. rrreeeChangements dans les valeurs importéesCommonJsLes valeurs importéessont copiées, donc les valeurs copiéespeuvent être modifiées, mais cela provoquera une pollution variable, et le le nom sera répété accidentellement. rrreeeDans l'exemple ci-dessus, vous pouvez voir que la valeur exportée parexportsest une copie de la valeur. Après avoir modifié la valeur++ num, il n'y a aucun changement. , et lenum importé Nous pouvons également modifier la valeur deSummaryCommonJsrésout des problèmes tels que la pollution variable, la dépendance aux fichiers, etc. Nous avons également a présenté sa syntaxe de base ci-dessus, il peut être importé dynamiquement (le code se produit au moment de l'exécution) et ne peut pas être importé à plusieurs reprises.

Syntaxe de base du module EsExportL'exportation dansEs Moduleest divisée en deux types, une exportation unique (export), export par défaut (export default), un seul export n'importe pas toutes les valeurs directement commeCommonJslors de l'import,Es Le modulepeut importer la valeur que je veux. Ensuite, l'export par défaut consiste à tout importer directement. Bien entendu, tout type de valeur peut également être exporté depuisEs Module. rrreeeExportation mixteVous pouvez utiliserexportetexport defaulten même temps sans vous affecter mutuellement. Vous devez seulement faire attention lors de l'importation, le cas échéant. est une importation mixte dans le fichier, vous devez d'abord importer l'exportation par défaut, puis importer la valeur importée unique. rrreeeImporter

Es Module使用的是import语法进行导入。如果要单个导入则必须使用花括号{}注意:这里的花括号跟解构不一样

// index,js export const name = "蛙人" export const age = 24 import { name, age } from './index.js' console.log(name, age) // "蛙人" 24 // 如果里面全是单个导出,我们就想全部直接导入则可以这样写 import * as all from './index.js' console.log(all) // {name: "蛙人", age: 24}
Copier après la connexion
Copier après la connexion

混合导入

混合导入,则该文件内用到混合导入,import语句必须先是默认导出,后面再是单个导出,顺序一定要正确否则报错。

// index,js export const name = "蛙人" export const age = 24 export default { msg: "蛙人" } import msg, { name, age } from './index.js' console.log(msg) // { msg: "蛙人" }
Copier après la connexion
Copier après la connexion

上面example中,如果导入的名称不想跟原本地名称一样,则可以起别名。

// index,js export const name = "蛙人" export const age = 24 export default { msg: "蛙人" } import { default as all, name, age } from './index.js' console.log(all) // { msg: "蛙人" }
Copier après la connexion
Copier après la connexion

导入值的变化

export导出的值是值的引用,并且内部有映射关系,这是export关键字的作用。而且导入的值,不能进行修改也就是只读状态。

// index.js export let num = 0; export function add() { ++ num } import { num, add } from "./index.js" console.log(num) // 0 add() console.log(num) // 1 num = 10 // 抛出错误
Copier après la connexion
Copier après la connexion

Es Module是静态

就是Es Module语句``import只能声明在该文件的最顶部,不能动态加载语句,Es Module`语句运行在代码编译时。

if (true) { import xxx from 'XXX' // 报错 }
Copier après la connexion
Copier après la connexion

总结

Es Module也是解决了变量污染问题,依赖顺序问题,Es Module语法也是更加灵活,导出值也都是导出的引用,导出变量是可读状态,这加强了代码可读性。

CommonJs和Es Module的区别

CommonJs

  • CommonJs可以动态加载语句,代码发生在运行时
  • CommonJs混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
  • CommonJs导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染

Es Module

  • Es Module是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时

  • Es Module混合导出,单个导出,默认导出,完全互不影响

  • Es Module导出是引用值之前都存在映射关系,并且值都是可读的,不能修改

感谢

谢谢各位在百忙之中点开这篇文章,希望对你们能有所帮助,如有问题欢迎各位大佬指正。

我是蛙人,如果觉得写得可以的话,请点个赞吧。

原文地址:https://juejin.cn/post/6938581764432461854

作者:蛙人

更多编程相关知识,请访问:编程视频!!

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!

Étiquettes associées:
source:juejin.cn
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
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!