引子:



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



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 测试运行状态

最终

再次测试压缩一个23k js:

调用tool.css-js.com/compressor.html接口大概要270毫秒

后台代码压缩需要140毫秒

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

后端自动构建前端css和js的更多相关文章

  1. Gulp自动构建前端开发一体化

    gulp是基于Nodejs的自动任务运行器, 她能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试.检查.合并.压缩.格式化.浏览器自 ...

  2. jenkins自动构建前端项目(window,vue)

    我们把一个多人协作的vue前端项目发布服务器,一般要经过以下步骤: git更新最新的代码 构建项目 把构建后的代码上传到服务器 如果用jenkins来构建的话,只需要点击一次构建按钮,就可以自动完成以 ...

  3. 前后端分离--构建前端Mock Server--windows部署rap

    mock:模拟的,虚假的 mock server:模拟服务,模拟请求,模拟虚假数据 为了前后端更好的分工,接口文档是必须的,前后端都根据接口文档写代码,然后对接接口就行了. 但是,后端跟不上前端节奏, ...

  4. gulp自动刷新和css、js压缩

    之前搭建过Grunt,但是用起来有点繁琐,后来有人跟我说gulp更多简单.所以今天又搭建一个gulp.在使用gulp前应该有nodeJs环境,安装完nodejs后,就可以开始gulp的搭建了. 先新建 ...

  5. PHP为前端CSS和JS增加时间戳版本号

    一.PHP代码如下: function addVersion($url){ $version = date("Y-m-d H:i:s",filemtime($_SERVER['DO ...

  6. [后端人员耍前端系列]AngularJs篇:使用AngularJs打造一个简易权限系统

    一.引言 上一篇博文已经向大家介绍了AngularJS核心的一些知识点,在这篇博文将介绍如何把AngularJs应用到实际项目中.本篇博文将使用AngularJS来打造一个简易的权限管理系统.下面不多 ...

  7. ispriter自动构建css-sprite

    优化你的网站: 当一个网站中的资源(比如:js文件.css文件.图片等)很多时必然影响用户访问速度,这时候你就需要做网站性能优化,你可以选择把资源分开放在不同的服务器上,因为一个资源服务器最多可以同时 ...

  8. 处理ios webview 更新缓存本地css、js后webview缓存无法更新的问题

    项目中需要使用app本地css.js,并且可以根据服务下发自动更新本地css.js.测试发现只要更新后的css或者js和更新前路径一致,webview加载的还是更新前的css.js.怀疑是webvie ...

  9. 使用webpack+vue.js构建前端工程化

    参考文章:https://blog.csdn.net/qq_40208605/article/details/80661572 使用webpack+vue.js构建前端工程化本篇主要介绍三块知识点: ...

随机推荐

  1. Asp.Net Core Docker镜像更新系统从wheezy改为stretch

    之前写过一个在Asp.Net Core里调用System.Drawing.Common绘图的DEMO,部署到Docker里运行,需要更新Asp.Net Core镜像的操作系统. https://www ...

  2. 在Windows上安装Gradle

    1.开发环境 (1)Java:JDK8(必须是JDK或JRE7以上,使用java -version查看当前电脑java版本) (2)操作系统:Windows 7 2.安装步骤 (1)下载最新的Grad ...

  3. Mysql使用优化之处(转)

    1 开启事务之前需要rollback 连接句柄.(清理垃圾)2 mysql_ping 失败,程序需要处理重连逻辑:3 mysql_query()执行的SQL语句是一个以‘/0’结尾的字符串,而mysq ...

  4. 如何使用 Azure PowerShell 在 Azure Marketplace 中查找 Windows VM 映像

    本主题介绍如何使用 Azure PowerShell 在 Azure Marketplace 中查找 VM 映像. 创建 Windows VM 时使用此信息来指定 Marketplace 映像. 确保 ...

  5. python自学——列表

    #以下是我自己在联系列表中所编写的语句:names=["zangsan",'lisi','wangermazi','Xiaoliuzi','dabiaoge','牛erbiaodi ...

  6. jdk1.8配置环境变量

    1. 准备好jdk安装文件,选择地址,假设使用默认地址 2. 安装jdk,此时跳出安装 jre 的地址 3. 等待安装 4.找到安装路径,选择jdk 5. 复制文件夹下的bin 6. 点击我的电脑右键 ...

  7. 高通LCD的pwm背光驱动

    发生异常的现象: msm8953 lcd在快速亮灭的情况下背光概率性休眠不灭:测量高通pwm,发现正常的时候pwm的管脚LCM_BL_PWM为低电平,失败的时候为高电平: 根据原理图: mpp是什么? ...

  8. 【Weex学习】环境搭建

    教程来源:http://jspang.com/2017/07/12/weex/,我本地是第一次安装Android Studio和教程有些出入 一.软件安装 1.安装Node.js 2.安装Java(h ...

  9. PHP 与 YAML

    PHP 与 YAML 这一段时间都没有写blog,并不是因为事情多,而是自己变懒了.看到新技术也不愿意深入思考其背后的原理,学习C++语言了近一个多月,由于学习方法有问题,并没有什么项目可以练手.靠每 ...

  10. VS创建工程出错解决方案

    今天在用VS2010创建工程时出现错误:“ 此模板尝试加载组件程序集 “NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, Pu ...