首页 > 其他分享 >JS模块化——AMD、CommonJS和ESModules

JS模块化——AMD、CommonJS和ESModules

时间:2024-04-07 21:29:24浏览次数:23  
标签:CommonJS ESModules doSomething 导出 AMD js 模块 加载

文章目录

JS模块化——AMD、CommonJS和ESModules

前端模块化是指将前端代码拆解成互相独立的小块,每一块完成特定的功能,这些小块被称为模块。通过模块化,可以更好的组织管理代码,实现功能的服用。

方法介绍

传统方法:

在模块化概念出现之前,JS 的脚本通常是通过 script 标签直接嵌入 HTML 中的,但是不同 js 文件里申明的变量都会存在于全局作用域中。不同的开发者维护不同的 js 文件,很难保证不和其它 js 文件冲突。全局变量污染开始成为开发者的噩梦。

立即执行函数:

立即执行函数表达式(IIFE)是用来创建局部作用域,可以避免全局作用域污染。

(function() {
    // 这里的变量和函数都在局部作用域中
    var privateVar = 'I am private';
    function privateFunction() {
        console.log(privateVar);
    }

    // 对外暴露的接口
    window.myModule = {
        publicMethod: function() {
            privateFunction();
        }
    };
})();

异步模块定义AMD:

AMD是"Asynchronous Module Definition",意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
RequireJS是一个流行的实现AMD规范的库,以此为例子:

// 定义一个模块
define(['dependency'], function(dependency) {
    function doSomething() {
        // ...
    }

    return {
        doSomething: doSomething
    };
});

CommonJS:

CommonJS也是一种JS模块化规范,Node.js采用了这种方式。
Node.js 应用由模块组成,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
CommonJS 规范还规定,每个模块内部有两个变量可以使用,require 和 module。require 用来加载某个模块,module 代表当前模块,是一个对象,保存了当前模块的信息。exports 是 module 上的一个属性,保存了当前模块要导出的接口或者变量,使用 require 加载的某个模块获取到的值就是那个模块使用 exports 导出的值。

// 引入依赖
var dependency = require('dependency');

function doSomething() {
    // ...
}

// 导出模块接口
module.exports = {
    doSomething: doSomething
};

ES Modules:

ECMAScript 2015(ES6)引入了官方的JavaScript模块化标准,称为ES Modules (ESM)。
模块功能主要由两个命令构成:export 和 import。export 命令用于导出模块的对外接口,import 命令用于导入其他模块导出的内容。

// 导出
export function doSomething() {
    // ...
}

// 导入
import { doSomething } from './module.js';

特点:

  • 静态结构:ESM的设计是静态的,这意味着你不能根据条件动态地导入或导出模块。所有的导入和导出语句都必须位于模块的顶层,并且它们在代码的解析阶段就已经确定,这支持了编译时优化,如“摇树”优化(Tree Shaking),这种优化可以移除未使用的代码,从而减少最终打包文件的大小。
  • 实时绑定:ESM导出的是引用,而不是值的复制。这意味着,如果模块内导出的变量值发生了变化,导入该模块的其他模块也能实时获取到最新的值。
  • 异步加载:ESM支持原生的异步加载模块,使用import()语法可以实现动态导入,这对于按需加载代码、减少初始加载时间非常有用。

CommonJS 和 ES Modules 区别

最大的区别:动态和静态结构。
ES6 模块(ESM)是静态的,这意味着 import 和 export 语句必须出现在模块的顶层作用域,并且不能被包裹在任何结构如 if 语句或函数中。因为它们是静态的,所以模块的结构(依赖关系、导入和导出的变量)在代码的解析阶段就已经确定下来了。这使得工具像是打包器和静态分析工具可以在运行之前进行代码优化,诸如“摇树”(tree-shaking)来移除未使用的代码,更好地进行代码拆分等。
而 CommonJS 模块(如 Node.js 中使用)是动态的。require() 函数可以在模块的任何地方调用,甚至可以在运行时根据条件调用,这意味着你在运行时才能确定导出的接口。这种设计更加灵活,但它限制了静态分析的能力和优化潜力,同时也不支持异步加载,在浏览器端,这可能会导致性能问题,因为需要等待文件下载完成,才能继续执行后续代码。

设计的考虑:
ES6模块:目标是为JavaScript提供一种静态的模块系统,支持编译时优化和更好的静态分析。它的设计鼓励模块的前置声明,使得模块依赖更清晰,也便于各种工具进行分析和打包。
CommonJS:最初是为服务器环境设计的,考虑到服务器端模块的加载一般不会涉及到网络延迟,因此采用了同步加载的方式。它的设计允许更灵活的模块定义和导出方式,适合Node.js这样的环境。

标签:CommonJS,ESModules,doSomething,导出,AMD,js,模块,加载
From: https://blog.csdn.net/cherry__yu/article/details/137470063

相关文章

  • AMD_Ubuntu_Docker部署firefox
    AMD_Ubuntu_Docker部署firefox下载driverhttps://github.com/mozilla/geckodriver/releasesfirefox好像跟chrome不一样高版本的geckodriver可以兼容低版本的firefox所以理论上应该节约了很大的工作量.https://www.mozilla.org/zh-CN/firefox/linux/https://downl......
  • Ubuntu_amd64容器化部署chromedriver的过程
    Ubuntu_amd64容器化部署chromedriver的过程获取部分资料其他版本需要自己选择下载:https://chromedriver.com/download老版本:https://old.chromedriver.com/index.htmlhttps://www.chromedownloads.net/chrome64linux-stable/dockerpullubuntu:2404wgethttps://sto......
  • Amdroid Studio 下载及安装(保姆级)
    下载下载地址:官方下载地址https://developer.android.google.cn/studio/archive拉到最下面安装路径自己改官方下载地址配置SDK并下载等待下载完成  创建一个空白项目名字路径自己改,语言选Java  构建配置......
  • 银河麒麟高级服务器操作系统(AMD64版)V10 7
    银河麒麟高级服务器操作系统(AMD64版)V10部署发布.NETframeworkWebFroms项目下载ios镜像麒麟生态官网下载:https://eco.kylinos.cn/找到需要下载的镜像,注意版本,电脑是国产芯片的看一下对应的版本下载,AMD和Intel芯片下载AMD版的或者点击下面地址直接下载https://distro-imag......
  • [转帖]芯片相关-- Cpu历史--AMD系列
    芯片相关--Cpu历史--AMD系列https://zhuanlan.zhihu.com/p/477864185 1.1AMD1968年,仙童半导体的8位创始人中的两位——总经理罗伯特·诺伊斯(RobertNoyce)和实验室负责人戈登·摩尔(GordenMoore),带着一部分员工离开了陷入资金危机的公司,成立了英特尔(Intel)。而一......
  • AMD hipcc 生成各个gpu 微架构汇编语言代码的方法示例
    1,gpuvectorAdd示例为了简化逻辑,故假设vector的size与运行配置的thread个熟正好一样多,比如都是512之类的.1.1源码vectorAdd.hip#include<stdio.h>#include<hip/hip_runtime.h>__global__voidvectorAdd(constfloat*A,constfloat*B,float*C){inti=......
  • AMD、request.js,生词太多,傻傻搞不清
    前言之前在公司用JS写前端页面,本来自己是一个写后端的,但是奈何人少,只能自己也去写了。但是自己对前端基本不懂,基本就是照着前人写的照着抄,反正大体意思是明白的,但是出现问题了,基本上也是吭哧吭哧好几天,也能解决,但是由于自己对前端这一套是一点都不懂,导致效率很低,而且经常返工。后......
  • Qt信号 lamda 表达式使用
    对于Qt信号的绑定,有几种方式:1.标准的SIGNAL和SLOT的绑定方式; 例如:connect(qApp,SIGNAL(focusChanged(QWidget*,QWidget*)),this,SLOT(focusChanged(QWidget*,QWidget*)));//qApp为发送者,this类为接收者;focusChanged为发送者发送的信号,fo......
  • nodejs 实现 AMD 加载 依赖
    importfsfrom"fs";importpathfrom"path";importvmfrom"vm";exportclassLoadComponent{componentsPath:string=path.resolve("../first/components/");componentName:string="";componentIn......
  • AMD Zen5越来越近了!Linux GCC编译器已支持
    AMD预计会在今年年中左右开始推出下一代Zen5CPU架构产品,首先从移动端开始,然后是桌面端、服务器端,相关支持也正在紧锣密鼓地进行中,尤其是Linux系统下。现在,AMD已经将Zen5微架构加入到了GCC编译器的支持,GCCGit仓库的target设定值为“znver5”,可以赶上GCC4.1稳定版的发布。目前......