JS模块简介

js模块化,简单说就是将系统或者功能分隔成单独的、互不影响的代码片段,经过严格定义接口,使各模块间互不影响,且可以为其他所用。
常见的模块化有,C中的include (.h)文件、java中的import等。
为什么JS需要模块
很显然,没有模块我们也可以实现同样的功能,为什么我们还要使用模块来写js代码呢?下面几点是模块化给我们带来的一些变化:
ES5及之前的模块系统
在ES5及之前版本,还没有原生的模块语法。不过这并不代表ES5之前,前端没有使用模块。简单介绍两种:IIFE、Revealing Module.
IIFE
Immediately Invoked Function Expression,立即执行函数表达式。
(function(){
// ...
})()
看上面的代码,IIFE可以说成是一个在定义的时候就执行的匿名函数。注意函数是先被”()”包起来了,然后后面紧跟”()”表示执行函数。如果是以下代码,将会报错:
function(){
console.log('test');
}()
// => Uncaught SyntaxError: Unexpected token )
这种写法表示,先定义一个匿名函数,然后再去解析”()”。由于在第一行”function”出现在首位,这表明此处定义一个函数,函数后紧跟”()”,此时表示单独解析”()”,就会报出上面的错误信息,因此需要先将函数定义包裹起来。
“(function…)”这种写法表示执行”()”内部代码,并返回该语句执行结果,此处返回结果为该函数,后面紧跟”()”即表示执行该函数。IIFE可以帮助我们做到:
显而易见,这种编码方式并没有提供良好的机制来解决依赖管理问题。
Revealing Module
根据字面暂解释为揭示模式,与IIFE形式类似,但是提供了一个返回值。方便集中管理公有的api,使模块、公用api更加简洁清晰。
// Expose module as global variable
var singleton = function(){
// Inner logic
function sayHello(){
console.log('Hello');
}
// Expose API
return {
sayHello: sayHello
}
}()
稍微注意下,上面的代码,我们并没有用”()”去包裹,因为关键字”function”并不在该行的开头。
我们可以像下面这样使用模块api:
// Access module functionality singleton.sayHello(); // => Hello
当然,我们也可以以构造函数形式导出:
// Expose module as global variable
var Module = function(){
// Inner logic
function sayHello(){
console.log('Hello');
}
// Expose API
return {
sayHello: sayHello
}
}
请注意,上面函数在定义的时候并没有执行。
我们可以这么使用它:
var module = new Module(); module.sayHello(); // => Hello
与IIFE一样,揭示模式并没有提供良好的解决依赖管理的方案。
更多模块化解决方案
ES6或者ES2015,自带原生的模块语法。
在这之前,有以下几种常见的用于模块化的解决方案:
AMD
AMD,Asynchronous Module Definition,异步模块定义。AMD形式被用于浏览器端,使用”define”来定义模块依赖:
//Calling define with a dependency array and a factory function
define(['dep1', 'dep2'], function (dep1, dep2) {
//Define the module value by returning a value.
return function () {};
});
CMD
CMD,Common Module Definition,通用模块定义。该规范由国内大神玉伯提出,与AMD区别在与AMD是依赖关系前置,有该依赖就必须先加载依赖,CMD是按需加载。
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
})
CommonJs
CommonJs在Node.js中用的较多,使用”require”来定义依赖,使用”module.exports”来定义模块:
var dep1 = require('./dep1');
var dep2 = require('./dep2');
module.exports = function(){
// ...
}
UMD
UMD,Universal Module Definition,通用模块定义。可以用于浏览器端与Node.js端:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['b'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory(require('b'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.b);
}
}(this, function (b) {
//use b in some fashion.
// Just return a value to define the module export.
// This example returns an object, but the module
// can return a function as the exported value.
return {};
}));
System.register
System.register方式设计初衷主要是为了在ES5中能够支持ES6模块语法:
import { p as q } from './dep';
var s = 'local';
export function func() {
return q;
}
export class C {
}
ES6 module
ES6中自带原生的模块语法,使用关键字”export”来导出模块的公用api:
// lib.js
// Export the function
export function sayHello(){
console.log('Hello');
}
// Do not export the function
function somePrivateFunction(){
// ...
}
以关键字”import”来导入模块:
import { sayHello } from './lib';
sayHello();
// => Hello
目前各浏览器对ES6的支持度不一,因此我们现在需要使用编译器,像Babel,来将ES6的代码编译成ES5的形式。
模块加载器
一个模块加载器可以理解模块,并以固定的形式来加载模块。
模块加载器工作在运行时,流程大致如下:
一些比较常见的模块加载器有:
模块打包
模块打包可以替换模块加载器。
然而,相比模块加载器,模块打包动作是在编译时运行的:
截止目前,比较常用的模块打包方案有以下两种:
总结
为了在现代js开发环境中更好的使用这些工具,你首先需要知道模块、模块化解决方案、模块加载、模块打包之前的区别。
模块是一段封装好的代码,可以以公用api形式导出并在其他代码中被加载和调用;
模块化解决方案或者模块化思想,实际含义是定义一个模块的语法。由于定义语法的差异,目前常用的有AMD、CMD、CommonJS、UMD等;
模块加载,在运行期解析和加载模块。常见的有RequireJS、SeaJS、SystemJS和jspm;
模块打包,其替换了模块加载的概念,在编译期间生成一个所有代码整合后的bundle.js文件。常见的有Browserify和Webpack。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家的支持。
# 模块
# module
# load加载js
# javascript
# bundle
# 浅谈Vue SSR中的Bundle的具有使用
# 浅析webpack-bundle-analyzer在vue-cli3中的使用
# 浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
# 浅谈webpack打包生成的bundle.js文件过大的问题
# no-bundle 构建原理浅析
# 加载
# 我们可以
# 不需要
# 两种
# 自带
# 按需
# 的是
# 是一个
# 器中
# 就会
# 是在
# 还没有
# 好了
# 将会
# 在这
# 出现在
# 你在
# 并在
# 不代表
# 要去
相关文章:
如何在企业微信快速生成手机电脑官网?
免费制作小说封面的网站有哪些,怎么接网站批量的封面单?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
如何快速搭建高效服务器建站系统?
如何快速辨别茅台真假?关键步骤解析
打鱼网站制作软件,波克捕鱼官方号怎么注册?
定制建站哪家更专业可靠?推荐榜单揭晓
建站之星如何实现五合一智能建站与营销推广?
宝塔建站无法访问?如何排查配置与端口问题?
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
个人网站制作流程图片大全,个人网站如何注销?
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?
香港服务器如何优化才能显著提升网站加载速度?
c# await 一个已经完成的Task会发生什么
网站制作软件免费下载安装,有哪些免费下载的软件网站?
教学网站制作软件,学习*后期制作的网站有哪些?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
c# F# 的 MailboxProcessor 和 C# 的 Actor 模型
建站主机选购指南与交易推荐:核心配置解析
建站之星安全性能如何?防护体系能否抵御黑客入侵?
如何选择适配移动端的WAP自助建站平台?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何通过VPS建站无需域名直接访问?
头像制作网站在线制作软件,dw网页背景图像怎么设置?
建站主机选哪家性价比最高?
小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化
红河网站制作公司,红河事业单位身份证如何上传?
黑客入侵网站服务器的常见手法有哪些?
家具网站制作软件,家具厂怎么跑业务?
宝塔新建站点为何无法访问?如何排查?
如何确保西部建站助手FTP传输的安全性?
如何在IIS中新建站点并配置端口与物理路径?
孙琪峥织梦建站教程如何优化数据库安全?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
独立制作一个网站多少钱,建立网站需要花多少钱?
制作网站公司那家好,网络公司是做什么的?
C#如何在一个XML文件中查找并替换文本内容
建站主机选虚拟主机还是云服务器更好?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
大学网站设计制作软件有哪些,如何将网站制作成自己app?
Swift中循环语句中的转移语句 break 和 continue
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
微信推文制作网站有哪些,怎么做微信推文,急?
如何规划企业建站流程的关键步骤?
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
再谈Python中的字符串与字符编码(推荐)
如何通过虚拟主机空间快速建站?
如何基于PHP生成高效IDC网络公司建站源码?
*请认真填写需求信息,我们会在24小时内与您取得联系。