Liferay前端非侵入式开发(完结)

时间:2015-06-1 作者:剧中人

马上就要离开贝尔 CDC 项目组了,这里整理下这一年工作中,个人在前端方面对 Liferay 使用的一点儿经验,作为阶段性工作的总结,也供使用此框架的朋友参考。上一篇介绍

Liferay Theme 相关介绍

Liferay 的 Theme 不仅仅是样式视图的集合,自身也完成了代码压缩合并的功能,项目中只使用一个经过压缩合并后的主 CSS。因为 Liferay 本身是一款 CMS 框架,Theme 自带了一套的基础代码,其结构有点儿类似于 sass、less 的文件管理。Theme 采用文件覆写机制,不推荐直接修改源代码,而是在_diffs目录下建立需要修改的对应目录、文件名进行操作。

目录结构如下图所示。 Liferay theme folder

为什么放弃本地开发?

本地开发在后端人员的工作模式中优势还是蛮大的,但在一个已经成型的大型项目面前,前端开发的工作变得比较特殊,在这种情况下,放弃本地开发可能会获得更大的优势。

这么做有哪儿些好处?

使用新的工作方式之后,Java 环境无需启动,Tomcat 也从电脑上删除了,就连项目目录也只保留了 Theme 部分。开发过程变成了启动 Fiddler,启动工具脚本(写了个 bat 文件,双击即可)。接下来就可以自由的徜徉在代码的海洋里,无需为 build、deploy 费神。

怎么做呢?

我这里用到的工具主要有两个

Fidder:前端利器,WEB开发必备工具之一

nodeJS:本地文件查找合并的脚本语言,用来弥补 Fiddler 逻辑上无法完成的部分

使用 Fiddler 的 AutoResponder 功能,可以以假乱真地替换线上文件。通过 AutoResponder 来响应 CSS、JS 的请求,即可起到前端的调试作用。

Liferay theme folder

Fiddler 上的工作量,主要就是去配置需要用本地文件去替换的URL。其实也不多,唯一麻烦点儿的是项目主 CSS ,需要本地去模拟 Liferay 的覆写机制以及代码合并功能。这里我使用 NodeJS 监听 Theme 目录下任意 CSS 的改动,若有改动则执行下面动作:

这里的新文件,即是需要用到的主 CSS。生成出一个可以替代服务器上对应的CSS文件,而且未经压缩,更容易排查问题。接下来的任务就交给伟大的Fiddler,在AutoResponder里配置好服务器和本地的CSS路径,即可安心的敲自己的代码。

由于 Liferay 自身处理了版本控制,所以每次服务器上做和 Theme 相关的的部署,都会引起CSS路径的变化,为了避免频繁的 AutoResponder 配置,直接用正则模式匹配regex:.+/SCPortal-theme/css/main.css?.+

打磨成形的工具脚本

其实脚本很简单,就是模拟 Liferay 对 Theme 的处理逻辑,合并生成出新的文件。当然,这里使用了fswatch方法进行监听变动。

var fs = require('fs');
//获取文本内容
function getTxt(src){
    return fs.readFileSync(src,'utf-8');
}
//写文件
function write(src,str){
    fs.writeFileSync(src,str);
}
//文件是否存在
function hasFile(src){
    return fs.existsSync(src);
}
//创建文件
function createFile(projectDir,outputFilePath){
    console.log('\n\nget main css!\n');
    //获取主文件
    var mainTXT = getTxt(projectDir + 'css/main.css');
    var outoutString = '';
    //遍历需要合并的文件
    mainTXT.replace(/\@\i\m\p\ort\s\ur\l\((.+)?\)/g,function(a,b){

        outoutString += '\r\n/*------ concat start from ' + b + ' ------*/\r\n';
        if(hasFile(projectDir + '_diffs/css/' + b)){
            //在_diffs目录下查找
            console.log('  ' + b + '  > diffs');
            outoutString += getTxt(projectDir + '_diffs/css/' + b);
        }else{
            //进入主目录查找
            console.log('  ' + b);
            outoutString += getTxt(projectDir + 'css/' + b);
        }
        outoutString += '\r\n/*------ concat over from ' + b + ' ------*/\r\n';

        return a;
    });
    console.log('\nwrite css');
    //写入合并后的文件
    write(outputFilePath,outoutString);
    console.log('\nwork end !');
};
module.exports = function(projectDir,outputFilePath){
    console.log('\nstart watch project');
    projectDir = projectDir.replace(/\/$/,'') + '/';
    //监听目录改动
    fs.watch(projectDir + '_diffs/css/',function(type,file){
        console.log('\n\n' + file + ' changed' + new Date());
        createFile(projectDir,outputFilePath);
    });
    createFile(projectDir,outputFilePath);
};

项目中调用工具

因为项目不止一个,这里把配置单独拎了出来。

//引用工具文件
var concatTool = require('./concat.js');
//配置目录
var config = {
    mainPath : 'D:/workspace/xxxx/docroot/',
    outputPath : 'D:/autoresponder/xxxx/main.css'
};
//启动工具
concatTool(config.mainPath,config.outputPath);

PS: 不管未来如何,这一年的工作经历将是我一笔宝贵的财富。感谢一年来领导、同事们的关照,特别感谢东方龙马 [drupalchina 创始人 ] 在工作中的支持和帮助,谢谢。