近几年前端工程化越来越完善,打包工具也已经是前端标配了,像seajs这种老古董早已停止维护,而且使用的人估计也几个了。但这并不能阻止好奇的我,为了了解当年的前端前辈们是如何在浏览器进行代码模块化的,我鼓起勇气翻开了Seajs的源码。下面就和我一起细细品味Seajs源码吧。
如何使用seajs
在看Seajs源码之前,先看看Seajs是如何使用的,毕竟刚入行的时候,大家就都使用browserify、webpack之类的东西了,还从来没有用过Seajs。
<!-- 首先在页面中引入sea.js,也可以使用CDN资源 --><script type="text/javascript" src="./sea.js"></script><script>// 设置一些参数seajs.config({ debug: true, // debug为false时,在模块加载完毕后会移除head中的script标签 base: './js/', // 通过路径加载其他模块的默认根目录 alias: { // 别名 jquery: 'https://cdn.bootcss.com/jquery/3.2.1/jquery' }})seajs.use('main', function(main) { alert(main)})</script>//main.jsdefine(function (require, exports, module) { // require('jquery') // var $ = window.$ module.exports = 'main-module'})
seajs的参数配置
首先通过script导入seajs,然后对seajs进行一些配置。seajs的配置参数很多具体不详细介绍,seajs将配置项会存入一个私有对象data中,并且如果之前有设置过某个属性,并且这个属性是数组或者对象,会将新值与旧值进行合并。
(function (global, undefined) { if (global.seajs) { return } var data = seajs.data = {} seajs.config = function (configData) { for (var key in configData) { var curr = configData[key] // 获取当前配置 var prev = data[key] // 获取之前的配置 if (prev && isObject(prev)) { // 如果之前已经设置过,且为一个对象 for (var k in curr) { prev[k] = curr[k] // 用新值覆盖旧值,旧值保留不变 } } else { // 如果之前的值为数组,进行concat if (isArray(prev)) { curr = prev.concat(curr) } // 确保 base 为一个路径 else if (key === "base") { // 必须已 "/" 结尾 if (curr.slice(-1) !== "/") { curr += "/" } curr = addBase(curr) // 转换为绝对路径 } // Set config data[key] = curr } } }})(this);
设置的时候还有个比较特殊的地方,就是base这个属性。这表示所有模块加载的基础路径,所以格式必须为一个路径,并且该路径最后会转换为绝对路径。比如,我的配置为base: './js'
,我当前访问的域名为http://qq.com/web/index.html
,最后base属性会被转化为http://qq.com/web/js/
。然后,所有依赖的模块id都会根据该路径转换为uri,除非有定义其他配置,关于配置点到为止,到用到的地方再来细说。
模块的加载与执行
下面我们调用了use方法,该方法就是用来加载模块的地方,类似与requirejs中的require方法。
新闻热点
疑难解答
图片精选