js 理解模块化

请叫我海龟先生 等级 413 0 0

经常在面试或者其他文章看到关于模块化的问题,之前也只是寥寥看了几次,对于 CommonJSAMDES6也说不出个所以然,于是今天抽空好好看了 红宝书第4版关于模块化的介绍,这里记录一下。

理解模块模式

初衷

在开发中肯定有设计大量三方库或者业务逻辑代码,较好的方式是将其分割为多个小模块,最后以一定的方式连接起来使用,这就是模块化兴起的初衷。

模块化一般包含什么?

模块化通常需要含一下几个点。

模块标识符

模块系统本质上是键/值实体,每个模块都有引用它的标志符,一般是路径或者文件名,部分模块系统也支持自定义标识符,这取决于哪种模块系统。

模块依赖

模块系统的核心就是是管理依赖了,脑海中大概有一张 A→B→C,这样的图就可以明白了。

模块加载

根据依赖,加载模块,在浏览器中只有整个依赖图都加载完成,才可以执行入口模块。

入口

这个就比较好理解了,相互依赖的模块必须指定一个模块作为入口(entry point),这也是代码执行的起点。

异步依赖

因为 JavaScript 可以异步执行,所以如果能按需加载就好了。换句话说,可以让 JavaScript 通知模块系统在必要时加载新模块,并在模块加载完成后提供回调。

// 在模块 A 里面
load('moduleB').then(function(moduleB) {
 moduleB.doStuff();
});
动态依赖

可以在程序结构中动态引入模块

if (loadCondition) {
 require('./moduleA');
} 
静态分析

模块中包含的发送到浏览器的 JavaScript 代码经常会被静态分析,分析工具会检查代码结构并在不实际执行代码的情况下推断其行为。

循环依赖

CommonJS、AMD 和ES6 在内的所有模块系统都支持循环依赖。

上面几点就是模块化的一些基本知识,接下来就看下我们比较关心的也面试偶尔问道的 CommonJSAMDES6

CommonJS

CommonJS 规范主要概述了同步声明依赖的模块定义,一般用于服务端规范,比如node.js(Node.js使用了轻微修改版本的 CommonJS,因为 Node.js 主要在服务器环境下使用,所以不需要考虑网络延迟问题。),CommonJS模块语法是不能直接在浏览器中使用的

使用方法

var moduleB = require('./moduleB');
module.exports = {
 stuff: moduleB.doStuff();
}; 
/**
  一般使用 require 和 module.exports的方式
  可以赋值给变量,也可直接 require 进入,同时不管请求多少次,也只会加载一次
  第一次加载后,模块就会缓存起来,供后续使用
**/ 

AMD

CommonJS 以服务器端为目标环境,能够一次性把所有模块都加载到内存,而 AMD 异步模块定义,是以浏览器为目标。 AMD模块是以函数包装的方式来实现的,就避免暴露全局变量的方式,但是需要AMD加载库来实现。

// ID 为'moduleA'的模块定义。moduleA 依赖 moduleB,
// moduleB 会异步加载
define('moduleA', ['moduleB'], function(moduleB) {
 return {
 stuff: moduleB.doStuff();
 };
}); 

ES6 模块

以上说的两种都需要模块加载器,ES6引入了模块规范,同时原生浏览器也开始支持,融入了 AMD 和 CommonJS的优点


  //像我们平常写的
  import { foo } from './fooModule.js'
  export default 123
  //或者
  <script type="module">
     import './moduleA.js'
  <script>

<script type="module" src="./moduleA.js"></script>
/**
与传统脚本不同,所有模块都会像<script defer>加载的脚本一样按顺序执行。解析到<script
type="module">标签后会立即下载模块文件,但执行会延迟到文档解析完成。
**/

ES6模块的加载

既可以通过浏览器加载,也可以通过打包工具加载

ES6模块部分优点

 1、模块只能加载一次。
 2、模块可以请求加载其他模块。
 3、模块顶级 this 的值是 undefined(常规脚本中是 window)。
 4、模块中的 var 声明不会添加到 window 对象。
 5、ES6 模块是异步加载和执行的,输出值的引用。

几个不同之处

1、CommonJS模块输出是值的拷贝,ES6 Module模块输出的值是引用
2、CommonJS是运行时加载,ES6 Module是编译是输出
3、AMD规范是采用异步方式,依赖前置必须一开始就写好,所有的依赖加载完成后才会执行回调函数里的内容

剩下关于 ES6 模块导入导出的使用方法和规则就不逐一介绍了。

收藏
评论区

相关推荐

JavaScript 引擎、事件循环、任务队列
一、先引用别人的一幅图 (很好的概括了JS主线程和任务队列是如何执行的) 1.JS引擎和runtime的区别: 引擎:解释并编译代码,让它变成
😎手撕吊打面试官系列面试题
js基础 1. 用js打印一个乘法表 这一题面试官考察的是你关于js的打印相关基础api的熟悉程度,以及基本的数学常识,送分题 console.log( 111 212 224 313 326 339 414 428 4312 4416 515 5210 5315 5420 5525
项目实战之---AES 加密
ajax/index.js import axiosApi from '../js/fetch'; import { baseUrl, headerParams } from '../js/baseUrl'; // import引用AES源码js import CryptoJS from 'cryptojs/cryptojs'; console.lo
Android webview 与 js(Vue) 交互
js 与原生交互分为两种情况:js 调用原生方法,原生调用 js 方法。 本文将对这两种情况分别讲解,H5 端用 vue 实现。 一、前期准备(Vue项目准备) 本文的 H5 端用Vue 实现,所以在正式开始前先把 Vue 项目环境准备好。 项目写好后,执行 npm run serve 命令启动项目,启动成功后会在命令
面试之手撕 JS 继承
提到JS继承,你首先想到的什么? 面试 继承方式 优缺点...,js继承作为曾经的苦主,我看了忘,忘了看,看了又忘,OMG,都0212年了面试官还不放过我。 ok
JS - ES6 的 Module
一、介绍 模块,(Module),是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体)。 两个基本的特征:外部特征和内部特征 外部特征是指模块跟外部环境联系的接口(即其他模块或程序调用该模块的方式,包括有输入输出参数、引用的全局变量)和模块的功能 内部特征是指模块的内部环境具有的特点(即该模
44道JS难题,还不来考考?
国外某网站给出了44道JS难题,试着做了下,只做对了17道。这些题涉及面非常广,涵盖JS原型、函数细节、强制转换、闭包等知识,而且都是非常细节的东西,透过这些小细节可以折
44道JS难题,做对一半就是高手
国外某网站给出了44道JS难题,试着做了下,只做对了17道。这些题涉及面非常广,涵盖JS原型、函数细节、强制转换、闭包等知识,而且都是非常细节的东西,透过这些小细节可以折
几个常用js库,别再重复造轮子了
年底了,总结下今年用到的一些有意思的《js轮子》(只是大概列出些比较有意思的库,每个标题都是超链接,可点击自行查阅) 希望能对您有用! 如有意思的 轮子 可以在评论列出一起讨论下 color(https://links.jianshu.com/go?tohttps%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fco
js 理解模块化
经常在面试或者其他文章看到关于模块化的问题,之前也只是寥寥看了几次,对于 CommonJS,AMD,ES6也说不出个所以然,于是今天抽空好好看了 红宝书第4版关于模块化的介绍,这里记录一下。 理解模块模式 初衷在开发中肯定有设计大量三方库或者业务逻辑代码,较好的方式是将其分割为多个小模块,最后以一定的方式连接起来
js去除字符串
js去除字符串js<DOCTYPE html<html<head <title</title</head<body</body<script type"text/javascript" function delHtmlTag(str){   return str.replace(/<^/g,""); } var s
js删除表格中的某一行
点击表格中的内容,删除某一行正文js代码如下 function removeTd(obj) { obj.parentNode.parentNode.remove();}
日常必备的JS工具函数大全
为元素添加on方法 Element.prototype.on Element.prototype.addEventListener; NodeList.prototype.on function (event, fn) 、 []['forEach'].call(this, function (el) el.on(ev
只听说过CSS in JS,怎么还有JS in CSS?
CSS in JS是一种解决css问题想法的集合,而不是一个指定的库。从CSS in JS的字面意思可以看出,它是将css样式写在JavaScript文件中,而不需要独立出.css、.less之类的文件。将css放在js中使我们更方便的使用js的变量、模块化、treeshaking。还解决了css中的一些问题,譬如:更方便解决基于状态的样式,更容易追溯依赖关
前端 - 常见的异常捕获方法
前端异常捕获在ES3之前js代码执行的过程中,一旦出现错误,整个js代码都会停止执行,这样就显的代码非常的不健壮。从ES3开始,js也提供了类似的异常处理机制,从而让js代码变的更健壮,程序执行的过程中出现了异常,也可以让程序具有了一部分的异常恢复能力。js异常的特点是,出现不会导致JS引擎崩溃,最多只会终止当前执行的任务。回归正题,我们该如何在程序异常发生