UNPKG

24.3 kBJavaScriptView Raw
1'use strict';
2var processPath = process.cwd().replace(/\\/g, "/")
3 , fsExtra = require('../../../fs-extra')
4 , del = require('../../../del');
5
6fsExtra.copySync('node_modules/@omnia/foundation/task/external/node_modules/webpack/lib/FunctionModuleTemplatePlugin.js', 'node_modules/webpack/lib/FunctionModuleTemplatePlugin.js');
7// delete local node_modules
8del.sync('node_modules/@omnia/foundation/node_modules');
9
10var gulp = require('gulp')
11 , glob = require('../../../glob')
12 , globby = require('../../../globby')
13 , chokidar = require('../../../chokidar')
14 , fs = require('fs')
15 , $ = require('../../../gulp-load-plugins')({
16 pattern: [
17 'gulp-*'
18 ],
19 rename: {
20 }
21 })
22 , timestamp = require('../../../console-timestamp')
23 , webpack = require("../../../webpack")
24 , namedModulesPlugin = require('../../../webpack/lib/NamedModulesPlugin')
25 , gutil = require("../../../gulp-util")
26 , merge = require('../../../webpack-merge')
27 , exec = require('child_process').exec
28 , jsonfile = require('../../../jsonfile')
29 , extend = require('../../../deep-extend')
30 , path = require('path')
31 , omfWebpackPlugins = require('./services/omf.webpack.plugins')
32 , utils = require('../../tooling/utils')
33 , core = require('../../tooling/core');
34
35var appConfig = {};
36mergeConfig();
37core.registerBuildTask({ type: core.BuildType.BeforeBuild, order: 9, task: beforeBuild });
38core.registerBuildTask({ type: core.BuildType.AfterBuild, order: 20, task: afterBuild });
39
40gulp.task('omf-webpack-bundle', function (cb) {
41 var files, i = process.argv.indexOf("--files");
42 if (i > -1 && process.argv.length - 1 > i) {
43 files = process.argv[i + 1];
44 webpackBundle(true, files.split(','));
45 }
46 else {
47 webpackBundle(true).then(cb);
48 }
49});
50
51
52gulp.task('omf-webpack-bundle-libs', function (cb) {
53 if (appConfig.angular.webpack.bundleLibs && appConfig.angular.webpack.bundleLibs.configFile
54 && appConfig.angular.webpack.bundleLibs.configFile.length > 0 && appConfig.angular.webpack.bundleLibs.outputFile && appConfig.angular.webpack.bundleLibs.outputFile.length > 0) {
55 let stream = fs.readFileSync(appConfig.angular.webpack.bundleLibs.configFile, 'utf8');
56 if (stream.indexOf("//webpack-eof") === -1)
57 fs.appendFileSync(appConfig.angular.webpack.bundleLibs.configFile, '\r\n //webpack-eof');
58 var basePaths = ["node_modules"];
59 webpack(merge(require("./config/webpack.config.js"), {
60 entry: {
61 'vendor': './task/config/external.js',
62 'app': processPath + '/' + appConfig.angular.webpack.bundleLibs.configFile
63 },
64 target: "web",
65 output: {
66 pathinfo: true,
67 filename: appConfig.angular.webpack.bundleLibs.outputFile,
68 },
69 externals: [
70 function (context, request, callback) {
71 if (request.toLowerCase().indexOf("@angular") === 0 || request.toLowerCase().indexOf("rxjs") === 0) {
72 return callback(null, "__webpack_require__('" + request.toLowerCase() + "')");
73 }
74 else {
75 callback();
76 }
77 }
78 ],
79 module: {
80 loaders: [
81 {
82 test: /\.js$/,
83 loader: 'babel-loader',
84 query: {
85 compact: false,
86 presets: ['es2015'],
87 ignore: [
88 ]
89 }
90 }
91 ]
92 },
93 plugins: [
94 new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'node_modules/@omnia/foundation/task/temp/external.bundle.js' }),
95 new omfWebpackPlugins.NamedModulesPlugin({
96 replacements: [
97 {
98 pattern: /\/node_modules/g,
99 replace: ""
100 }
101 ]
102 }),
103 new omfWebpackPlugins.ReplaceBundlePlugin([
104 {
105 pattern: /\/\/webpack-eof[\s\S]+}\,\[(.*?)\]/g,
106 replacement: function (match) {
107 return '})},[]'
108 }
109 },
110 {
111 pattern: new RegExp("__webpack_require__\\(\/\\*(.*)\\)", 'g'),
112 replacement: function (match) {
113 return match
114 .replace(/\/\*!(.*?)\/(.*?)"/i, '"')
115 .replace(/\/\*!(.*?)\/(.*?)\)/i, function (requireModulePath) {
116 return requireModulePath
117 .replace("/*!", '"')
118 .replace(/\*\/(.*?)\)/i, '")')
119 .replace(/ /g, "")
120 })
121 }
122 }
123 ])
124 ]
125 }),
126 function (err, stats) {
127 if (err) throw new gutil.PluginError("webpack", err);
128 })
129 .plugin("done", function () {
130 let stream = fs.readFileSync(appConfig.angular.webpack.bundleLibs.configFile, 'utf8');
131 stream.replace(/\/\/webpack-eof/g, "")
132 fs.writeFileSync(appConfig.angular.webpack.bundleLibs.configFile, stream);
133 if (appConfig.angular.webpack.bundleLibs.concatToOutPut
134 && appConfig.angular.webpack.bundleLibs.concatToOutPut.files
135 && appConfig.angular.webpack.bundleLibs.concatToOutPut.files.length > 0
136 ) {
137 var temFilePath = appConfig.angular.webpack.bundleLibs.outputFile.replace(/\\/g, "/");
138 var outFileName = temFilePath.substring(temFilePath.lastIndexOf('/'));
139 var folderPath = ".";
140 if (temFilePath.lastIndexOf('/') > 0)
141 folderPath = temFilePath.substring(0, temFilePath.lastIndexOf('/'))
142 gulp.src([appConfig.angular.webpack.bundleLibs.outputFile].concat(appConfig.angular.webpack.bundleLibs.concatToOutPut.files))
143 .pipe($.concat(outFileName))
144 .pipe(gulp.dest(folderPath))
145 .on('end', function () {
146 console.log('bundle completed');
147 cb();
148 });
149 }
150 else {
151 console.log('bundle completed');
152 cb();
153 }
154 });
155 }
156 else {
157 console.log('Not found configs angular.webpack.bundleLibs.configFile or appConfig.angular.webpack.bundleLibs.outputFile');
158 }
159
160});
161
162function beforeBuild() {
163 return new Promise(function (resolve, reject) {
164 fsExtra.copySync('node_modules/@omnia/foundation/task/external/node_modules/bin', processPath + '/node_modules/.bin');
165 del.sync('node_modules/@types/node');
166 del.sync('node_modules/@omnia/foundation/node_modules');
167 resolve();
168 });
169}
170
171function afterBuild() {
172 return new Promise(function (resolve, reject) {
173 aotCompile()
174 .then(webpackBundle)
175 .then(resolve)
176 });
177}
178
179function aotCompile() {
180 return new Promise(function (resolve, reject) {
181 console.log(timestamp('[hh:mm:ss]') + ' Aot compile running...');
182
183 if (!enableRunAot() && (process.argv.length === 0 || process.argv[process.argv.length - 1] !== '--force-aot')) {
184 console.warn('Aot compile disabled in environment.json');
185 resolve();
186 return;
187 }
188 if (appConfig.angular.aot.cleanBefore && appConfig.angular.aot.cleanBefore.length > 0) {
189 del.sync(appConfig.angular.aot.cleanBefore);
190 }
191 fsExtra.copySync('node_modules/@omnia/foundation/task/external/node_modules/gulp-tsc/lib/compiler.js', processPath + '/node_modules/gulp-tsc/lib/compiler.js');
192
193 jsonfile.writeFileSync('./omf.tsconfig.aot.json', appConfig.angular.aot.ngc);
194 exec('"node_modules/.bin/ngc" -p ./omf.tsconfig.aot.json', function (err, stdout, stderr) {
195 if (stdout)
196 console.log(stdout);
197 if (stderr)
198 console.log(stderr);
199 if (err !== null) {
200 console.log(err);
201 throw "have an exception when aot compiling";
202 }
203 else {
204 if (appConfig.angular.aot.compileAotTsFiles && appConfig.angular.aot.compileAotTsFiles.length > 0) {
205 del.sync('node_modules/@types/node');
206 gulp.src(appConfig.angular.aot.typesForCompileAotTsFiles.concat(appConfig.angular.aot.compileAotTsFiles))
207 .pipe($.tsc({
208 "target": "es5",
209 "module": "commonjs",
210 "moduleResolution": "node",
211 "lib": ["es2015", "dom"],
212 "declaration": false,
213 "sourceMap": false,
214 "removeComments": false,
215 "noImplicitAny": false,
216 "emitDecoratorMetadata": true,
217 "experimentalDecorators": true,
218 "skipLibCheck": true
219 }))
220 .pipe(gulp.dest(appConfig.angular.aot.outDir))
221 .on('end', function () {
222 doWebpackCompile(resolve);
223 });
224 }
225 else {
226 doWebpackCompile(resolve);
227 }
228 }
229 });
230 })
231
232 function doWebpackCompile(resolve) {
233 if (appConfig.angular.aot.webpackBundleFiles && appConfig.angular.aot.webpackBundleFiles.length > 0) {
234 var totalFiles = 0;
235 var countLoop = 0;
236 for (var i = 0; i < appConfig.angular.aot.webpackBundleFiles.length; i++) {
237 glob(appConfig.angular.aot.webpackBundleFiles[i], function (err, files) {
238 countLoop++;
239 totalFiles = totalFiles + files.length;
240 if (totalFiles === 0 && countLoop === appConfig.angular.aot.webpackBundleFiles.length) {
241 console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
242 resolve();
243 }
244 for (var k = 0; k < files.length; k++) {
245 webpackCompile(appConfig.angular.webpack.basePaths, appConfig.angular.webpack.flatModules, appConfig.angular.webpack.ignoreFiles, files[k], function () {
246 totalFiles = totalFiles - 1;
247 if (totalFiles === 0) {
248 if (appConfig.angular.aot.copyOutputAotFilesToTenantResources && appConfig.angular.aot.copyOutputAotFilesToTenantResources.length > 0) {
249 var count = 0;
250 for (var j = 0; j < appConfig.angular.aot.copyOutputAotFilesToTenantResources.length; j++) {
251 gulp.src(appConfig.angular.aot.copyOutputAotFilesToTenantResources[j].source)
252 .pipe(gulp.dest(appConfig.angular.aot.copyOutputAotFilesToTenantResources[j].target))
253 .on('end', function () {
254 count++;
255 if (count === appConfig.angular.aot.copyOutputAotFilesToTenantResources.length) {
256 if (appConfig.angular.aot.cleanAfter && appConfig.angular.aot.cleanAfter.length > 0) {
257 del.sync(appConfig.angular.aot.cleanAfter);
258 }
259 console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
260 resolve();
261 }
262 });
263 }
264 }
265 else {
266 if (appConfig.angular.aot.cleanAfter && appConfig.angular.aot.cleanAfter.length > 0) {
267 del.sync(appConfig.angular.aot.cleanAfter);
268 }
269 console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
270 resolve();
271 }
272 }
273 });
274 }
275 });
276 }
277 }
278 else {
279 if (appConfig.angular.aot.cleanAfter && appConfig.angular.aot.cleanAfter.length > 0) {
280 del.sync(appConfig.angular.aot.cleanAfter);
281 }
282 console.log(timestamp('[hh:mm:ss]') + ' Aot compile finished');
283 resolve();
284 }
285 }
286}
287
288function webpackBundle(allowLog, files) {
289 return new Promise(function (resolve, reject) {
290 console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle running...');
291 var srcfiles = files || appConfig.angular.webpack.compileFiles;
292 var thresholdThread = appConfig.angular.webpack.thresholdThread || 100;
293 var totalFiles = 0;
294 var countCompletes = 0;
295 if (srcfiles.length === 0) {
296 console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle finished');
297 resolve();
298 }
299 else {
300 globby(srcfiles).then(function (files) {
301 if (files.length < thresholdThread)
302 thresholdThread = files.length;
303
304 totalFiles = totalFiles + files.length;
305 var countThread = 0;
306
307 for (var k = 0; k < thresholdThread; k++) {
308 if (files.length > 0) {
309 countThread++;
310 webpackCompile(appConfig.angular.webpack.basePaths, appConfig.angular.webpack.flatModules, appConfig.angular.webpack.ignoreFiles, files.shift(), recursiveCompile, allowLog);
311 }
312
313 }
314 function recursiveCompile() {
315 countThread--;
316 countCompletes++;
317 if (totalFiles === countCompletes) {
318 console.log(timestamp('[hh:mm:ss]') + ' Webpack bundle finished');
319 resolve();
320 }
321 else if (countThread < thresholdThread && files.length > 0) {
322 countThread++;
323 webpackCompile(appConfig.angular.webpack.basePaths, appConfig.angular.webpack.flatModules, appConfig.angular.webpack.ignoreFiles,
324 files.shift(), recursiveCompile, allowLog);
325 }
326 }
327
328 })
329 }
330 })
331}
332
333
334
335
336function webpackCompile(basePaths, flatModules, ignoreFiles, filePath, callBack, allowLog) {
337 var isSelfResolveModule = false;
338 var isCompile = false;
339 var destPath = filePath.replace(/\\/g, "/").replace(utils.root('.').replace(/\\/g, "/") + "/", "");
340 if (!isMatchIgnoreFiles(ignoreFiles, destPath)) {
341 let stream = fs.readFileSync(destPath, 'utf8');
342 isCompile = stream.indexOf('webpackJsonp([0],{') !== 0;
343 if (isCompile) {
344 isSelfResolveModule = checkResolveSelfModule(stream);
345 }
346 }
347 if (isCompile) {
348 var namedModulesReplacements = [];
349 for (var i = 0; i < basePaths.length; i++) {
350 namedModulesReplacements.push({
351 pattern: new RegExp(basePaths[i].replace(/\//g, "\\/") + "\\/", 'g'),
352 replace: ""
353 });
354 }
355 namedModulesReplacements.push({
356 pattern: /\/node_modules/g,
357 replace: ""
358 });
359 fs.appendFileSync(destPath, '\r\n //webpack-eof');
360 destPath = "./" + destPath.replace(/[/\\*]/g, "/");
361 var fileName = destPath.substring(destPath.lastIndexOf('/'));
362 webpack(merge(require("./config/webpack.config.js"), {
363 entry: {
364 'external': './task/config/external.js',
365 'app': destPath
366 },
367 externals: [
368 function (context, request, callback) {
369 if (destPath.indexOf(request.replace("./", "")) === -1 || destPath.substring(destPath.indexOf(request.replace("./", "")), destPath.length) !== request.replace("./", "")) {
370 return callback(null, "__webpack_require__('" + request.toLowerCase() + "')");
371 }
372 else {
373 callback();
374 }
375 }
376 ],
377 cache: false,
378 output: {
379 pathinfo: true,
380 filename: destPath.replace("./", ''),
381 },
382 plugins: [
383 new webpack.optimize.CommonsChunkPlugin({ name: 'external', filename: 'node_modules/@omnia/foundation/task/temp/external.bundle.js' }),
384 new omfWebpackPlugins.NamedModulesPlugin({
385 replacements: namedModulesReplacements
386 }),
387 new omfWebpackPlugins.ReplaceBundlePlugin([
388 {
389 pattern: /\/\/# sourceMappingURL[\s\S]+\/\/webpack-eof/g,
390 replacement: function (match) {
391 return '//webpack-eof'
392 }
393 },
394 {
395 pattern: /\/\/webpack-eof[\s\S]+}\,\[(.*?)\]/g,
396 replacement: function (match) {
397 return '})},[]'
398 }
399 },
400 {
401 pattern: /"use strict";[\s\S]+"use strict";/g,
402 replacement: '"use strict";'
403 },
404 {
405 pattern: new RegExp("__webpack_require__\\(\/\\*(.*)\\)", 'g'),
406 replacement: function (match) {
407 return match
408 .replace("/*!", "'")
409 .replace(/\*\/(.*?)\){1}/i, "')")
410 .replace(/ /g, "")
411 .replace(/'(.*?)'/i, function (requireModulePath) {
412 requireModulePath = requireModulePath.replace(/'/g, "");
413 if (requireModulePath.indexOf(".") === 0) {
414 requireModulePath = path.resolve(path.dirname(destPath), requireModulePath);
415 requireModulePath = requireModulePath.replace(/\\/g, "/");
416 for (var i = 0; i < basePaths.length; i++) {
417 requireModulePath = requireModulePath.replace(utils.root(basePaths[i]).replace(/\\/g, "/"), "");
418 }
419 requireModulePath = requireModulePath
420 .replace(utils.root('TenantResources').replace(/\\/g, "/") + '/~/', "")
421 .replace(utils.root('.').replace(/\\/g, "/") + '/~/', "")
422 .replace(utils.root('.').replace(/\\/g, "/"), "")
423 .trim("/");
424 if (requireModulePath.indexOf("/") === 0)
425 requireModulePath = requireModulePath.substring(1, requireModulePath.length);
426 if (requireModulePath.indexOf("node_modules/") === 0)
427 requireModulePath = requireModulePath.replace(/node_modules\//i, "");
428 if (destPath.indexOf(requireModulePath + '.js') > -1) {
429 console.log('have recursive import self : ' + destPath);
430 }
431 }
432
433 return "'" + requireModulePath.toLowerCase().replace("@omnia/foundation/extensibility/typings/", "@omnia/foundation/extensibility/") + "'";
434 });
435 }
436 },
437 {
438 skip: !isSelfResolveModule,
439 pattern: /webpackJsonp\(\[0\],{[\s\S]+":/g,
440 replacement: function (match) {
441 var moduleId = match.match(/"(.*?)"/)[1]
442 return "omfExecuteModules.push('" + moduleId + "'); ";
443 },
444 insertToEOF: true
445 },
446 {
447 pattern: /;;/g,
448 replacement: ';'
449 },
450 ])
451 ]
452 }), function (err, stats) {
453 if (err) throw new gutil.PluginError("webpack", err);
454 })
455 .plugin("done", function () {
456 if (allowLog)
457 console.log('bundle completed - ' + filePath);
458 if (callBack !== undefined)
459 callBack();
460 });
461 }
462 else {
463 if (callBack !== undefined)
464 callBack();
465 }
466
467 function checkResolveSelfModule(content) {
468 return content.indexOf('.OmniaControl({') > -1
469 || content.indexOf('.OmniaAdminControl({') > -1
470 || content.indexOf('.OmniaControlTemplate({') > -1
471 || content.indexOf('.TemplateId(') > -1
472 || content.indexOf('.GlueToolbarItem(') > -1
473 || content.indexOf('.GluePaneContent(') > -1
474 || content.indexOf('.GlueTopbarItem(') > -1
475 || content.indexOf('.GluePaneTab(') > -1
476 || content.indexOf('Extensibility_1.TemplateId') > -1
477 || content.indexOf('Extensibility_1.OmniaControl') > -1
478 || content.indexOf('<<webpack-resolve-module>>') > -1
479 }
480}
481
482function isMatchIgnoreFiles(ignoreFiles, filePath) {
483 var isMatch = false
484 for (var i = 0; i < ignoreFiles.length; i++) {
485 if (filePath.indexOf(ignoreFiles[i]) > -1) {
486 isMatch = true;
487 return isMatch;
488 }
489 }
490
491 return isMatch;
492}
493
494function enableRunAot() {
495 var result = true;
496 var processPath = process.cwd().replace(/\\/g, "/");
497
498 if (fs.existsSync(processPath + '/environment.json')) {
499 try {
500 var config = require(processPath + '/environment.json');
501 if (config.Angular && config.Angular && config.Angular.AOT && config.Angular.AOT.RunOnBuild === false)
502 result = false
503 }
504 catch (err) {
505 console.log(err);
506 }
507 }
508
509 return result;
510}
511
512function mergeConfig() {
513 appConfig = require('./config/app.json');
514 var config = core.getConfig('/TaskRunner/Tasks/Angular/task.config.json');
515 if (config !== null)
516 utils.extend(appConfig, config)
517}