個人LESS編譯方案

背景

近期項目前端決定使用less,簡單介紹一下,詳細信息有興趣查看官方文檔(http://www.lesscss.net/article/home.html) css

LESSCSS是一種動態樣式語言,屬於CSS預處理語言的一種,它使用相似CSS的語法,爲CSS的賦予了動態語言的特性,如變量、繼承、運算、函數等,更方便CSS的編寫和維護。 html

簡單來講,它自定義了一套語法規則,在css中提供公共變量的抽取,簡單的函數運算等功能,最終經過編譯器或解析器將其編譯或解析爲相對應的css代碼。 前端

可是LESS文件在什麼時候編譯成爲一個值得關注的問題,按照常規方式由幾種方案node

一、前端人員手工將less文件編譯爲css,並在頁面引入css文件

這種方案前端人員工做量會比較大,同時維護less文件和css文件,多人編輯同一個文件時很容易出錯,而且多版本並行時合併代碼不方便,一點點細微的改動都要從新編譯文件web

二、頁面引入less文件,項目編譯時使用插件統一進行預編譯

該方案要求全部開發人員都要安裝編譯環境(nodejs和less),而且文件修改後都要從新編譯項目才能看到效果ajax

三、頁面引入less文件和js解析文件,在頁面上將less解析爲css

其實對於互聯網項目來講,這種方式基本不會考慮在線上運營,執行效率過低apache

LESS的兩種編譯方式

一、頁面引入js代碼文件解析

首先引入less代碼npm

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

而後引入解析代碼服務器

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

解析代碼會根據rel屬性類型經過ajax方式拉取less代碼,而後並解析成css後追加到頁面 網絡

好處:沒必要安裝less編譯環境,一樣可使用less文件
缺點:在頁面上解析代碼,效率較低,受機器、網絡影響較大 

二、服務端預編譯

官方提供了基於node.js的編譯工具lessc 

首先全局安裝less

npm install -g less

而後直接使用less編譯便可

lessc example/example.less example/example.css
優勢:服務端預編譯,效率高,避免客戶端解析延時。
缺點:須要安裝node以及less環境,而且每次修改less後都須要將其編譯爲css文件方可見效 

方案基本思路

鑑於上述緣由,經與前端商量後決定製定一套較爲平衡的方案,即:

開發環境使用方式1,不用全部開發人員安裝環境,下降開發成本,避免每次修改後都編譯

其餘環境使用方式2,預編譯less文件,提升頁面加載速度 

方案歸納

一、經過配置文件,添加一個區分開發環境和其餘環境的標誌位lessOn(好比開發環境爲false,其餘環境爲true) 
二、頁面使用自定義標籤引入less文件,經過區分lessOn的值來判斷引入編譯前的less文件仍是編譯後的css文件 
  這裏自定義標籤代碼就不貼了,舉個例子:
  經過自定義標籤引入文件"/less/example.less",在輸出到頁面前判斷當前若是是服務器環境將其轉爲"/css/example.css"  
三、頁面全局經過判斷lessOn的取值決定是否添加對less.js的引入 
  若是是開發環境則引入官方的js腳本用於頁面解析,服務器環境則不引入  
<script src="lesscss-1.4.0.min.js"></script>
四、使用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

五、使用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>

 總結

思路其實很簡單,經過區分項目運行環境,兼得兩種編譯方式的優勢

任何工具都不該當直接拿來使用,經過合適的定製使其更加適合自身項目開發

相關文章
相關標籤/搜索