Skip to content

common.js和es6中模块引入的区别?

Posted on:2024年8月18日 at 12:59

CommonJS 和 ES6 模块系统在语法和行为上有显著的区别:

CommonJS

CommonJS 是一种模块系统,主要用于 Node.js 环境。它使用 require 函数来引入模块,并使用 module.exports 来导出模块。

语法

// moduleA.js
const name = "John";
module.exports = name;

// 或者导出一个对象
const person = { name: "John", age: 30 };
module.exports = person;
// main.js
const name = require("./moduleA");
console.log(name); // 'John'

// 引入对象
const person = require("./moduleA");
console.log(person.name); // 'John'
console.log(person.age); // 30

特点

  1. 动态引入: require 可以在函数体内、条件语句中动态引入模块。

    if (condition) {
      const moduleA = require("./moduleA");
    }
    
  2. 同步加载: require 是同步的,模块在执行 require 时会立即加载并返回结果。

  3. 导出的是值的拷贝: 但对于对象和数组等引用类型,修改引用类型的属性会在所有引用中反映出来。

    const obj = require("./moduleA");
    obj.newProp = "new";
    console.log(require("./moduleA").newProp); // 'new'
    

ES6 模块

ES6 模块系统是 ECMAScript 标准的一部分,使用 importexport 语法来定义模块,广泛用于现代前端开发以及一些支持 ES6 的服务器环境。

语法

// moduleA.js
export const name = "John";

// 导出默认值
const person = { name: "John", age: 30 };
export default person;
// main.js
import { name } from "./moduleA";
console.log(name); // 'John'

// 引入默认导出
import person from "./moduleA";
console.log(person.name); // 'John'
console.log(person.age); // 30

特点

  1. 静态引入: import 必须在文件的顶部声明,不能在函数体内或条件语句中使用(注意,这里有个例外,动态import()是可以在函数或者条件语句中使用的,这也是我们通常code splitting所依赖的特性)。这使得 ES6 模块可以在编译时确定依赖关系和优化。

    // 错误的用法
    if (condition) {
      import { name } from "./moduleA";
    }
    
  2. 异步加载: 浏览器中的 ES6 模块是异步加载的,这意味着它们不会阻塞页面的其他加载过程。

  3. 导出的是值的引用: 导出值的引用意味着当导出模块中的值发生变化时,所有引用该值的地方都会反映出这些变化。

    // moduleA.js
    export let count = 1;
    setTimeout(() => {
      count += 1;
    }, 1000);
    
    // main.js
    import { count } from "./moduleA";
    setTimeout(() => {
      console.log(count);
    }, 2000); // 2
    

兼容性和转换

总结

选择使用哪种模块系统取决于项目需求和运行环境。对于现代前端开发,推荐使用 ES6 模块。对于 Node.js 项目,传统上使用 CommonJS,但也可以逐渐迁移到 ES6 模块。

原文转自:https://fe.ecool.fun/topic/b9a0ceb2-84b5-4a79-8548-d043a97d0096