最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • js模块化

    正文概述 掘金(lhw46831)   2021-04-08   539

    背景

    1. js承担的任务越来越重。其它语言像Java有包等模块化技术。
    2. js通过立即执行函数来实现模块化
        var myModule = (function(){
            var var1 = 1;
            var var2 = 2;
            function fn1(){
            }
            function fn2(){
            }
            return {
                fn1: fn1,
                fn2: fn2
            };
        })();
    

    目前,通行的JavaScript模块规范主要有两种:CommonJS和AMD

    1. CommonJS是随着node js诞生服务端的模块化解决方案。主要是通过require来加载依赖项,通过exports或者module.exports来暴露接口或者数据的方式。
    1. 定义模块。根据CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为global对象的属性

    2. 模块输出:模块只有一个出口,module.exports对象,我们需要把模块希望输出的内容放入该对象

    3. 加载模块:加载模块使用require方法,该方法读取一个文件并执行,返回文件内部的module.exports对象

    1. module.exports 初始值为一个空对象 {}
    2. exports 是指向的 module.exports 的引用
    3. require() 返回的是 module.exports 而不是 exports

    尴尬的浏览器

    仔细看上面的代码,会发现require是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块接口。

    这在服务器端实现很简单,也很自然,然而, 想在浏览器端实现问题却很多。

    浏览器端,加载JavaScript最佳、最容易的方式是在document中插入script 标签。但脚本标签天生异步,传统CommonJS模块在浏览器环境中无法正常加载。

    解决思路之一是,开发一个服务器端组件,对模块代码作静态分析,将模块与它的依赖列表一起返回给浏览器端。 这很好使,但需要服务器安装额外的组件,并因此要调整一系列底层架构。

    另一种解决思路是,用一套标准模板来封装模块定义,但是对于模块应该怎么定义和怎么加载,又产生的分歧:

    AMD

    AMD 即Asynchronous Module Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范

    由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎RequireJS,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出

    requireJS主要解决两个问题

    多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器 js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长

    CMD

    CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同

    语法 Sea.js 推崇一个模块一个文件,遵循统一的写法

    AMD与CMD区别

    关于这两个的区别网上可以搜出一堆文章,简单总结一下

    最明显的区别就是在模块定义时对依赖的处理不同

    AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块 CMD推崇就近依赖,只有在用到某个模块的时候再去require 这种区别各有优劣,只是语法上的差距,而且requireJS和SeaJS都支持对方的写法

    最终解决方案

    2015年6月,ECMAScript2015也就是ES6发布了,JavaScript终于在语言标准的层面上,实现了模块功能,使得在编译时就能确定模块的依赖关系,以及其输入和输出的变量,不像 CommonJS、AMD之类的需要在运行时才能确定(例如FIS这样的工具只能预处理依赖关系,本质上还是运行时解析),成为浏览器和服务器通用的模块解决方案。

    与CommonJS用require()方法加载模块不同,在ES6中,import命令可以具体指定加载模块中用export命令暴露的接口(不指定具体的接口,默认加载export default),没有指定的是不会加载的,因此会在编译时就完成模块的加载,这种加载方式称为编译时加载或者静态加载。

    可以看出,CommonJS中是将整个模块作为一个对象引入,然后再获取这个对象上的某个属性。

    因此ES6的编译时加载,在效率上面会提高不少,此外,还会带来一些其它的好处,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。

    可惜的是,目前浏览器和Node.js的支持程度都并不理想,截止发稿,也就只有 Chrome61+ 与 Safari10.1+ 才做到了部分支持。

    不过可以通过Babel这类工具配合相关的plugin(可以参考《Babel笔记》),转换为ES5的语法,这样就可以在Node.js运行起来了,如果想在浏览器上运行,可以添加Babel配置,为模块文件添上AMD的define函数作为外层,再并配合RequireJS之类的加载器即可。

    编译时加载。


    起源地下载网 » js模块化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元