>  기사  >  웹 프론트엔드  >  CommonJs와 Es 모듈이 무엇인지에 대한 간략한 분석은 무엇입니까? 차이점은 무엇입니까?

CommonJs와 Es 모듈이 무엇인지에 대한 간략한 분석은 무엇입니까? 차이점은 무엇입니까?

青灯夜游
青灯夜游앞으로
2021-10-08 10:17:262794검색

CommonJ와 Es 모듈이 무엇인가요? 차이점은 무엇입니까? 다음 기사에서는 CommonJs와 Es 모듈이 무엇인지, 그리고 그 차이점에 대해 설명하겠습니다. 도움이 되기를 바랍니다.

CommonJs와 Es 모듈이 무엇인지에 대한 간략한 분석은 무엇입니까? 차이점은 무엇입니까?

CommonJs와 Es 모듈이 있는 이유

우리 모두는 초기에 JavaScript 모듈의 개념이 script 태그를 통해 도입되었다는 것을 알고 있습니다. .>js 파일 코드. 물론 이러한 기본적이고 간단한 요구사항을 작성하는 데에는 문제가 없지만, 프로젝트가 점점 커지면 도입하는 js 파일이 많아지고 다음과 같은 문제가 발생하게 됩니다. 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

直接导出

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

exports.name = "蛙人"
exports.sex = "male"

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

exports.name = "蛙人"
exports.sex = "male"
exports = {
    name: "蛙人"
}

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

混合导出

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

exports.name = "蛙人"
module.exports.age = 24

导入

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

// index.js
module.exports.name = "蛙人"
module.exports.age = 24

let data = require("./index.js")
console.log(data) // { name: "蛙人", age: 24 }

重复导入

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

let data = require("./index.js")
let data = require("./index.js") // 不会在执行了

动态导入

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

let lists = ["./index.js", "./config.js"]
lists.forEach((url) => require(url)) // 动态导入

if (lists.length) {
    require(lists[0]) // 动态导入
}

导入值的变化

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

上面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 }

混合导出

可以使用exportexport default

  • js 파일의 범위는 모두 최상위 수준이므로 다양한 오염이 발생할 수 있습니다.
  • js 파일이 너무 많아 유지 관리가 어렵습니다.
  • js 파일 종속성 문제, 약간의 부주의로 인해 오류가 발생할 수 있으므로 모든 코드는 오류를 보고합니다
위의 문제를 해결하기 위해 JavaScript 커뮤니티가 CommonJs 등장했습니다. CommonJs는 일종의 모듈화입니다. 현재 NodeJs를 포함한 사양도 CommonJs 구문의 일부를 사용합니다. 그런 다음 나중에 Es6 버전에 공식적으로 Es 모듈 모듈이 추가되었습니다. 두 가지 모두 위의 문제를 해결하므로 어떤 문제를 해결합니까?

  • 변수 오염 문제 해결, 각 파일은 독립적인 범위를 가지므로 변수 오염이 없습니다
  • 코드 유지 관리 문제 해결, 파일의 코드가 매우 명확합니다파일 종속성 문제를 해결하면 어떤 파일이 파일에 종속되어 있는지 명확하게 알 수 있습니다.
그럼 해당 구문과 단점을 하나씩 알아봅시다

CommonJs 기본 구문🎜🎜🎜🎜🎜Export🎜🎜🎜🎜CommonJsmodule.exports를 사용하여 변수와 함수를 내보냅니다. 모든 유형 값을 내보낼 수도 있습니다. 다음 사례를 참조하세요. 🎜
export const name = "蛙人"
export const age = 24

export default {
    fn() {},
    msg: "hello 蛙人"
}
🎜🎜직접 내보내기🎜🎜🎜내보내기에는 module 키워드를 생략하거나, 내보내기용으로 직접 쓸 수도 있습니다. 다음의 경우를 참고하세요. 🎜
// 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}
🎜참고: 단일 값을 내보내기 위해 내보내기를 사용하는 경우 개체 값을 내보낼 수 없습니다. 이는 내보내기의 개체 변경만 수정하지만 최종 내보내기는 여전히 이름과 성별입니다. , 최종 내보내기는 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: "蛙人" }
🎜위의 예에서 이 상황은 개체의 참조 값을 변경하고 내보내기가 무효화되므로 최종 내보내기는 여전히 name, sex입니다. 코드>. 🎜🎜🎜하이브리드 내보내기🎜🎜🎜하이브리드 내보내기, <code>exportsmodule.exports를 문제 없이 동시에 사용할 수 있습니다. 🎜
// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import { default as all,  name, age } from &#39;./index.js&#39;
console.log(all) // { msg: "蛙人" }
🎜🎜🎜Import🎜🎜🎜🎜CommonJsrequire 구문을 사용하여 가져올 수 있습니다. 단일 값을 원하는 경우 개체를 구조화하여 가져올 수 있습니다. 🎜
// 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 // 抛出错误
🎜🎜반복 가져오기🎜🎜🎜 CommonJsEs 모듈이든 상관없이 파일을 한 번만 로드하면 반복적으로 가져오지 않습니다. 다시 가져오면 적용되지 않습니다. 🎜
if (true) {
	import xxx from &#39;XXX&#39; // 报错
}
🎜🎜Dynamic import🎜🎜🎜CommonJs는 동적 가져오기를 지원한다는 것이 무엇을 의미하나요? 문에서 require 구문을 사용할 수 있습니다. 사례. 🎜rrreee🎜🎜가져온 값의 변경🎜🎜🎜CommonJs가져온 값이 ​​​​복사되므로 복사된 값은 수정이 가능하지만 이로 인해 다양한 오염이 발생하게 되며, 이름이 우연히 반복됩니다. 🎜rrreee🎜위 예시에서 exports로 내보낸 값이 ++num 값을 변경한 후에는 해당 값이 없다는 것을 알 수 있습니다. 변경하고 가져온 num 🎜🎜🎜🎜Summary🎜🎜🎜🎜CommonJs 값을 수정할 수도 있습니다. 이는 변수 오염, 파일 종속성 등과 같은 문제를 해결합니다. 위에서도 기본 구문을 소개했지만 동적 가져오기(코드는 런타임에 발생)가 가능하며 반복적으로 가져올 수 없습니다. 🎜

🎜Es 모듈 기본 구문🎜🎜🎜🎜🎜Export🎜🎜🎜🎜Es 모듈의 내보내기는 두 가지 유형으로 나누어지며, 단일 내보내기(export), 기본 내보내기(export default), 단일 내보내기는 가져올 때 CommonJs처럼 모든 값을 직접 가져오지 않으며, Es 모듈은 내가 원하는 값을 가져올 수 있습니다. 그런 다음 기본 내보내기는 모든 것을 직접 가져오는 것입니다. 물론 모든 유형의 값을 Es 모듈에서 내보낼 수도 있습니다. 🎜rrreee🎜🎜혼합 내보내기🎜🎜🎜서로 영향을 주지 않고 내보내기내보내기 기본값을 동시에 사용할 수 있습니다. 가져올 때만 주의하면 됩니다. 파일의 혼합 가져오기인 경우 먼저 기본 내보내기를 가져온 다음 가져온 단일 값을 가져와야 합니다. 🎜rrreee🎜🎜🎜가져오기🎜🎜🎜

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

// index,js
export const name = "蛙人"
export const age = 24

import { name, age } from &#39;./index.js&#39;
console.log(name, age) // "蛙人" 24

// 如果里面全是单个导出,我们就想全部直接导入则可以这样写
import * as all from &#39;./index.js&#39;
console.log(all) // {name: "蛙人", age: 24}

混合导入

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

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import msg, { name, age } from &#39;./index.js&#39;
console.log(msg) // { msg: "蛙人" }

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

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import { default as all,  name, age } from &#39;./index.js&#39;
console.log(all) // { msg: "蛙人" }

导入值的变化

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 // 抛出错误

Es Module是静态

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

if (true) {
	import xxx from &#39;XXX&#39; // 报错
}

总结

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

CommonJs和Es Module的区别

CommonJs

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

Es Module

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

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

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

感谢

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

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

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

作者:蛙人

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

위 내용은 CommonJs와 Es 모듈이 무엇인지에 대한 간략한 분석은 무엇입니까? 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제