@omnia/foundation
Version:
Provide omnia foundation typings and tooling work on client side for omnia extension
541 lines (497 loc) • 24.3 kB
JavaScript
/// <binding BeforeBuild='fix-build' />
;
var gulp = require('gulp')
, glob = require('glob')
, chokidar = require('chokidar')
, webpack = require("webpack")
, namedModulesPlugin = require('webpack/lib/NamedModulesPlugin')
, gutil = require("gulp-util")
, merge = require('webpack-merge')
, exec = require('child_process').exec
, fs = require('fs')
, fsExtra = require('fs-extra')
, argv = require('yargs').argv
, del = require('del')
, $ = require('gulp-load-plugins')({
pattern: [
'gulp-*'
],
rename: {
}
})
, jsonfile = require('jsonfile')
, extend = require('deep-extend')
, timestamp = require('console-timestamp')
, path = require('path')
, exec = require('child_process').exec
, omniaPlugins = require('./TaskRunner/omf.webpack.plugins.js')
, utils = require('./TaskRunner/omf.utils.js');
var appConfig = {};
gulp.task('fix-build', function(cb) {
del.sync('node_modules/@types/node');
});
gulp.task('build', function (cb) {
mergeConfig()
.then(aotCompile)
.then(webpackBundle)
.then(function () { console.log(timestamp('[hh:mm:ss]') + ' Build finished'); })
});
gulp.task('aot-compile', function (cb) {
mergeConfig()
.then(aotCompile)
.then(cb);
})
gulp.task('webpack-bundle', function (cb) {
mergeConfig()
.then(webpackBundle)
.then(cb);
});
gulp.task('less', function (cb) {
mergeConfig()
.then(compileAllLess)
.then(cb);
});
gulp.task('watch-less', function () {
process.on('uncaughtException', function (err) {
console.log(err);
});
var watchLessTenantResource = chokidar.watch(appConfig.less.watch, {
ignored: /[\/\\]\./,
persistent: true
});
watchLessTenantResource.on('ready', function () {
watchLessTenantResource
.on('change', function (path) {
console.log(utils.getCurrentDateTime() + " : compiling > " + path);
compileAllLess();
console.log(utils.getCurrentDateTime() + " : done");
});
});
});
gulp.task('webpack-watch', function () {
var listFilesBundling = [];
process.on('uncaughtException', function (err) {
console.log(err);
});
var watchAngular = chokidar.watch(appConfig.webpack.watch, {
ignored: /[\/\\]\./,
persistent: true
});
watchAngular.on('ready', function () {
watchAngular
.on('change', function (filePath) {
if (listFilesBundling.indexOf(filePath) === -1) {
listFilesBundling.push(filePath);
webpackCompile(appConfig.webpack.basePath, appConfig.webpack.flatModules, appConfig.webpack.ignoreFiles, filePath, function () {
if (listFilesBundling.indexOf(filePath) > -1)
listFilesBundling.splice(listFilesBundling.indexOf(filePath), 1)
}, true);
}
});
});
});
function aotCompile() {
return new Promise(function (resolve, reject) {
console.log(timestamp('[hh:mm:ss]') + ' Aot compile running...');
jsonfile.writeFileSync('./omf.tsconfig.aot.json', appConfig.aot.ngc);
// del.sync('node_modules/@types/node');
if (!enableRunAot() && (process.argv.length === 0 || process.argv[process.argv.length - 1] !== '--force')) {
console.warn('Aot compile disabled in environment.json');
resolve();
return;
}
if (appConfig.aot.cleanBefore && appConfig.aot.cleanBefore.length > 0) {
del.sync(appConfig.aot.cleanBefore);
}
exec('ngc -p ./omf.tsconfig.aot.json', function (err, stdout, stderr) {
if (stdout)
console.log(stdout);
if (stderr)
console.log(stderr);
if (err !== null) {
resolve(err);
return;
}
//doWebpackCompile(resolve);
else {
if (appConfig.aot.compileAotTsFiles && appConfig.aot.compileAotTsFiles.length > 0) {
gulp.src(appConfig.aot.typesForCompileAotTsFiles.concat(appConfig.aot.compileAotTsFiles))
.pipe($.tsc({
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"declaration": false,
"sourceMap": false,
"removeComments": false,
"noImplicitAny": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"types":[]
}))
.pipe(gulp.dest('.'))
.on('end', function () {
doWebpackCompile(resolve);
});
}
else {
doWebpackCompile(resolve);
}
}
});
})
function doWebpackCompile(resolve) {
if (appConfig.aot.webpackCompileFiles && appConfig.aot.webpackCompileFiles.length > 0) {
var totalFiles = 0;
var countLoop = 0;
for (var i = 0; i < appConfig.aot.webpackCompileFiles.length; i++) {
glob(appConfig.aot.webpackCompileFiles[i], function (err, files) {
countLoop++;
totalFiles = totalFiles + files.length;
if (totalFiles === 0 && countLoop === appConfig.aot.webpackCompileFiles.length) {
console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
resolve();
}
for (var k = 0; k < files.length; k++) {
webpackCompile(appConfig.webpack.basePaths, appConfig.webpack.flatModules, appConfig.webpack.ignoreFiles, files[k], function () {
totalFiles = totalFiles - 1;
if (totalFiles === 0) {
if (appConfig.aot.copyOutputAotFilesToTenantResources && appConfig.aot.copyOutputAotFilesToTenantResources.length > 0) {
var count = 0;
for (var j = 0; j < appConfig.aot.copyOutputAotFilesToTenantResources.length; j++) {
gulp.src(appConfig.aot.copyOutputAotFilesToTenantResources[j].source)
.pipe(gulp.dest(appConfig.aot.copyOutputAotFilesToTenantResources[j].target))
.on('end', function () {
count++;
if (count === appConfig.aot.copyOutputAotFilesToTenantResources.length) {
if (appConfig.aot.cleanAfter && appConfig.aot.cleanAfter.length > 0) {
del.sync(appConfig.aot.cleanAfter);
}
console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
resolve();
}
});
}
}
else {
if (appConfig.aot.cleanAfter && appConfig.aot.cleanAfter.length > 0) {
del.sync(appConfig.aot.cleanAfter);
}
console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
resolve();
}
}
});
}
});
}
}
else {
if (appConfig.aot.cleanAfter && appConfig.aot.cleanAfter.length > 0) {
del.sync(appConfig.aot.cleanAfter);
}
console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
resolve();
}
}
}
function webpackBundle(allowLog) {
return new Promise(function (resolve, reject) {
console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle running...');
var srcfiles = appConfig.webpack.compileFiles;
var totalFiles = 0;
var countLoop = 0;
for (var i = 0; i < srcfiles.length; i++) {
glob(srcfiles[i], function (err, files) {
countLoop++;
totalFiles = totalFiles + files.length;
for (var k = 0; k < files.length; k++) {
webpackCompile(appConfig.webpack.basePaths, appConfig.webpack.flatModules, appConfig.webpack.ignoreFiles, files[k], function () {
totalFiles = totalFiles - 1;
if (totalFiles === 0 && countLoop === srcfiles.length) {
console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle finished');
resolve();
}
}, allowLog);
}
});
}
if (srcfiles.length === 0) {
console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle finished');
resolve();
}
})
}
function compileLess(filePath, callBack) {
var filePathFOrmatOS = filePath.replace(/\//g, "\\");
gulp.src(filePath)
.pipe($.sourcemaps.init())
.pipe($.less({}))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(filePath.substring(0, filePath.lastIndexOf('/'))))
.on('end', function () {
if (callBack !== undefined)
callBack();
});
}
function compileAllLess() {
return new Promise(function (resolve, reject) {
console.log(timestamp('[hh:mm:ss]') + ' Compile less running...');
var totalFiles = 0;
var countLoop = 0;
for (var i = 0; i < appConfig.less.compile.tenantResource.files.length; i++) {
glob(appConfig.less.compile.tenantResource.files[i], function (err, files) {
countLoop++;
totalFiles = totalFiles + files.length;
for (var k = 0; k < files.length; k++) {
compileLess(files[k], function () {
totalFiles = totalFiles - 1;
if (totalFiles === 0 && countLoop === appConfig.less.compile.tenantResource.files.length) {
console.log(timestamp('[hh:mm:ss]') + ' Compile less finished');
resolve();
}
});
}
});
}
if (appConfig.less.compile.tenantResource.files.length.length === 0) {
console.log(timestamp('[hh:mm:ss]') + ' Compile less finished');
resolve();
}
});
}
function webpackCompile(basePaths, flatModules, ignoreFiles, destPath, callBack, allowLog) {
var isSelfResolveModule = false;
var isCompile = false; // work around for teamcity not clean resource folder when rebuild
var flatModule = isFlatModule(flatModules, destPath)
if (!isMatchIgnoreFiles(ignoreFiles, destPath) && destPath.indexOf('.ngsummary.js') === -1) {
let stream = fs.readFileSync(destPath, 'utf8');
//isCompile = stream.indexOf('webpackJsonp([0],{') !== 0 && stream.indexOf('define(') !== 0;
isCompile = stream.indexOf('webpackJsonp([0],{') !== 0;
if (isCompile) {
isSelfResolveModule = stream.indexOf('.OmniaControl({') > -1 || stream.indexOf('.OmniaAdminControl({') > -1 || stream.indexOf('.NgModule({') > -1 || stream.indexOf('.Component({') > -1
|| stream.indexOf('Extensibility_1.TemplateId') > -1 || stream.indexOf('Extensibility_1.OmniaControl') > -1 || stream.indexOf('<<webpack-resolve-module>>') > -1
}
}
if (isCompile) {
var namedModulesReplacements = [];
for (var i = 0; i < basePaths.length; i++) {
namedModulesReplacements.push({
pattern: new RegExp(basePaths[i].replace(/\//g, "\\/") + "\\/", 'g'),
replace: ""
});
}
namedModulesReplacements.push({
pattern: /\/node_modules/g,
replace: ""
});
fs.appendFileSync(destPath, '\r\n //webpack-eof');
destPath = "./" + destPath.replace(/[/\\*]/g, "/");
var fileName = destPath.substring(destPath.lastIndexOf('/'));
webpack(merge(require("./TaskRunner/config/webpack.config.js"), {
entry: {
'external': './TaskRunner/config/external.js',
'app': destPath
},
externals: [
function (context, request, callback) {
if (destPath.indexOf(request.replace("./", "")) === -1 || destPath.substring(destPath.indexOf(request.replace("./", "")), destPath.length) !== request.replace("./", "")) {
//if (flatModule && request.indexOf('./') === 0 && request !== './TaskRunner/config/external.js') {
// callback();
//}
//else
// return callback(null, "__webpack_require__('" + request.toLowerCase() + "')");
return callback(null, "__webpack_require__('" + request.toLowerCase() + "')");
}
else {
callback();
}
}
],
//target: "node",
cache: false,
output: {
//library: destPath,
libraryTarget: flatModule ? "amd" : "var",
pathinfo: true,
//path: '.',
filename: destPath.replace("./", ''),
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({ name: 'external', filename: 'TaskRunner/config/external.bundle.js' }),
new omniaPlugins.NamedModulesPlugin({
replacements: namedModulesReplacements
}),
new omniaPlugins.ReplaceBundlePlugin([
{
partten: /\/\/webpack-eof[\s\S]+}\,\[(.*?)\]/g,
replacement: function (match) {
return '}},[]'
}
},
//{
// partten: /define\((.*?)return webpackJsonp\(\[/i,
// replacement: function (match) {
// return match
// .replace('define(', "define('" + destPath.replace("./", "") + "',")
// .replace(/\[(.*?)\]/i, "[]") // remove dependency, will undo later
// .replace(/function\((.*?){/i, "function(){") // remove dependency, will undo later
// .replace(/__webpack_require__\(\'(.*?)'\)/g, function (module) {
// var requireModulePath = module
// .replace("__webpack_require__('", "")
// .replace("')", "")
// if (requireModulePath.indexOf(".") === 0) {
// var requireModulePath = path.resolve(path.dirname(destPath), requireModulePath);
// requireModulePath = requireModulePath.replace(/\\/g, "/");
// for (var i = 0; i < basePaths.length; i++) {
// requireModulePath = requireModulePath.replace(utils.root(basePaths[i]).replace(/\\/g, "/"), "")
// }
// requireModulePath = requireModulePath
// .replace(utils.root('TenantResources').replace(/\\/g, "/") + '/~/', "")
// .replace(utils.root('.').replace(/\\/g, "/") + '/~/', "")
// .replace(utils.root('.').replace(/\\/g, "/"), "")
// .trim("/");
// if (requireModulePath.indexOf("/") === 0)
// requireModulePath = requireModulePath.substring(1, requireModulePath.length);
// if (requireModulePath.indexOf("node_modules/") === 0)
// requireModulePath = requireModulePath.replace(/node_modules\//i, "");
// }
// return requireModulePath;
// });
// }
//},
{
partten: /"use strict";[\s\S]+"use strict";/g,
replacement: '"use strict";'
},
{
partten: /\/\* no static exports found[\s\S]+function\(module, exports, __webpack_require__\) {/i,
replacement: function (match) { return "function(module, exports, __webpack_require__) {"; }
},
{
partten: new RegExp("__webpack_require__\\(\/\\*(.*)\\)", 'g'),
replacement: function (match) {
return match
.replace("/*!", "'")
.replace(/\*\/(.*?)\){1}/i, "')")
.replace(/ /g, "")
.replace(/'(.*?)'/i, function (requireModulePath) {
requireModulePath = requireModulePath.replace(/'/g, "");
if (requireModulePath.indexOf(".") === 0) {
var requireModulePath = path.resolve(path.dirname(destPath), requireModulePath);
requireModulePath = requireModulePath.replace(/\\/g, "/");
for (var i = 0; i < basePaths.length; i++) {
requireModulePath = requireModulePath.replace(utils.root(basePaths[i]).replace(/\\/g, "/"), "");
}
requireModulePath = requireModulePath
.replace(utils.root('TenantResources').replace(/\\/g, "/") + '/~/', "")
.replace(utils.root('.').replace(/\\/g, "/") + '/~/', "")
.replace(utils.root('.').replace(/\\/g, "/"), "")
.trim("/");
if (requireModulePath.indexOf("/") === 0)
requireModulePath = requireModulePath.substring(1, requireModulePath.length);
if (requireModulePath.indexOf("node_modules/") === 0)
requireModulePath = requireModulePath.replace(/node_modules\//i, "");
if (destPath.indexOf(requireModulePath + '.js') > -1) {
console.log('have recursive import self : ' + destPath);
}
}
return "'" + requireModulePath.toLowerCase().replace("@omnia/foundation/extensibility/typings/", "@omnia/foundation/extensibility/") + "'";
});
}
},
{
skip: !isSelfResolveModule,
partten: /webpackJsonp\(\[0\],{[\s\S]+":/g,
replacement: function (match) {
var moduleId = match.match(/"(.*?)"/)[1]
return "omfExecuteModules.push('" + moduleId + "'); ";
//return "require('" + destPath.replace("./", "") + "');\r\n"
// + "omfExecuteModules.push('" + moduleId + "'); ";
},
insertToEOF: true
},
//{
// skip: isSelfResolveModule,
// partten: /webpackJsonp\(\[0\],{[\s\S]+":/g,
// replacement: function (match) {
// return "require('" + destPath.replace("./", "") + "');";
// },
// insertToEOF: true
//},
{
partten: /;;/g,
replacement: ';'
},
])
]
}), function (err, stats) {
if (err) throw new gutil.PluginError("webpack", err);
})
.plugin("done", function () {
if (allowLog)
console.log('bundle completed - ' + destPath);
if (callBack !== undefined)
callBack();
});
}
else {
if (callBack !== undefined)
callBack();
}
}
function isMatchIgnoreFiles(ignoreFiles, filePath) {
var isMatch = false
for (var i = 0; i < ignoreFiles.length; i++) {
if (filePath.indexOf(ignoreFiles[i]) > -1) {
isMatch = true;
return isMatch;
}
}
return isMatch;
}
function isFlatModule(flatModules, filePath) {
var isMatch = false
for (var i = 0; i < flatModules.length; i++) {
if (filePath.replace(/\\/g, "/").toLowerCase().indexOf(flatModules[i].replace(/\\/g, "/").toLowerCase()) > -1) {
isMatch = true;
return isMatch;
}
}
return isMatch;
}
function enableRunAot() {
var result = true;
var processPath = process.cwd().replace(/\\/g, "/");
if (fs.existsSync(processPath + '/environment.json')) {
try {
var config = require(processPath + '/environment.json');
if (config.Angular && config.Angular && config.Angular.AOT && config.Angular.AOT.RunOnBuild === false)
result = false
}
catch (err) {
console.log(err);
}
}
return result;
}
function mergeConfig() {
return new Promise(function (resolve, reject) {
var processPath = process.cwd().replace(/\\/g, "/");
if (fs.existsSync(processPath + '/TaskRunner/omf.task.config.json')) {
try {
appConfig = require('./TaskRunner/config/app.json');
var extendConfig = require(processPath + '/TaskRunner/omf.task.config.json');
extend(appConfig, extendConfig);
// console.log(appConfig);
resolve();
}
catch (err) {
console.log('have an exception in omf.task.config.json : ' + err);
}
}
else{
appConfig = require('./TaskRunner/config/app.json');
resolve();
}
})
}