前端为什么需要模块化开发
栏目: JavaScript · 发布时间: 6年前
内容简介:看着上面的script标签,是不是有一种很熟悉的感觉。通过script引入你想要的资源,从上到下的顺序,这其中顺序是非常重要的,资源的加载先后决定你的代码是否能够跑的下去。当然我们还没有加入defer和async属性,不然加载的逻辑会更加复杂。这里引入的资源还是算少的,过多的script标签会造成过多的请求。同时项目越大,到最后依赖会越来越复杂,并且难以维护,依赖模糊,请求过多。全局污染的可能性就会更大。那么问题来了,如何形成独立的作用域?defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,
看着上面的script标签,是不是有一种很熟悉的感觉。通过script引入你想要的资源,从上到下的顺序,这其中顺序是非常重要的,资源的加载先后决定你的代码是否能够跑的下去。当然我们还没有加入defer和async属性,不然加载的逻辑会更加复杂。这里引入的资源还是算少的,过多的script标签会造成过多的请求。同时项目越大,到最后依赖会越来越复杂,并且难以维护,依赖模糊,请求过多。全局污染的可能性就会更大。那么问题来了,如何形成独立的作用域?
defer和async的区别
defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。
模块化的基石
立即执行函数(immediately-invoked function expression),简称IIFE,其实是一个javaScript函数。可以在函数内部定义方法以及 私有属性 ,相当于一个封闭的作用域。例如下面的代码:
let module = (function(){ let _private = 'myself'; let fun = () =>{ console.log(_private) } return { fun:fun } })() module.fun()//myself module._private//undefined 复制代码
以上代码便可以形成一个独立的作用域,一定程度上可以减少全局污染的可能性。这种写法可是现代模块化的 基石 。虽然能够定义方法,但是不能定义属性,这时候各种前端规范就陆续登场了。
首先登场的是common.js
最先遵守CommonJS规范是node.js。这次变革让服务端也能用js爽歪歪的写了,我们的javaScript并不止于浏览器,服务端也能分一杯羹,被人称为模块化的第一座里程碑。想想长征二万五,第一座里程碑在哪里?
CommomJS模块的特点
- 模块内的代码只会运行在模块作用域内,不会污染到全局作用域
- 模块的可以多次引入,但只会在第一次加载的时候运行一次,后面的运行都是取缓存的值。想要让模块再次运行,必须清楚缓存。
// 删除指定模块的缓存 delete require.cache[moduleName]; // 删除所有模块的缓存 Object.keys(require.cache).forEach(function(key) { delete require.cache[key]; }) 复制代码
- 模块的加载顺序,遵循在代码中出现的顺序。
为什么要少用exports
exports只是一个变量,指向module.exports,也就是exports只是一个 引用 而已。所以对外输出模块的时候,我们就可以通过exports添加方法和和属性。通过module.exports对外输出其实也是读取module.exports的变量。但是使用exports时要非常的小心,因为稍不注意就会切断和module.exports的联系。例如:
exports = function(x) {console.log(x)}; 复制代码
上面的代码运行之后,exports不再指向module.exports。如果你难以区分清楚,一般最好就别用exports,只使用module.exports就行。
怎么区分模块是直接执行,还是被调用执行。
require.mainAPI就有这样的作用,如果模块是直接执行,那么这时require.main属性就指向模块本身。例如下面:
require.main === module 复制代码
为什么客户端不使用commonjs规范?
我们知道客户端(浏览器)加载资源主要是通过网络获取,一般本地读取的比较少,而node.js主要是用于服务器编程,模块文件一般都存在于本地硬盘上,然后I/O读取是非常快速的,所以即使是 同步加载 也是能够适用的,而浏览器加载资源必须通过异步获取,比如常见的ajax请求,这时候AMD规范就非常合适了,可以异步加载模块,允许回调函数。
客户端的规范不仅仅只有AMD,还有CMD.
每个规范的兴起背后总有一些原因,requirejs的流行是因为commonjs未能满足我们需要的效果,sea.js被创造的 原因 也是因为requirejs不能满足一些场景。
AMD和CMD的区别
- | AMD | CMD |
---|---|---|
原理 | define(id ?,dependencies ?,factory)定义了一个单独的函数“define”。id为要定义的模块。依赖通过dependencies传入factory是一个工厂参数的对象,指定模块的导出值。 | CMD规范与AMD类似,并尽量保持简单,但是更多的与common.js保持兼容性。 |
优点 | 特别适用于浏览器环境的异步加载 ,且可以并行加载。依赖前置,提前执行。 定义模块时就能清楚的声明所要依赖的模块 | 依赖就近,延迟执行。 按需加载,需要用到时再require |
缺点 | 开发成本较高,模块定义方式的语义交为难理解,不是很符合通过的模块化思维方式。 | 依赖SPM打包,模块的加载主观逻辑交重。 |
体现 | require.js | sea.js |
ES6让前端模块化触手可及
概念
ES6的模块不是对象,import语法会被JavaScript引擎 静态分析 ,请注意,这是一个很重要的功能,我们通常使用commonjs时,代码都是在运行时加载的,而es6是在编译时就引入模块代码,当然我们现在的浏览器还没有这么强大的功能,需要借助各类的编译工具(webpack)才能正确的姿势来使用es6的模块化的功能。也正因为能够编译时就引入模块代码,所以使得静态分析就能够实现了。
ES6模块化有哪些优点
-
静态化编译 如果能够静态化,编译的时候就能确定模块的依赖关系,以及输出和输入的变量,然后CommonJS和AMD以及CMD都只能在运行代码时才能确定这些关系。
-
不需要特殊的UMD模块化格式 不再需要UMD模块的格式,将来服务器和浏览器都会支持ES6模块格式。目前各种 工具 库(webpack)其实已经做到这一点了。
-
目前的各类全局变量都可以模块化 比如navigator现在是全局变量,以后就可以模块化加载。这样就不再需要对象作为命名空间。
需要注意的地方
- export语句输出的接口,通过import引入之后,与其对应的值是动态的绑定关系,也就是模块的内的值即使改变了,也是可以取到实时的值的。而commonJS模块输出的是值的缓存,不存在动态更新。
- 由于es6设计初衷就是要静态优化,所以export命令不能处于 块级作用域内 ,如果出现就会报错,所以一般export统一写在底部或则顶层。
function fun(){ export default 'hello' //SyntaxError } 复制代码
- import命令具有提升效果,会提升到整个模块的头部首先执行。例如:
fun() import {fun} from 'myModule'; 复制代码
上面的代码import的执行早于fun调用,原因是import命令是编译阶段执行的,也就是在代码运行之前。
export default使用
export default就是输出一个叫default的变量或方法,然后系统允许你为它取任意名字。所以,你可以看到下面的写法。
//modules.js function add(x,y){ return x*y } export {add as default}; //等同于 export default add; //app.js import {default add foo} from 'modules'; //等同于 import foo from 'modules' 复制代码
这是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ordering Disorder
Khoi Vinh / New Riders Press / 2010-12-03 / USD 29.99
The grid has long been an invaluable tool for creating order out of chaos for designers of all kinds—from city planners to architects to typesetters and graphic artists. In recent years, web designers......一起来看看 《Ordering Disorder》 这本书的介绍吧!