背景
JavaScript模块加载器很多人都知道,市面上比较流畅的Require.JS、SeaJS,就算没用过,也听过。模块加载器又分为同步、异步两类,现在貌似用的比较多的方式是异步。
预习功课
浅谈 JavaScript 模块化编程
前端模块化开发的价值
浏览器端多使用SeaJs辅助开发,所有,很多内容都是与SeaJs有关,不过,都是大同小异的。
选择哪个模块加载器,看个人喜好、适应能力,先找官网、教程,照着撸一遍就好了,先学会使用,再学习使用好它,然后可以研究它是怎么倒腾出来的了。
简单使用SeaJs
先简单上手SeaJs。
|-- demo
|--|--| lib
|--|--|-- sea.js
|--|--|-- utils.js
|--|--| modules
|--|--|-- demo.js
|-- demo.html
一个简单的项目目录。
<script src="./lib/sea.js"></script>
<script>
seajs.use('./modules/demo')
</script>
内容很简单,在页面上把我们依赖的SeaJs引入,然后使用SeaJs提供的接口把一个模块加载进来。
// utils.js
define(function(require, exports, module) {
exports.doPrintA = function() {
console.log('A')
}
})
// demo.js
define(function(require, exports, module) {
var utils = require('../lib/utils')
utils.doPrintA()
})
如果在浏览器打开页面,并且打开控制台,控制台就会出现 A ,嗯,就是这么简单。只要在demo.js(即页面引入的模块的文件)按照以前的方式写代码,就好了。
浅析
每个define里面的匿名函数就是一个模块,通常一个文件一个模块,当然,可也以一个文件多个模块,通过一些id标记。通常都是先一个文件一个模块写好,在通过打包工具合并文件。
在模块里,通过require引入其他模块,并且执行内部的代码,exports、module都是向外部暴露接口。
使用好SeaSj
以前做项目,文件夹都分的很简单,例如style里面就是css文件,img就是图片,js就是各种js代码。写一个页面,可能会引用多个文件,页面上一排script。现在使用上了模块加载器,各种文件夹都要细分一下。
|-- js
|--|-- lib
|--|-- common
|--|-- modules
例如上面这,js文件里面大体分为三部分,lib里面第三方公共库,common里面放本羡慕会用到的公共模块,modules里面就是每个页面具体业务的模块。
配合上seajs的配置文件,就可以更好玩了。
例如,require某个模块的时候,路径很长,还容易写错层级关系。
// 简单上手 案例
seajs.config({
alias: { 'utils': './lib/utils' }
})
// 在demo.js中可以直接这样,无论层级如何复杂,都可以简单的引入模块
var utils = require('utils')
更多配置玩法,可以参考Seajs 提供简单、极致的模块化开发体验
简单看看SeaJs如何运行的
<script src="./lib/sea.js"></script>
<script>
seajs.use('./modules/demo')
</script>
通常我们是这样使用,那么在浏览器加载到这里的时候,发送了什么。
首先加载sea.js,代码在window对象写入seajs、define,然后在使用seajs加载对应的模块。
在加载模块前,可能我们会对seajs进行一些配置操作,例如设置别名、路径等。seajs内部构建一个完整的引用路径,以及别名路径,和其他设置。
seajs.use 通过识别传入的变量,加上够不构建的路径,拼接上一个完整的文件引入路径。同时,针对 .js
的优化(缺失值补充?),在引入模块时,可以不写后缀名。在加载文件前,对比当前已加载模块队列,判断是否已加载,避免重复加载文件。创建一个script标签,把src熟悉修改为文件路径,添加到body的底部,动态引入一个js文件,文件加载好后,把模块对应的模块ID(或者是模块路径)添加到已加载队列中。
第一个模块加载好了,那么require引入的模块怎么玩呢,define函数传入一个匿名函数,通过内部的一些操作,具体的我也不清楚,找到require的地方,通过相似的方式加载模块,并且正确的在内部把模块返回的值赋值给变量。
嗯,大致就是这样的吧。
转载请注明:OnlyLing - Web 前端开发者 » 简单说说SeaJs是怎么玩的