构建基于 NodeJS 的 LESS.js 预编译 CSS 服务

简介: 我们在项目中使用 Less.js 的预编译 css 技术。Less 最终编译的代码是 css,也就是 *.less 输出 *.css 的工作,围绕这项过程的方式方法多种多样,有的是导入 less.js 到页面编译 less(客户端执行),有的是透过构建工具如 Grunt、Glup 生成。

我们在项目中使用 Less.js 的预编译 css 技术。Less 最终编译的代码是 css,也就是 *.less 输出 *.css 的工作,围绕这项过程的方式方法多种多样,有的是导入 less.js 到页面编译 less(客户端执行),有的是透过构建工具如 Grunt、Glup 生成。客户端执行比较耗时而且也有浏览器兼容的问题,故不推荐;构建工具比较流行于前端社区,如果放在 JEE 项目中似乎太重了,不便于 Javaer 学习跟使用。我们想,既然 less 是 js 编写的编译器,其官方也有提供跟 nodejs 对接 npm 包,那干脆通过 nodejs 搭建一个 web 服务器,接收到请求就返回编译好 css 便完事。

页面上通过 link 标签导入 node 运行着的服务,返回由参数所指定的 less 文件-->css 文件。如下例子如是:

<link rel="Stylesheet" type="text/css" href="http://192.168.1.92/lessService/?isdebug=true&ns=C:/work/eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/yuetv_wap/asset/less&lessFile=C:/work/eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/yuetv_wap/asset/less/yuetv_wap.less&picPath=http://localhost:8080/yuetv_wap/asset/images/1/&MainDomain=http://192.168.1.92:8080/yuetv_wap" />

其中 url 如:http://192.168.1.92/lessService/?isdebug=true&ns=C:/work/eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/yuetv_wap/asset/less&lessFile=C:/work/eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/yuetv_wap/asset/less/yuetv_wap.less&picPath=http://localhost:8080/yuetv_wap/asset/images/1/&MainDomain=http://192.168.1.92:8080/yuetv_wap

请求的参数应按如下表传参:

参数名 是否必传 含义
lessFile y LESS 文件位置,就是要解析的 LESS 文件名全称
ns n 参数 ns =namespace 为命名空间之目录名,LESS 会在此目录下自动加入 LESS 而无须加上 目录前缀。通常为项目的 LESS 总目录,该目录下有多个 LESS 文件
picPath n 参数 picPath 是背景图的所在目录。开发阶段和线上的部署阶段的目录会有所不同
isdebug n 参数 isDebug = true 为调试阶段,不压缩 css 输出;当 isDebug = false 时候,压缩输出

通过上述介绍大家应该明白这是一种什么思路了。好接着我们需要一个 nodejs 环境,而且安装 less.js NPM 包。NPM 下载:

npm install less (https://www.npmjs.com/package/less)

OR

下载我提供的 js 包,内置了 less.js 包完整依赖。(稍后提供)

光有包不够,真正把 less 服务暴露到 web 还是下面 js 脚本。下载下面 js。

  • http://git.oschina.net/sp42/ajaxjs/blob/master/nodejs/less-parser.js?dir=0&filepath=nodejs%2Fless-parser.js
  • http://git.oschina.net/sp42/ajaxjs/blob/master/nodejs/lib/step.js?dir=0&filepath=nodejs%2Flib%2Fstep.js
  • http://git.oschina.net/sp42/ajaxjs/blob/master/nodejs/lib/webserver-utils.js?dir=0&filepath=nodejs%2Flib%2Fwebserver-utils.js

首先我们要让 nodejs 跑起 web 服务来,这是 nodejs 强项,仅次于 hello world 用法:

const HTTP = require('http'), less = require('less'), fs = require('fs'), Step = require('./lib/step'), webUtils = require('./lib/webserver-utils');

const port = 80, base_less_folder = 'c:/project/ajaxjs/less',
server = HTTP.createServer((req, res) => {
	init(req, res);
});

server.listen(port, null, () => {
	var host = '';
	console.log(`Image Server running at http://${host}:${port}/`);
});

这里是 80 端口,需要的话就修改吧。还有个 base_less_folder 配置你也可以修改,是关于 less 读取的目录,也就是上述 ns 参数。当前默认有一个,然而可以通过 url 参数陆续添加。

真正处理转换的是 init 函数:

init = function (request, response) {
	console.log('Current Less.js vresion:' + less.version.join('.'));
	
	var _req = webUtils.url2json(request.url),
		lessFile = _req.lessFile,
		ns = _req.ns; // 读取 url 的命名空间


	if (!lessFile) 
		return webUtils.show500error(response, '未发行对应的样式文件!');

	// 指定包空间

	var ns_arr = [
	            base_less_folder
    ];
	
	ns && ns_arr.push(ns);

	// 背景图的路径按 CSS 为基准。但因为 CSS 处于 Node 服务器上,所以要指定到 Tomcat 上才行。

	var assetFilePath = '@assetFilePath: "http://localhost:8080/sport/asset/images";\n';
	var assetFilePath = '@assetFilePath: "' + _req.picPath + '";\n';

	Step(function () {
		console.log('请求 LESS 命名空间:' + lessFile.split('/').pop());
		fs.readFile(lessFile, "utf8", this);
	}, function (err, lessFile) {
		if (err) 
			return webUtils.show500error(response, '未发行对应的样式文件!原因:' + err.toString());
		
		var isDebug = _req.isdebug; // 是否压缩样式 


		
		try {
			less.render(assetFilePath + lessFile, {
				paths: ns_arr,
				compress: (!isDebug || isDebug == 'false')
			}, this);
		} catch (e) {
			return webUtils.show500error(response, 'LESS 解析 less 失败,请检查 LESS 文件是否写错!原因:' + e);
		}
	}, function (err, tree) {
		if (err) 
			return webUtils.show500error(response, 'LESS 解析 less 失败!原因:' + err);
		
		response.writeHead(200, { 'Content-Type': 'text/css; charset=UTF-8' });

		var isDebug = _req.isdebug; // 是否压缩样式


		response.end(tree.css);
		
		if (!isDebug || isDebug == 'false') {}
		else if (isDebug == 'true') { }

		// 总是 localhost/app 后面有一个 app 项目名

		// deployUsed = deployUsed.replace(/http:\/\/localhost:8080\/\w+/i, _req.MainDomain);

		// console.log('--------' + tree);

		console.log('--------' + _req.picPath);
		var deployUsed = tree.css.replace(new RegExp(_req.picPath, 'g'), '../images');

		// 保存文件在父级 css 目录下,save to file

		// toCSS(lessFile.replace(/(.*?\/)(\w+)\.less/, '$1../css/$2.css'), deployUsed);

	});
}

这里使用了 step.js 避免 callback hell 问题和封装了相关 web 的方法。

值得注意的是,这一系列过程都是开发环境用的。如果生成环境就是得 css 读取了。我们的后台会自动识别,如果开发的时候就走 less/node 的,生产环境就 css。

怎么让生产环境读到 css 呢?一个笨方法就是手工 copy 导出的再保存,另外一种方法就是上面脚本 倒数第三行的,自动把得到的 css 保存起来,这样就不用手工拷贝了。

目录
相关文章
|
8天前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
26 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
29天前
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
53 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
1月前
|
人工智能 程序员 UED
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
123 21
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
1月前
html+js+css实现的建筑方块立体数字时钟源码
html+js+css实现的建筑方块立体数字时钟源码
79 33
|
1月前
|
中间件 API
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
这篇文章介绍了作者在使用Nextjs15进行项目开发时遇到的部署问题。在部署过程中,作者遇到了打包构建时的一系列报错,报错内容涉及动态代码评估在Edge运行时不被允许等问题。经过一天的尝试和调整,作者最终删除了lodash-es库,并将radash的部分源码复制到本地,解决了打包报错的问题。文章最后提供了项目的线上预览地址,并欢迎读者留言讨论更好的解决方案。
41 10
|
2月前
一个好看的小时钟html+js+css源码
一个好看的小时钟html+js+css源码
116 24
|
2月前
纸屑飘落生日蛋糕场景js+css3动画特效
纸屑飘落生日蛋糕CSS3动画特效是一款js+css3制作的全屏纸屑飘落,生日蛋糕点亮庆祝动画特效。
59 3
|
2月前
|
存储 JavaScript NoSQL
Node.js新作《循序渐进Node.js企业级开发实践》简介
《循序渐进Node.js企业级开发实践》由清华大学出版社出版,基于Node.js 22.3.0编写,包含26个实战案例和43个上机练习,旨在帮助读者从基础到进阶全面掌握Node.js技术,适用于初学者、进阶开发者及全栈工程师。
78 9
|
2月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
71 12
|
3月前
|
前端开发 测试技术 定位技术
如何利用HTML和CSS构建企业级网站的全过程。从项目概述到页面结构设计,再到HTML结构搭建与CSS样式设计,最后实现具体页面并进行优化提升,全面覆盖了网站开发的关键步骤
本文深入介绍了如何利用HTML和CSS构建企业级网站的全过程。从项目概述到页面结构设计,再到HTML结构搭建与CSS样式设计,最后实现具体页面并进行优化提升,全面覆盖了网站开发的关键步骤。通过实例展示了主页、关于我们、产品展示、新闻动态及联系我们等页面的设计与实现,强调了合理布局、美观设计及用户体验的重要性。旨在为企业打造一个既专业又具吸引力的线上平台。
121 7

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    47
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    Node.js 中实现多任务下载的并发控制策略
    34
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    47
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    57
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    57
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    57