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 指向)

相关推荐
Qrun7 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp7 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.8 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl10 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫11 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友11 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理13 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻13 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front14 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰14 小时前
纯flex布局来写瀑布流
前端·javascript·css