设为首页 收藏本站
查看: 976|回复: 0

[经验分享] 打包并压缩seajs代码

[复制链接]

尚未签到

发表于 2017-2-23 10:31:18 | 显示全部楼层 |阅读模式
背景
    seajs是一款优秀的模块开发插件,但是当我们使用它来进行模块化开发的时候,由于它的每个模块的加载都会进行一次http请求,那么当模块数量倍增的时候,会拖慢页面的加载速度。

    通常我们为了能加快页面的加载速度,都会对js进行压缩并把关联的模块打包为一个独立的js文件,这样可以大大减少js的文件大小并且减少http请求的次数,这样可以提升到页面的加载速度。
    我们可以是用spm来对js文件进行打包、压缩(使用spm-build),但是当我们编写兼容多种环境的js的时候(既可以直接用script引用又可以使用seajs来引用),那么我们就没办法使用前面的方法来对js进行打包和压缩了。
    其次就是使用spm-build还要先了解package.json文件配置,还是有少许麻烦的,为了减轻上手的难度和简化功能,这里我们将介绍另类的使用nodejs来对js脚本进行压缩。
实现
    http://tool.css-js.com/站点提供了多种脚本压缩,通过使用YUI压缩,我们发现它实际上是使用http的POST来实现代码压缩的,如图:
     DSC0000.jpg
    接着我们使用ajax来进行测试,代码如下:

$.post('http://tool.css-js.com/!java/?type=js&munge=true&preserveAllSemiColons=false&disableOptimizations=false', {
code: 'var x = (function() { var foo = 1,  bar = 2; return (foo + bar) }())'
}, function(res){
console.log(res);
});

    结果跟截图的效果是相同的,接下来使用nodejs来编写一个用于读取js文件并发起http然后把压缩的拼接到一个独立的js文件中去。
    使用原生的nodejs的http来发起post的代码如下:

var m_http = require('http');
var m_qs = require('querystring');
var options = {
host: 'tool.css-js.com',
port: 80,
method: 'POST',
path: '/!java/?type=js&munge=true&preserveAllSemiColons=false&disableOptimizations=false',
headers: {
'Content-Type':'application/x-www-form-urlencoded'
}
};
exports.compress = function (str, callback){
var req = m_http.request(options, function(res) {
res.setEncoding('utf-8');
var compressed = '';
res.on('data', function(chunk){
compressed += chunk;
});
res.on('end', function(){
callback(compressed)
});
});
req.write(m_qs.stringify({ code: str }));
req.end();
};

     有了压缩的方法,接下来我们需要提供一个可以循环读取文件夹内的所有js文件并压缩合并到独立的js文件的函数,代码大致如下:

var m_fs = require('fs');
var m_path = require('path');
//其他代码略
exports.combineDir = function (dir, output){
var self = this;
m_fs.readdirSync(dir).forEach(function (filename) {
if (filename.indexOf('.') === -1) {
self.compressDir(m_path.join(dir, filename));
return;
}
var path = m_path.join(dir, filename);
m_fs.readFile(path, 'utf8', function (err, content){
if (err) {
return;
}
self.compress(content, function (compressed){
var id = filename.substr(0, filename.indexOf('.'));
compressed = compressed.replace('this.define(', ['this.define(\'', id, '\','].join(''));
m_fs.appendFileSync(output, compressed);
});
});
});
};                                                                                                      

    以上代码之所以要替换'this.define'字符串是因为我们编写的兼容脚本中,会使用闭包将脚本包含在内部,并在内部对this.define进行判断,当this.define存在的情况下,才会将编码的模块赋值给module.exports来完成模块,示例代码如下:

//a.js
(function(){
var a = (function() { var foo = 1,  bar = 2; return (foo + bar) }())
if (this.define) {
this.define(function (require, exports, module) {
'require:nomunge,exports:nomunge,module:nomunge';
module.exports = a;
});
}
}).call(this);
//b.js
(function(){
var b = (function() { var foo = 1,  bar = 2; return (foo + bar) }())
if (this.define) {
this.define(function (require, exports, module) {
'require:nomunge,exports:nomunge,module:nomunge';
module.exports = a;
});
}
}).call(this);
    使用编码好的函数来进行合并后,结果如下:

(function(){var b=(function(){var c=1,a=2;return(c+a)}());if(this.define){this.define('a',function(require,exports,module){module.exports=b})}}).call(this);
(function(){var c=(function(){var d=1,b=2;return(d+b)}());if(this.define){this.define('b',function(require,exports,module){module.exports=a})}}).call(this);

扩展
    对于创建请求,我们可以使用nodegrass来完成我们的功能,它内部封装了http和https的get、post的函数,简化了调用,大家可以使用看看。
    其次对于循环文件夹内的js文件,当存在多层嵌套的时候,由于没有将父级文件夹添加到seajs定义的id内,因此调用合并后的js文件的时候,会出现错误,这里就不详细解说如何解决了,这个问题就留给大家去解决啦。
    对于以上代码由于使用了异步方法,造成了多层文件嵌套,如果大家觉得嵌套太多导致代码难看、难以阅读,可以使用wind.js或者eventproxy.js或者其他的异步js来解决多层嵌套的问题。

结尾
    这次的文章就到这里了,内容中有任何问题不吝赐教,谢谢各位!
    另外感谢http://tool.css-js.com/站点提供的功能.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346090-1-1.html 上篇帖子: 社区网站系统 jsGen 下篇帖子: 打包并压缩seajs代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表