Commonjs
CommonJS 是一种使用广泛的 JavaScript 模块化规范,核心思想是通过 require 方法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接口。 CommonJS 规范的流行得益于 Node.js 采用了这种方式,后来这种方式被引入到了网页开发中。
//title.jsfunction show() {console.log('我是commonjs')}// 第一种导出方式module.exports = {show}// 第二种导出方式exports.show = show// index.jsconst title = require('./title.js')console.log(title.show())
CommonJS 的优点在于:
- 代码可复用于 Node.js 环境下并运行,例如做同构应用;
- 通过 NPM 发布的很多第三方模块都采用了 CommonJS 规范。
CommonJS 的缺点在于这样的代码无法直接运行在浏览器环境下,必须通过工具转换成标准的 ES5。
AMD
AMD 也是一种 JavaScript 模块化规范,与 CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs。
// 定义一个模块define('module', ['dep'], function(dep) {return exports;});// 导入和使用require(['module'], function(module) {});
AMD 的优点在于:
- 可在不转换代码的情况下直接在浏览器中运行;
- 可异步加载依赖;
- 可并行加载多个依赖;
- 代码可运行在浏览器环境和 Node.js 环境下。
AMD 的缺点在于JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。
Es6模块
ES6 模块化是 ECMA 提出的 JavaScript 模块化规范,它在语言的层面上实现了模块化。浏览器厂商和 Node.js 都宣布要原生支持该规范。它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
// 导入import { readFile } from 'fs';import React from 'react';// 命名导出export function hello() {};// 对于命名导出的模块需要用{}来接收import {hello} from './hello'// 默认导出export default {// ...};import test from './test'//命名导出的变量都是通过 {} 来接收的,那么去掉 {} ,接收的就是默认导出的变量了,因为导出的变量是匿名的,因此我们可以随意地起个变量名用于接收
ES6模块虽然是终极模块化方案,但它的缺点在于目前无法直接运行在大部分 JavaScript 运行环境下,必须通过工具转换成标准的 ES5 后才能正常运行。
Commonjs和es6模块的区别
对于模块的依赖,CommonJS是动态的,ES6 Module 是静态的
对于模块的依赖,何为动态?何为静态?
动态是指对于模块的依赖关系建立在代码执行阶段; 静态是指对于模块的依赖关系建立在代码编译阶段;
CommonJS导入时,require 的路径参数是支持表达式的,例如// A.js let fileName = 'example.js'const bModule = require('./' + fileName) 复制代码
因为该路径在代码执行时是可以动态改变的,所以如果在代码编译阶段就建立各个模块的依赖关系,那么一定是不准确的,只有在代码运行了以后,才可以真正确认模块的依赖关系,因此说CommonJS是动态的。
CommonJS导入的是值的拷贝,ES6 Module导入的是值的引用
