前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端模块化的区别

前端模块化的区别

原创
作者头像
大发明家
发布2021-12-06 13:54:58
3930
发布2021-12-06 13:54:58
举报
文章被收录于专栏:技术博客文章

1.commonJS语法:

暴露模块:module.exports = value或exports.xxx = value

引入模块:require(xxx),如果是第三方模块,xxx为模块名;如果是自定义模块,xxx为模块文件路径

每个模块内部,module对象代表当前模块,它的exports属性(即module.exports)是对外的接口(暴露出去)。

加载某个模块,其实是加载该模块的module.exports属性。

代码语言:txt
复制
// example.js
代码语言:txt
复制
var x = 5;
代码语言:txt
复制
var addX = function (value) {
代码语言:txt
复制
  return value + x;
代码语言:txt
复制
};
代码语言:txt
复制
module.exports.x = x;
代码语言:txt
复制
module.exports.addX = addX;

通过module.exports输出变量x和函数addX。

代码语言:txt
复制
var example = require('./example.js');//如果参数字符串以“./”开头,则表示加载的是一个位于相对路径
代码语言:txt
复制
console.log(example.x); // 5
代码语言:txt
复制
console.log(example.addX(1)); // 6

require命令用于加载模块文件。require命令的基本功能是,读入并执行一个javascript文件,然后返回该模块的exports对象,如果没有的话就会报错。

2.AMD语法

定义没有依赖的模块

代码语言:txt
复制
//定义没有依赖的模块
代码语言:txt
复制
```define(function(){
代码语言:txt
复制
   return 模块
代码语言:txt
复制
})

定义有依赖的模块

代码语言:txt
复制
//定义有依赖的模块
代码语言:txt
复制
define(['module1', 'module2'], function(m1, m2){
代码语言:txt
复制
   return 模块
代码语言:txt
复制
})

引入模块

代码语言:txt
复制
require(['module1', 'module2'], function(m1, m2){
代码语言:txt
复制
   使用m1/m2
代码语言:txt
复制
})

3.CMD

CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。

CMD规范整合了CommonJS和AMD规范的特点。

定义暴露模块:

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

引入模块

代码语言:txt
复制
define(function (require) {
代码语言:txt
复制
  var m1 = require('./module1')
代码语言:txt
复制
  var m4 = require('./module4')
代码语言:txt
复制
  m1.show()
代码语言:txt
复制
  m4.show()
代码语言:txt
复制
})

4.ES6

export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

代码语言:txt
复制
/** 定义模块 math.js **/
代码语言:txt
复制
var basicNum = 0;
代码语言:txt
复制
var add = function (a, b) {
代码语言:txt
复制
    return a + b;
代码语言:txt
复制
};
代码语言:txt
复制
export { basicNum, add };
代码语言:txt
复制
/** 引用模块 **/
代码语言:txt
复制
import { basicNum, add } from './math';
代码语言:txt
复制
function test(ele) {
代码语言:txt
复制
    ele.textContent = add(99 + basicNum);
代码语言:txt
复制
}

注意:使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export

default命令,为模块指定默认输出。

另一种方式

代码语言:txt
复制
// export-default.js
代码语言:txt
复制
export default function () {
代码语言:txt
复制
  console.log('foo');
代码语言:txt
复制
}

模块默认输出, 其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

代码语言:txt
复制
// import-default.js
代码语言:txt
复制
import customName from './export-default';
代码语言:txt
复制
customName(); // 'foo'
其他

如果当前的module文件非常大,可能造成堵塞可以如下操作

代码语言:txt
复制
<script src="path/to/myModule.js" defer></script>
代码语言:txt
复制
<script src="path/to/myModule.js" async></script>

defer:等到整个页面正常渲染结束才会执行,

async:一旦下载完成,渲染引擎就会中断渲染,执行这个脚本以后再继续渲染。

如果有多个defer脚本,则会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

浏览器加载ES6模块时也使用script标签,但是要加入type=”module”属性。

代码语言:txt
复制
<script type="module" src="foo.js"></script>

由于type属性设为module,所以浏览器知道这是一个ES6模块

代码语言:txt
复制
<script type="module" src="foo.js"></script>
代码语言:txt
复制
<!-- 等同于 -->
代码语言:txt
复制
<script type="module" src="foo.js" defer></script>

ES6模块与CommonJS模块的差异

代码语言:txt
复制
CommonJS模块输出的是一个值的复制,ES6模块输出的是值的引用。
代码语言:txt
复制
CommonJS模块是运行时加载,ES6模块是编译时输出接口。

因为CommonJS加载的是一个对象(即module.exports属性),该对象只有在脚本运行结束时才会生成。而ES6模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.commonJS语法:
  • 2.AMD语法
  • 3.CMD
  • 4.ES6
    • 其他
    • ES6模块与CommonJS模块的差异
    相关产品与服务
    命令行工具
    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档