我的LESS编译方案

背景

近期项目前端决定使用less,简单介绍一下,详细信息有兴趣查看官方文档(http://www.lesscss.net/article/home.html) 

LESSCSS是一种动态样式语言,属于CSS预处理语言的一种,它使用类似CSS的语法,为CSS的赋予了动态语言的特性,如变量、继承、运算、函数等,更方便CSS的编写和维护。 

简单来说,它自定义了一套语法规则,在css中提供公共变量的抽取,简单的函数运算等功能,最终通过编译器或解析器将其编译或解析为相对应的css代码。 

但是LESS文件在何时编译成为一个值得关注的问题,按照常规方式由几种方案

1、前端人员手工将less文件编译为css,并在页面引入css文件

这种方案前端人员工作量会比较大,同时维护less文件和css文件,多人编辑同一个文件时很容易出错,并且多版本并行时合并代码不方便,一点点细微的改动都要重新编译文件

2、页面引入less文件,项目编译时使用插件统一进行预编译

该方案要求所有开发人员都要安装编译环境(nodejs和less),并且文件修改后都要重新编译项目才能看到效果

3、页面引入less文件和js解析文件,在页面上将less解析为css

其实对于互联网项目来说,这种方式基本不会考虑在线上运营,执行效率太低

LESS的两种编译方式

1、页面引入js代码文件解析

首先引入less代码

<link rel="stylesheet/less" href="example.less" />

然后引入解析代码

<script src="lesscss-1.4.0.min.js"></script>

解析代码会根据rel属性类型通过ajax方式拉取less代码,然后并解析成css后追加到页面 

好处:不必安装less编译环境,同样可以使用less文件
缺点:在页面上解析代码,效率较低,受机器、网络影响较大 

2、服务端预编译

官方提供了基于node.js的编译工具lessc 

首先全局安装less

npm install -g less

然后直接使用less编译即可

lessc example/example.less example/example.css
优点:服务端预编译,效率高,避免客户端解析延时。
缺点:需要安装node以及less环境,并且每次修改less后都需要将其编译为css文件方可见效 

方案基本思路

鉴于上述原因,经与前端商量后决定制定一套较为平衡的方案,即:

开发环境使用方式1,不用所有开发人员安装环境,降低开发成本,避免每次修改后都编译

其他环境使用方式2,预编译less文件,提高页面加载速度 

方案概括

1、通过配置文件,添加一个区分开发环境和其他环境的标志位lessOn(比如开发环境为false,其他环境为true) 
2、页面使用自定义标签引入less文件,通过区分lessOn的值来判断引入编译前的less文件还是编译后的css文件 
  这里自定义标签代码就不贴了,举个例子:
  通过自定义标签引入文件"/less/example.less",在输出到页面前判断当前如果是服务器环境将其转为"/css/example.css"  
3、页面全局通过判断lessOn的取值决定是否添加对less.js的引入 
  如果是开发环境则引入官方的js脚本用于页面解析,服务器环境则不引入  
<script src="lesscss-1.4.0.min.js"></script>
4、使用node.js编写工具脚本遍历指定目录、批量编译less文件
var fs = require('fs'),
    path = require('path'),
    exec = require('child_process').exec,
    sourcePath, targetPath;

//获取命令行中的路径
process.argv.forEach(function (val, index, array) {
    if (index == 2) {
        sourcePath = val;
    }
    if (index == 3) {
        targetPath = val;
    }
})

var lessc = function (rootPath, targetPath) {
    //取得当前绝对路径
    rootPath = path.resolve(rootPath);
    //目标路径绝对路径
    targetPath = path.resolve(targetPath);
    //判断目录是否存在
    fs.exists(rootPath, function (exists) {
        //路径存在
        if (exists) {
            //获取当前路径下的所有文件和路径名
            var childArray = fs.readdirSync(rootPath);
            if (childArray.length) {
                for (var i = 0; i < childArray.length; i++) {
                    var currentFilePath = path.resolve(rootPath, childArray[i]);
                    var currentTargetPath = path.resolve(targetPath, childArray[i])
                    //读取文件信息
                    var stats = fs.statSync(currentFilePath);
                    //若是目录则递归调用
                    if (stats.isDirectory()) {
                        lessc(currentFilePath, currentTargetPath);
                    } else {
                        //判断文件是否为less文件
                        if (path.extname(currentFilePath) === ".less") {
                            var newFilePath = path.resolve(targetPath, path.basename(currentFilePath, '.less') + ".css");
                            if (!fs.existsSync(targetPath)) {
                                fs.mkdirSync(targetPath);
                            }
                            console.log(newFilePath);
                            exec("lessc -x " + currentFilePath + " > " + newFilePath);
                        }
                    }
                }
            }
        } else {
            console.log("directory is not exists");
        }
    });
}

lessc(sourcePath, targetPath);
View Code

5、使用maven插件maven-antrun-plugin,在编译打包前执行第4部的脚本预编译less文件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <configration>
                <tasks>
                    <echo>
                        ------------node less-compiler.js-------------
                    </echo>
                    <exec executable="node" dir="${project.basedir}/src/main/webapp/assets/less" failonerror="true">
                        <arg line="less-compiler.js  ${project.basedir}/src/main/webapp/assets/less 
                    ${project.basedir}/src/main/webapp/assets/css"
/> </exec> <echo> ------------compiler success----------------- </echo> </tasks> </configration> <goals>run</goals> </execution> </executions> </plugin>

 总结

思路其实很简单,通过区分项目运行环境,兼得两种编译方式的优点

任何工具都不应当直接拿来使用,通过合适的定制使其更加适合自身项目开发

posted @ 2013-08-07 10:22  逆风之羽  阅读(5562)  评论(2编辑  收藏  举报