目录
一、背景:
项目使用差异化管理,一个项目里面有多个产品形态的项目。公用组件和其他公共代码,只有业务模块进行分离。
在加载的时候使用懒加载。
二、问题:
在执行编译时,由于在路由中配置了懒加载,在打包时会把其他产品形态业务代码也打进去。
三、解决思路:
在编译时,使用nodejs读取自己的路由模块,将这部分代码读出来,把不是自己业务模块的代码删除掉,之后再执行编译命令。当编译完成后再讲原始内容些人路由模块。
- 使用nodejs处理编译前处理以及编译后的重写处理
#!/usr/bin/env node
'use strict';
/**
* 拿到当前路径
* @type {string}
*/
var path = process.cwd();
if (path.indexOf('chubao') > 0) {
path = path.replace('chubao', '');
}
/**
* 拿到文件对象
* @type {"fs"}
*/
const fs = require('fs');
/**
* 获取文件路径
* @param _path
* @returns {string}
*/
function getFilePath(_path) {
return _path.startsWith('/') ? path + _path : path + '/' + _path;
}
/**
*
* @param _path
* @returns {{data: *, dataNoPostil}}
*/
function filterPostil(_path){
const filePath = getFilePath(_path);
const fileData = fs.readFileSync(filePath, 'utf-8');
const fileDataNoPostil = fileData.replace(/(\/\*(\s|.)*?\*\/)|(\/\/[^\n]*)/g, '');
fs.writeFileSync(filePath, fileDataNoPostil);
return {
data: fileData,
dataNoPostil: fileDataNoPostil
}
}
/**
* 写入文件内容
* @param _path
* @param data
*/
function writeFile(_path, data) {
const filePath = getFilePath(_path);
fs.writeFileSync(filePath, data);
}
const routesUrl = '/src/app/routes/routes.module.ts';
const routingUrl = '/src/app/routes/routes-routing.module.ts';
var routingData;
/**
* 处理routes-routing.module配置冗余内容
*/
function filterRoutingCfg(product) {
routingData = filterPostil(routingUrl);
/**
* routes-routing.module 里面需要处理的字符串 已经经过截取了
*/
var routingDataNoPostil = routingData.dataNoPostil;
const routesStr = routingDataNoPostil.split('const CHILDREN = ')[1].split('const routes: Routes')[0];
const routesStrArr = routesStr.match(/\{(\s|.)*?(\]\},)/g);
const len = routesStrArr.length;
for (var i = 0; i < len; i++) {
const item = routesStrArr[i];
const name = item.match(/\{name(\s|.)*?(\},)/g);
const nameLen = name.length;
for (var j = 0; j < nameLen; j++) {
const itemName = name[j];
if (itemName.toLowerCase().indexOf(product.toLowerCase()) > 0) {
} else {
routingDataNoPostil = routingDataNoPostil.replace(item, '');
}
}
}
/**
* 将处理过的内容填充回去
*/
writeFile(routingUrl, routingDataNoPostil);
}
var routesData;
function filterRoutesCfg(product) {
/**
* 拿到处理后的数据
*/
routesData = filterPostil(routesUrl);
/**
* 这是清除注释后的数据
*/
var routesDataNoPostil = routesData.dataNoPostil;
/**
* 截取关键数组
*/
const HoemModule = routesDataNoPostil.split('const HoemModule')[1];
if (HoemModule) {
var routesStr = HoemModule.split('];')[0];
var routesStrCache = routesDataNoPostil.split('const HoemModule')[1].split('];')[0];
const routesStrArr = routesStr.split(' ');
const len = routesStrArr.length;
/**
* 根据product将字符串一点点替换清除掉非自身模块的配置
*/
for (var i = 0; i < len; i++) {
const item = routesStrArr[i];
const name = item.toLowerCase();
if (name && name.indexOf('module') > 0 && name.indexOf(product.toLowerCase()) < 0) {
routesStrCache = routesStrCache.replace(item, '');
}
}
routesDataNoPostil = routesDataNoPostil.replace(routesStr, routesStrCache);
/**
* 将处理过的内容填充回去
*/
writeFile(routesUrl, routesDataNoPostil);
}
}
/**
* 开启进行编译处理
* @param _product
*/
function filterBegin(_product) {
filterRoutingCfg(_product);
filterRoutesCfg(_product);
setProgress('begin');
}
/**
* 设置进度条
*/
function setProgress(time) {
if (time === 'begin') {
console.log('---------开始编译 请耐心等待!---------');
console.log('--------------5%--------------');
} else {
console.log('--------------编译完成,请取包: ' + path + 'chubao');
}
}
/**
* 编译完成后 将原来的数据 从新写入
*/
function filterEnd() {
writeFile(routesUrl, routesData.data);
writeFile(routingUrl, routingData.data);
setProgress('end');
}
/*编译处理*/
const child_process = require('child_process');
/**
* 获取传入的参数
* @type {Array.<T>}
*/
const args = process.argv.splice(2);
/**
* 获取参数 第一为产品形态 第二位为oem定制信息
* @param index
* @returns {*}
*/
function getParams(index) {
return args && args[index] ? args[index] : 'soc'
}
/**
* 编译开始 只传产品形态即可
* @param product
*/
function compileStart(product, oem) {
/**
* 产品形态
* @type {string}
*/
filterBegin(getParams(0) || product);
/**
* 开始执行编译命令
*/
child_process.exec('npm run-script build:'+ getParams(1) || getParams(0) || oem, function(error, stdout, stderr){
filterEnd();
child_process.exec('cd ..');
});
}
/**
* 启动设置缓存
*/
function setItemLocalStorage(type, _path) {
const filePath = getFilePath('/src/environments/environment.cache.ts');
const fileData = fs.readFileSync(filePath, 'utf-8');
var typeData = fileData.match(/export(\s|.)*?(;)/g);
if (typeData[0]) {
typeData = fileData.replace(typeData[0], 'export let environment_cache = \'' +type+ '\';');
}
fs.writeFileSync(filePath, typeData);
const binPath = getFilePath(_path);
child_process.exec('start ' + binPath);
}
/**
* 将这些函数导出
* @type {{filterPostil: filterPostil, writeFile: writeFile}}
*/
module.exports = {
filterBegin: filterBegin,
filterEnd: filterEnd,
compileStart: compileStart,
setItemLocalStorage: setItemLocalStorage
};
- 使用bat批处理调用nodejs文件
@echo off
REM 声明采用UTF-8编码
chcp 65001
REM 执行node脚本
cmd /k node ../bin/build/soc.js soc soc
- nodejs脚本入口函数,用于传入不同的命令
#!/usr/bin/env node
/**
* 设置配置的默认路径用于编译相对应的配置项 // soc 关键字段 根目录下执行soc
*/
const fileUtils = require('../file_utils.js');
fileUtils.setItemLocalStorage('default', 'bin/start/start.bat proxy.conf.json --port 4200');
- 项目结构