Node应用使用CommonJS模块规范,Node中每个文件就是一个模块,有自己的作用域,在模块中定义的变量、函数都是私有的。
模块中有四个重要的变量global、module、exports、require。
Node中的全局变量global,和浏览器的window对象类似,声明在全局下的变量可以在所有模块中访问。module变量代表当前模块,其中module.exports属性表示当前模块对外输出的接口,当其他文件使用require引用该模块时,实际就是读取module.exports变量。
// 模块a.js
const num = 1
module.exports = {
num,
add: function(x,y){
return x+y
}
}
//模块b.js,引入a.js
const a = require('./a.js')
// {num:1, add:fn}
而exports变量是对module.exports的引用;相当于在顶部声明一个变量var exports = module.exports,exports不能直接赋值,这样就无法指向module.exports了
所以使用exports对外输出接口的写法如下,
// 模块a.js
exports.num = 1
exports.add = function(x,y){
return x+y
}
CommonJS规范加载模块是同步的,加载完成以后,才能执行后面的操作。同时模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
AMD:Asynchronous Module Definition,异步模块定义,是RequireJS在推广过程中对模块定义的规范化产出。require.js加载完成后,通过回调方法加载data-main中的js,然后require.config方法指定第三方资源路径,define方法来定义自己写的模块,最后使用require方法加载模块
<!-- 引入require.js,main.js中配置require.config -->
<script src="require.js" data-main="main.js"></script>
<!-- main.js -->
<script>
require.config({
paths: {
"vue": "./vue",
"jquery": "./jquery" //js后缀不写
}
})
require(["Vue","jquery"],function(vue,$){
// 依赖的模块会以参数的形式传进回调函数,这里就可以正常使用Vue和jQuery了
})
</script>
define方法自定义模块,不需要在require.config里配置路径
<!-- 自己的模块比如:module_test.js -->
<script>
define(function(){
function add(x,y){
return x+y
}
return {
add
}
})
</script>
<!-- 如果自定义依赖其他模块,先引入其他模块 -->
<script>
define(['jquery'],function($){
function add(x,y){
const total = x+y
$('body').html(total)
return total
}
return {
add
}
})
</script>
CMD:Common Module Definition,通用模块定义, 是SeaJS在推广过程中对模块定义的规范化产出。和AMD语法类似,区别是AMD在定义模块的时候就要声明其依赖的模块,而CMD只有在用到某个模块的时候再去加载。AMD和CMD都实现了前端资源的模块的,而现在ES6和webpack打包工具的出现这两个应该使用比较少了。
ES6在语言标准的层面上,实现了模块功能。模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。我们平时的项目一般都是基于webpack来处理,如果想直接在浏览器中加载ES6模块,和原来一样使用<script>便签,同时需要添加type="module"属性。
// m1.js定义输出
const a = 1
export default a
export const b = 2
export function add(x,y){
return x+y
}
// m2.js引用
import a, {b, add} from './m2.js'
ES6模块与CommonJS模块的两大差异
ES6模块中的原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
UMD是AMD和CommonJS的糅合,UMD会先判断是否支持Node.js模块的exports,再判断AMD的define方法是否存在,最后都不支持的话就挂载在window全局变量下。
比如打开Vue.js文件
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ?
module.exports = factory() :
// 是否支持Node.js模块
typeof define === 'function' && define.amd ?
define(factory) :
// 是否支持AMD
(global = global || self, global.Vue = factory());
// 最后都不行挂载在window.Vue
}(this, function () {
'use strict';
}))
模块化是指把一个复杂的系统分解到一个一个的模块。模块化开发的优点:代码复用,让我们更方便地进行代码管理、同时也便于后面代码的修改和维护。一个单独的文件就是一个模块,是一个单独的作用域,只向外暴露特定的变量和函数。
CommonJS 是服务器端的模块化方案,nodeJs 就采用了这种方案。在 CommonJS 规范中,一个文件即一个模块,用module.exports和exports定义模块输出的接口,用require加载模块。在 requireJS 中用define定义模块,require载入模块,require.config用来配置路径。ES6 Module 主要使用export输出,import加载。
在很长的一段前端历史里,是不存在打包这个说法的。那个时候页面基本是纯静态的或者服务端输出的, 没有 AJAX,也没有 jQuery。Google 推出 Gmail 的时候(2004 年),XMLHttpRequest, 也就是我们俗称的 AJAX被拾起的时候
AMD 是 RequireJS 给出的模块加载方案。 支持递归依赖解析、模块异步加载,夜兼容 CommonJS 可以在 Node.js 里用。 虽然目前已经不再流行,很多站点更倾向于编写 ES Modules 并直接 Webpack 打包, 但 AMD 是完整的
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。export通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例。
本文包含两部分,第一部分通过简明的描述介绍什么是 CommonJS、AMD、CMD、UMD、ES Module 以及它们的常见用法,第二部分则根据实际问题指出在正常的 webpack 构建过程中该如何指定打包配置中的模块化参数。
这篇文章主要介绍了css模块化方案,css的模块化方案可能和js的一样多,下面简单介绍几种主要的模块方案,非常具有实用价值,需要的小伙伴可以参考下。css的模块化方案可能和js的一样多,下面简单介绍几种主要的模块方案
在模块化规范形成之前,JS开发者使用Module设计模式来解决JS全局作用域的污染问题。Module模式最初被定义为一种在传统软件工程中为类提供私有和公有封装的方法。在JavaScript中,Module模式使用匿名函数自调用 (闭包)来封装
众所周知,早期 JavaScript 原生并不支持模块化,直到 2015 年,TC39 发布 ES6,其中有一个规范就是 ES modules(为了方便表述,后面统一简称 ESM)。但是在 ES6 规范提出前,就已经存在了一些模块化方案
CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。ES6 Modules 的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!