构建基于 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 保存起来,这样就不用手工拷贝了。

目录
相关文章
|
9月前
|
JavaScript 前端开发 物联网
JavaScript:构建动态世界的引擎
JavaScript:构建动态世界的引擎
|
9月前
|
前端开发 JavaScript 开发者
JavaScript:构建动态网络的引擎
JavaScript:构建动态网络的引擎
|
9月前
|
前端开发 JavaScript 开发者
JavaScript:构建动态Web的核心力量
JavaScript:构建动态Web的核心力量
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
9月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
前端开发 搜索推荐 JavaScript
如何通过DIY.JS快速构建出一个DIY手机壳、T恤的应用?
DIY.JS 是一款基于原生 Canvas 的业务级图形库,专注于商品定制的图形交互功能,帮助开发者轻松实现个性化设计。适用于 T 恤、手机壳等多种商品场景。它自带丰富功能,无需从零构建,快速集成到项目中。通过创建舞台、添加模型、定义 DIY 区域和添加素材四个步骤即可完成基础用法。支持在线演示体验,文档详细,易上手。
640 57
|
12月前
|
存储 前端开发 JavaScript
仿真银行app下载安装, 银行卡虚拟余额制作app,用html+css+js实现逼真娱乐工具
这是一个简单的银行账户模拟器项目,用于学习前端开发基础。用户可进行存款、取款操作,所有数据存储于浏览器内存中
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
1345 9
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

  • 1
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    513
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    398
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    395
  • 4
    (CSS)使用Flex布局,帮助你快速了解各种基本的Flex布局属性以及帮你让元素快速达到布局中的指定位置!
    257
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    509
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    681
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1213
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    272
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1009
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    471