后端自动构建前端css和js

service.js

引子:

别的复杂前端开发技术不会,用得多的还是手写代码,手动处理。

3年前手写合并压缩js和css文件的asp脚本代码目前还能正常运行,也就没有多大使用别的技术的动力。

直到近期被一个问题纠结着,今天花了一天时间摸索完成了一个后端构建功能。

目前接触到的项目前端开发模式基本上是一样的

  1. 项目不会很大
  2. 通用css、js、第三方库会独立成单个文件
  3. 页面依赖的多个文件会合并成一个css或js文件,并进行自定义语法编译和压缩混淆
  4. 多个页面会用到的但不够通用的会独立成一个html文件,内嵌style、script标签,服务器端后端运行时包含进来
  5. 页面使用的js、css完全内嵌style、script标签(无法抗拒的优点:打开一个文件就能看到所有源代码)
  6. 晓得这种模式很low,不过好用

了解到的前端构建方式

针对2、3项,跟目前看到的前端自动化构建工具,比如:webpack、gulp,其实处理思想上还是比较吻合,压缩混淆实现是调用的一个压缩js和css网站的接口tool.css-js.com/compressor.html

针对4、5项这种内嵌的style和script,以前是没有任何处理,一个月前特意加上了压缩混淆功能。实现方式是开发阶段完成相关文件的压缩混淆:压缩混淆是只要页面一运行,相关前端代码后端会自动化处理;然后手动上传结果到服务器。如果源码有改动,必须重新压缩混淆和上传文件(自己写的后台工具是这样的规则)。

最近就是被如果源码有改动,必须重新压缩混淆和上传文件这个问题困扰着,一个是操作复杂,致命的是:如果漏上传了混淆后的文件。。。

好,现在知道目前采用的压缩混淆方式了:编写前端代码,后端代码自动处理生成新的压缩混淆后的代码。

前奏

既然后端已经有压缩混淆功能了,那么还要这么复杂的操作流程就多余了。为什么不扔到服务器上自动处理?是考虑到第三方网站接口的稳定性,如果他们挂了,至少不影响线上功能(他们确实经常挂)。

问题出在第三方压缩混淆接口上,那把功能本地化不就稳定了,没毛病是这个逻辑。

昨天想了一下,如果要本地实现压缩混淆css和js,涉及的代码有点多,就放弃了。

今天上午又想了一下,如果不提前搞好,光生成出来的文件就一大堆,而且本质是次要的生成文件,提交svn的时候还要特殊对待,不提交又会导致新检出项目可能丢失文件,提交的话又算是垃圾文件。还要上传,如果是差异更新就有的对比了。必须动手了。

进行时

要压缩css,有很多办法:正则替换空白,不过复杂css格式去掉空白后语义是不是一致就难说了;用现成的工具,甚至可以带来更好的开发方式的lesssass,最终采用了less,看别人说的sass比less更好,不过要额外学和安装Ruby起点比less高了许多;最终采用less方案。

压缩js,uglifyjs不二选择。

安装node模块

cnpm install -g ing...

目前最新版本less 3.0.1压缩css遇到问题:The compress option has been deprecated -x新版本选项不能用了,得知装上less-plugin-clean-css--clean-css命令可以进行压缩。
好吧装上less-plugin-clean-css 1.5.1,Unable to load plugin clean-css please make sure that it is installed识别不到么,到less-plugin-clean-css看到一个issusehttps://github.com/less/less-plugin-clean-css/issues/24说是要降级到2.x。
cnpm show less versions 查询到less 2.x最高版本2.7.3,装上压缩成功。

uglifyjs 3.3.16最新版,装上就能压缩混淆,研究了一下参数,提供-m -c两个参数就足够了,-m混淆变量名,-c压缩优化代码。

后端代码接入和运行测试

后端接入方式和控制台敲命令行是一样的,通过cmd调用less 或 uglifyjs进行处理文件代码,接入进来很快的。

测试啦:win7环境

测试打开新页面速度:
比以前慢5、6倍

测试压缩一个23k js:
调用tool.css-js.com/compressor.html接口大概要270毫秒
后台代码压缩需要580毫秒

测试后台代码执行uglifyjs -V:需要350多毫秒
测试后台代码执行echo 123:需要0毫秒

测试分析:
实际压缩混淆速度580-350=230毫秒,和第三方接口出入不大。
cmd调用速度0毫秒也可以忽略。
那就是启动uglifyjs而外占用了350毫秒,猜了一下,每次启动压缩混淆都会重新启动node,然后初始化uglifyjs,所以导致巨慢,大文件还好,小文件就不得了,调用第三方接口40毫秒搞定的时,后台代码至少要400毫秒起步。从而导致了页面打开速度变慢很多倍。
基本上页面上的script和style都是小的片段,这个速度不能接受。

优化

虽然已经能够实现压缩混淆了,但是压缩必须经过启动速度巨慢这个问题不能接受。

既然是node和模块启动的问题导致的,那么将所有的压缩混淆共用一次启动过程不就解决了?是这样的。

怎么共用?用cmd肯定复杂了,直接上node,启动和初始化所有模块后等着命令的输入,然后进行压缩混淆,然后继续接受命令,往复循环。

如此方式用http server最合适不过了,启动和初始化所有模块,等待http请求,一有请求就马上处理并返回结果。

上code:

package.json里面的模块依赖:

{
  "name": "node_server",
  "version": "1.0.0",
  "main": "server.js",
  "dependencies": {
    "uglify-js": "3.3.16",
    "less": "2.7.3",
    "less-plugin-clean-css": "1.5.1"
  }
}

server.js node程序启动代码,特意只监听127.0.0.1省的配置防火墙

var http = require('http');
var querystring = require('querystring');

var UglifyJS = require("uglify-js");
var less = require('less');
var cleanCss = require("less-plugin-clean-css");

http.createServer(function (req, rep) {
    var ctx={c:0,m:"",v:""};
    
    var post = '';
    req.on('data', function(chunk){
        post += chunk;
    });
    req.on('end', function(){
        (async function(){
            try{
                var params = querystring.parse(post);
            
                var path0=(/^\/([^\/]+)/.exec(req.url)||[])[1]||"";
                if(path0=="test"){
                    ctx.v="test";
                }else if(path0=="buildcss"){
                    ctx.v=await BuildCss(params);
                }else if(path0=="buildjs"){
                    ctx.v=await BuildJs(params);
                };
            }catch(e){
                ctx.c=1;
                ctx.m="执行出错:"+e.stack;
            };
            try{
                var sendData=JSON.stringify(ctx);
            }catch(e){
                ctx={c:1,m:"返回数据失败:"+e.stack};
                sendData=JSON.stringify(ctx);
            }
            
            rep.writeHead(200, {'Content-Type': 'text/json; charset=utf-8'});
            rep.end(sendData);
        })();
    });
}).listen(8004,"127.0.0.1");







function BuildCss(params){
    return new Promise(function (resolve, reject) {
        less.render(params.code||"", { plugins: [new cleanCss({advanced: true})] })
        .then(function(output) {
            resolve(output.css);
        },function(e) {
            reject(new Error(e.message));
        });
    });
};
function BuildJs(params){
    return new Promise(function (resolve, reject) {
        var res=UglifyJS.minify(params.code||"");
        if(res.error){
            reject(res.error);
        }else{
            resolve(res.code);
        };
    });
};

提供接口地址:
http://127.0.0.1:8004/test 程序运行状态测试
http://127.0.0.1:8004/buildcss post code=css代码 编译css
http://127.0.0.1:8004/buildjs post code=js代码 编译js

接口返回结果
{c:0,m"错误消息",v:"没有错误时返回的结果"},c为状态码,如果出错c!=0,并提供错误消息,没有错误时v有值。

如何运行

没有怎么用node和npm,经验不足,不过还是能跑起来:

  1. 安装node
  2. 安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org npm太慢了
  3. 文件夹内新建package.json,把代码copy进去
  4. 文件夹内新建server.js,把代码copy进去
  5. 文件夹这个目录上下文内执行cmd命令cnpm install,自动下载依赖模块
  6. npm start 启动
  7. 浏览器内输入http://127.0.0.1:8004/test 测试运行状态
已经install过的,启动正常
服务已经在运行

最终

再次测试压缩一个23k js:
调用tool.css-js.com/compressor.html接口大概要270毫秒
后台代码压缩需要140毫秒

比第三方接口还要快,估计是新版本的原因吧,(不要看网速影响,最多影响10ms就不错了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容