js模块化之commonjs与es6模块化

js 模块化总结

定义与场景

模块化简介

把一个复杂的项目, 划分为多个模块. 模块与模块之间通过 (AMD/CMD/ES6模块化/commonjs)等规范为纽带进行关联. 从而实现可维护可复用 的多个文件组成的项目.

模块化的特点: 可复用,可组合,独立性,中心化

模块化的作用:

  1. 解决了命名冲突 -- 隔离了模块内的变量作用域;
  2. 提高可维护性 -- 功能的拆分,使每个模块坚持单一职责原则,更方便维护
  3. 性能优化 -- 异步加载模块,减少浏览器的瞬间加载压力

模块化方案

常见的模块化方案有:

  • CommonJs
  • AMD
  • CMD
  • UMD
  • ES6 模块化

CommonJs规范

内容参考 javascript.ruanyifeng.com/nodejs/modu...

来源: CommonJs 是以在浏览器之外的环境构建Javascript生态系统为目的而产生的项目,比如在服务器和桌面环境中。

这个项目最开始是 Mozilla 的工程师Kevin Dangoor 在2009年1月创建的,当时的名字是 ServerJS。Kevin Dangoor's What Server Side JavaScript needs 后来在2009年的8月更名为 CommonJs 。

CommonJs是一个规范,它的创建与核准是开放的。目前已经有了多种实现,通过依赖也支持构建在浏览器环境也可以使用的 CommonJs语法

使用场景

  • 服务器环境 ---> node
  • 浏览器环境 ---> Browserify
  • 项目编译打包 ---> webpack

CommonJs特点

  • 每个文件都是独立的,都有独立的 作用域。不会污染全局空间
  • 文件可被重复引用加载。首次加载是会缓存, 之后加载就直接读取缓存
  • 导入模块时 输出的模块是拷贝的。 一旦这个值被输出,模块内的变换不会影响已经输出的值

CommonJs 使用

CommonJs 每个模块(js文件)都默认存在 module.exports, exports, require 三个核心变量;
module.exports,exports, 代码负责对模块的内容进行到处
require 函数用于对其他模块的内容进行导入

  • module 记录当前模块信息。
  • require 引入模块的方法。
  • exports 当前模块导出的属性

导出 add.js

js 复制代码
function isNumber (val) {
  return typeOf (val) == "number"
}

function add (a, b) {
  if (isNumber(a) && isNumber(b)) {
    return a + b
  } else {
    throw new Errow('a and b must be a Number')
  }
}

// module.exports 也可以写为 exports 建议只是用module.exports, 不要两个都用。
module.exports.add = add

导入 index.js

js 复制代码
const { add } = require('./add.js')

console.log(add(1, 2))
commonJs是同步加载的 只有加载完成,才能执行后面的操作

require函数的加载过程: 先从缓存里找,有就加载 缓存没有就检查是不是全局模块,是就直接加载 不是就检查模块路径有没有该文件,有就解析路径并定位文件,然后执行加载 如果以上都不是,就沿当前路径向上层逐级递归查找,直到根目录 node_modules


AMD

内容参考 javascript.ruanyifeng.com/nodejs/modu...

来源: CommonJs 是以在浏览器之外的环境构建Javascript生态系统为目的而产生的项目,比如在服务器和桌面环境中。

这个项目最开始是 Mozilla 的工程师Kevin Dangoor 在2009年1月创建的,当时的名字是 ServerJS。Kevin Dangoor's What Server Side JavaScript needs 后来在2009年的8月更名为 CommonJs 。

CommonJs是一个规范,它的创建与核准是开放的。目前已经有了多种实现,通过依赖也支持构建在浏览器环境也可以使用的 CommonJs语法

使用场景

  • 服务器环境 ---> node
  • 浏览器环境 ---> Browserify
  • 项目编译打包 ---> webpack

CommonJs特点

  • 每个文件都是独立的,都有独立的 作用域。不会污染全局空间
  • 文件可被重复引用加载。首次加载是会缓存, 之后加载就直接读取缓存
  • 导入模块时 输出的模块是拷贝的。 一旦这个值被输出,模块内的变换不会影响已经输出的值

CommonJs 使用

CommonJs 每个模块(js文件)都默认存在 module.exports, exports, require 三个核心变量;
module.exports,exports, 代码负责对模块的内容进行到处
require 函数用于对其他模块的内容进行导入

  • module 记录当前模块信息。
  • require 引入模块的方法。
  • exports 当前模块导出的属性

导出 add.js

js 复制代码
function isNumber (val) {
  return typeOf (val) == "number"
}

function add (a, b) {
  if (isNumber(a) && isNumber(b)) {
    return a + b
  } else {
    throw new Errow('a and b must be a Number')
  }
}

// module.exports 也可以写为 exports 建议只是用module.exports, 不要两个都用。
module.exports.add = add

导入 index.js

js 复制代码
const { add } = require('./add.js')

console.log(add(1, 2))
commonJs是同步加载的 只有加载完成,才能执行后面的操作

require函数的加载过程: 先从缓存里找,有就加载 缓存没有就检查是不是全局模块,是就直接加载 不是就检查模块路径有没有该文件,有就解析路径并定位文件,然后执行加载 如果以上都不是,就沿当前路径向上层逐级递归查找,直到根目录 node_modules

commonJs最大的弊端就是同步加载。这在浏览器环境下是很可怕的。因为浏览器读取文件都是从服务器远程调用的 这无疑是对性能的极大消耗。但是不可否认commonjs 思想对与前端模块化开发 的影响与历史地位

Es6模块化

es6 模块化的优点 编译时加载

即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高

js 复制代码
// es6 模块化
import {a, b, c} from './utils.js'

// 直接从utils加载 a, b, c 三个属性。 不会加载模块的其他属性 即 (编译时加载)
js 复制代码
// common 模块化
const {a, b, c} = require('./utils.js')

// 加载模块的所有属性 生成一个对象 从对象中读取 a, b, c 三个属性

es6模块化 使用


导出 add.js

js 复制代码
// 单独导出
export function isNumber (val) {
  return typeOf (val) == "number"
}

export function add (a, b) {
  if (isNumber(a) && isNumber(b)) {
    return a + b
  } else {
    throw new Errow('a and b must be a Number')
  }
}

// 导出多个
export default var a = { add }

导入 index.js

js 复制代码
import { add } from './add.js'

console.log(add(1, 2))

异步导入

js 复制代码
import('./add.js').then(({add}) => {
  console.log(add(1, 2))
}).catch()

异步导入在webpack打包优化时的常见手段

ES6 Module 和 CommonJS 的区别:

  • ES6 Module 的 import 是静态引入,CommonJS的 require 是动态引入

  • Tree-Shaking 就是通过 ES6 Module 的 import 来进行静态分析,并且只支持 ES6 Module 模块的使用。 Tree-Shaking 就是移除掉 JS 上下文中没有引用的代码,比如 import 导入模块没有返回值的情况下,webpack 在打包编译时 Tree-Shaking 会默认忽略掉此文件 (webpack4 commonJs不可以; webpack5中已经对 commonJs提供支持)

  • ES6 Module 是对模块的引用,输出的是值的引用,改变原来模块中的值引用的值也会改变;CommonJS 是对模块的拷贝,修改原来模块的值不会影响引用的值

  • ES6 Module 里的 this 指向 undefined;CommonJS 里的 this 指向模块本身

  • ES6 Module 是在编译时确定依赖关系,生成接口并对外输出;CommonJS 是在运行时加载模块

  • ES6 Module 可以单独加载某个方法;CommonJS 是加载整个模块

  • ES6 Module 不能被重新赋值,会报错;CommonJS 可以重新赋值(改变 this 指向)

相关推荐
江城开朗的豌豆1 分钟前
Git分支管理:从'独狼开发'到'团队协作'的进化之路
前端·javascript·面试
GIS之家2 分钟前
vue+cesium示例:3D热力图(附源码下载)
前端·vue.js·3d·cesium·webgis·3d热力图
幽蓝计划3 分钟前
鸿蒙Next仓颉语言开发实战教程:下拉刷新和上拉加载更多
前端
红衣信4 分钟前
电影项目开发中的编程要点与用户体验优化
前端·javascript·github
LeeAt9 分钟前
npm:详细解释前端项目开发前奏!!
前端·node.js·html
山有木兮木有枝_11 分钟前
JavaScript对象深度解析:从创建到类型判断 (上)
前端
crary,记忆19 分钟前
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
前端·学习·webpack
清风~徐~来21 分钟前
【Qt】控件 QWidget
前端·数据库·qt
前端小白从0开始22 分钟前
关于前端常用的部分公共方法(二)
前端·vue.js·正则表达式·typescript·html5·公共方法
想用offer打牌22 分钟前
面试官拷打我线程池,我这样回答😗
java·后端·面试