likes
comments
collection
share

commonjs & ES module 模块化

作者站长头像
站长
· 阅读数 28

浅聊一下

记得刚入前端那会,总听大家说 commonjs ES module 模块化开发,但一直没明白他们之间到底有个什么羁绊,nodejs的模块化规范包括 commonjs规范 和 ES module规范,借着对 node.js 学习的开始,来聊一聊commonjs ES module...

在金三银四的尾巴上了车,如果你也和我一样也想在大三找一份还不错的实习,欢迎掘友们私聊我交流面经(wechat: LongLBond

commonjs

使用commonjs规范

第一步我们需要明白如何使用commonjs规范,首先使用npm init初始化我们的项目,初始完毕以后,在我们的目录中会多出一个package.json文件,添加一个type,type的值可以修改为commonjs module分别对应commonjs规范ES module规范

npm init

commonjs & ES module 模块化

commonjs引入和导出模块

  1. 导出模块

我们要想文件中引入其他文件中的方法或属性,就得先在其他的文件中将方法和属性导出,那么在文件中如何来导出方法和属性?

// 导出对象
module.exports = {
   success:1,
   error:0,
   fn: {}
}
// 导出值
module.exports = 12345
  1. 引入模块
  • 引入自己编写的模块

刚才我们在文件中已经使用了module.exports来抛出一个模块,那么我们如何引入?

const obj = require('./test.js')
console.log(obj);

看看结果

commonjs & ES module 模块化

  • 引入第三方模块

在开发过程中我们时常需要引入一些第三方的模块

const md5 = require('md5')
  • 引入nodejs内置模块 fs http net os child_process
const fs = require('node:fs') // 高版本nodejs node:fs 低版本 fs
  • 引入C++扩展 addon napi node-gyp .node
  • 引入json文件
const data = require('./data.json')

ES module

  1. 导出模块

可以选择以下方式导出模块

// 导出变量
export const name = 'bd'
// 导出对象
export default {
    success:1,
    error:0,
    fn: {}
}
  1. 导入模块
import obj from './test.js'

需要注意的是,ES module 规范不支持引入json文件。但是如果非要引入json文件也不是不可以,需要使用断言的方式引入

import data from './data.json' assert { type: "json" }; 

如果你不知道这个文件中抛出了什么方法或者属性,或者你想引入文件中的所有属性和方法,可以使用以下方式来引入

import * as all from './test.js'
console.log(all)

commonjs & ES module 模块化

commonjs 和 ES module 的区别

  1. commonjs是基于运行时的同步加载而ES module是基于编译时的异步加载

什么意思?commonjs模块是在运行时同步加载的,这说明当node.js执行到require语句时,会同步地加载并执行相应的模块代码,如下例子,当运行到第三行时,同步加载并执行require导入的代码块,并且此时,reqiure会阻塞后面的代码

const a = 1
cpnsole.log(a);
const b = require('./test.js')
console.log(b)

ES module的加载是异步的,这意味着它不会阻塞主线程的执行。当遇到import语句时,浏览器会并行地开始加载所需的模块,而不会等待模块完全加载完成再继续执行后续代码。import只能在模块的顶层使用

这导致commonjs可以动态导入模块,而ES module 不可以

// 运行成功
if (true) {
    const obj = require('./test.js')
}
// 报错
if (true) {
    import obj from './test.js'
}

commonjs & ES module 模块化

其实ESM还是有办法动态导入的,使用import()

if (true) {
    import('./test.js').then(res=>{
        console.log(res);
    })
}

commonjs & ES module 模块化 2. commonjs导入的值是可以可改的,ES module导入的值不可修改

先来看看commonjs

const obj = require('./test2.js')

console.log(obj);

obj.success = 2
obj.fn = function(a,b){
    return a+b;
}
console.log(obj);

commonjs & ES module 模块化

再看ES moudle

import obj,{name} from './test.js'

console.log(obj,name);

obj = {
    a:123
}
// 修改obj的属性是允许的
// obj.success = 2
// obj.fn = function(a,b){
//     return a+b;
// }
name = 'abc'
console.log(obj,name);

commonjs & ES module 模块化

但是修改obj的属性是允许的

commonjs & ES module 模块化

  1. commonjs中顶层的this指向这个模块本身,而ES6中顶层this指向undefined

结尾

commonjs和ES module的区别在面试中也经常被问到,希望到时候大家不会犯迷糊~

转载自:https://juejin.cn/post/7386494006224224283
评论
请登录