MST
星途 面试题库

面试题:JavaScript模块化开发中,ES6模块与CommonJS模块的差异及应用场景

在JavaScript模块化开发里,ES6模块和CommonJS模块是常见的两种规范。请分析它们在语法、加载机制、作用域等方面的差异,并举例说明在何种应用场景下更适合使用ES6模块,何种场景下更适合使用CommonJS模块。
11.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

语法差异

  • ES6模块:使用importexport关键字。例如:
// 导出
export const name = 'John';
export function greet() {
  console.log('Hello');
}

// 导入
import { name, greet } from './module.js';
  • CommonJS模块:使用exportsmodule.exports导出,require导入。例如:
// 导出
const name = 'John';
function greet() {
  console.log('Hello');
}
exports.name = name;
exports.greet = greet;

// 或者
module.exports = {
  name,
  greet
};

// 导入
const { name, greet } = require('./module.js');

加载机制差异

  • ES6模块:是编译时加载(静态加载),即在代码编译阶段就确定模块的依赖关系和导入导出的变量,编译时就可以分析出模块的依赖关系,能进行静态优化,且只在首次加载时执行模块代码,之后再次导入使用缓存。例如:
// moduleA.js
export const value = 1;
// main.js
import { value } from './moduleA.js';
console.log(value); 
  • CommonJS模块:是运行时加载(动态加载),在运行到require语句时才会去加载模块并执行模块代码,每次require都会执行模块代码并返回导出的值。例如:
// moduleA.js
let value = 1;
exports.getValue = function() {
  return value;
};
// main.js
const { getValue } = require('./moduleA.js');
console.log(getValue()); 

作用域差异

  • ES6模块:每个模块都有自己独立的作用域,模块顶级的变量、函数等不会污染全局作用域。例如:
// module.js
let count = 0;
export function increment() {
  count++;
  return count;
}
// main.js
import { increment } from './module.js';
console.log(increment()); 
// count变量不会暴露到其他模块作用域
  • CommonJS模块:同样每个模块有独立作用域,exportsrequiremodule等在模块作用域内有效,不会污染全局。例如:
// module.js
let count = 0;
exports.increment = function() {
  count++;
  return count;
};
// main.js
const { increment } = require('./module.js');
console.log(increment()); 
// count变量不会暴露到其他模块作用域

应用场景

  • 适合ES6模块的场景
    • 浏览器端应用:现代浏览器原生支持ES6模块,如构建单页应用(SPA)时,使用ES6模块能利用其静态加载的优势进行优化,提升性能。例如使用Vue、React等框架开发前端应用时,可直接使用ES6模块进行代码拆分和组织。
    • 追求代码静态分析和优化的场景:如在打包工具(Webpack等)中,ES6模块的静态特性便于进行摇树优化(Tree - shaking),去除未使用的代码,减小打包体积。
  • 适合CommonJS模块的场景
    • Node.js服务器端应用:Node.js从一开始就采用CommonJS规范,在Node.js环境中使用CommonJS模块非常自然和方便,如开发Node.js的后端服务、命令行工具等。例如Express框架的中间件开发,大量使用CommonJS模块来组织代码。
    • 动态加载场景:如果需要根据运行时条件动态加载模块,CommonJS的运行时加载机制更合适。例如根据不同的用户权限动态加载不同的模块。