模块化基础

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

JS语言刚开始只是为了处理一些页面上的交互效果,后来逐渐形成一门复杂的语言,在实现的功能越来越复杂,项目越来越大时,也开始像其他语言一样分文件开发,将每一个文件定义为一个module,在需要使用的模块引入这个module以引用这个模块暴露出来的接口,并且不让其污染全局作用域

常用的模块化规范有: CommonJS、AMD、CMD、ESM

一、CommonJS

CommonJS是最早出现被广泛应用的标准化模块化规范,是node完成初始,开发npm包管理工具时所用的模块化规范。

1.特点

》模块内所有代码都是在模块作用域,不会污染全局作用域
》CommonJS起初就是为了node服务的,他是同步的
》require 读入并执行一个JavaScript文件,返回该模块的exports对象。如果没有发现指定模块,会报错,如果第一次进来,会降exports存入缓存,然后第二次进入后只需要返回缓存中的export即可
》exports 用来向外暴露 API,exports 只能是一个 object 对象,暴漏的 API 须作为该对象的属性。

2.使用

```javascript // exports 规定exports为一个对象 module.exports = { key: value } module.exports.x = value export.x = value

// require 如果是第三方模块,xxx为模块名;如果是自定义模块,xxx为模块文件路径 require('moment') require('./math.js') ```

二、AMD

CommonJS是同步的,只有需要引入的模块加载完成才能执行后面的代码,一般都是服务端使用,如果浏览器端使用,需要借助Browserify将项目打包。而AMD是基于异步开发模式开发的,允许异步完成后调用一个回调函数。

1. 定义和使用

```javascript // 定义暴露接口 define(function() { // do something })

// 定义没有依赖的模块 define('math',['exports'],function (exports) { exports.getObs = function() { return Math.abs(-3); } // OR:直接返回 // function getObs() { // return Math.abs(-3); // } // return { // getObs, // }; });

// require

require(['math'], function(math){ math.getObs() }) ```

2.require.js

require是遵循amd规范的一个模块化工具,下面结合require.js来使用一下amd规范

》首先require需要下载,官网或者github上都可以(官网地址: https://requirejs.org/docs/release/2.3.6/minified/require.js)
》然后把require.js放入一个文件夹下(amd/js/require.js),并在入口文件中引入

amd/index.html html <!DOCTYPE html> <html> <head> <title>Modular Demo</title> <script src="js/require.js" data-main="main"></script> </head> <body></body> </html>

》 然后定义模块

javascript // amd/modules/math define('math',['exports'],function (exports) { exports.getObs = function() { return Math.abs(-3); } });

》 在main中引入模块

require.config({ baseUrl: "", // 默认在根目录下 paths: { math: "./modules/math", }, }); require(["math"], function (math) { alert(math.getObs()); })

效果: 在这里插入图片描述

二、CMD

CMD也是基于异步服务于浏览器端的一个模块化规范,它结合了ComminJs和AMD的特点,并开发了自己的模块化工具语言SeaJs

1.定义和使用

```javascript //定义没有依赖的模块,exports,module三个是默认传入 define(function(exports, module){ exports.xxx = value // Or // module.exports = value })

//定义有依赖的模块 define(function(require, exports, module){ //同步引入依赖 var module2 = require('./module2') //异步引入依赖 require.async('./module3', function (m3) {}) //暴露模块 exports.xxx = value })

// 引用 define(function (require) { var m1 = require('./module1') console.log(m1.xxx) })

```

2.SeaJS

》首先SeaJS需要下载,https://github.com/seajs/seajs
》引入到index.js

html <!DOCTYPE html> <html> <head> <title>Modular Demo</title> <script type="text/javascript" src="js/sea.js"></script> <script type="text/javascript"> seajs.use("./main"); </script> </head> <body></body> </html>

》定义模块

javascript define(function (require, exports, module) { module.exports = { getRandom: () => { return Math.random(); } } })

》在main.js中引用模块

javascript define(function (require) { var math = require("./modules/math.js"); console.log(math.getRandom()); });

效果 在这里插入图片描述

三 ESM

1.定义和使用

```javascript // export export { a: '', b: function() {} } export default { a: '' } export const a = 123; export const {a, b} = Obj

// 引入import 必须放在代码的最前面,因为ESM是不编译的 import A from "./a.js" import { a,b } from "./a.js" ```

2、ESM和CMD的区别

1.CMD因为输出的export对象是运行完成后才输出接口,而EMD是引用接口,所以编译时就输出接口
2.CMD是有缓存的,模块内数据更新,不会更新到引用的模块,还是使用缓存中的值。而EMD是没有缓存的,他是直接引用了模块中的变量和方法,当有数据改变时,引用的模块也会更新。

参考文章: https://juejin.cn/post/6844903744518389768#heading-32

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值