UNPKG

24.9 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('@omnia/tooling/shared/omf.utils.js')
33 , core = require('@omnia/tooling/shared/omf.core.js');
34
35var appConfig = {};
36mergeConfig();
37core.registerBuildTask({ type: core.BuildType.BeforeBuild, order: 9, task: beforeBuild });
38core.registerBuildTask({ type: core.BuildType.AfterBuild, order: 1, 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 namedModulesReplacements.push({
350 pattern: /(.*)/i,
351 replace: function (match) {
352 if (match.toLowerCase() === destPath.toLowerCase()) {
353 return "webpack<<startcurrentmodule>>" + match;
354 }
355 return match;
356 }
357 });
358 for (var i = 0; i < basePaths.length; i++) {
359 namedModulesReplacements.push({
360 pattern: new RegExp(basePaths[i].replace(/\//g, "\\/") + "\\/", 'g'),
361 replace: ""
362 });
363 }
364 namedModulesReplacements.push({
365 pattern: /\/node_modules/g,
366 replace: ""
367 });
368 fs.appendFileSync(destPath, '\r\n //webpack-eof');
369 destPath = "./" + destPath.replace(/[/\\*]/g, "/");
370 var fileName = destPath.substring(destPath.lastIndexOf('/'));
371 webpack(merge(require("./config/webpack.config.js"), {
372 entry: {
373 'external': './task/config/external.js',
374 'app': destPath
375 },
376 externals: [
377 function (context, request, callback) {
378 if (destPath.indexOf(request.replace("./", "")) === -1 || destPath.substring(destPath.indexOf(request.replace("./", "")), destPath.length) !== request.replace("./", "")) {
379 return callback(null, "__webpack_require__('" + request.toLowerCase() + "')");
380 }
381 else {
382 callback();
383 }
384 }
385 ],
386 cache: false,
387 output: {
388 pathinfo: true,
389 filename: destPath.replace("./", ''),
390 },
391 plugins: [
392 new webpack.optimize.CommonsChunkPlugin({ name: 'external', filename: 'node_modules/@omnia/foundation/task/temp/external.bundle.js' }),
393 new omfWebpackPlugins.NamedModulesPlugin({
394 replacements: namedModulesReplacements
395 }),
396 new omfWebpackPlugins.ReplaceBundlePlugin([
397 {
398 pattern: /\/\/# sourceMappingURL[\s\S]+\/\/webpack-eof/g,
399 replacement: function (match) {
400 return '//webpack-eof'
401 }
402 },
403 {
404 pattern: /\/\/webpack-eof[\s\S]+}\,\[(.*?)\]/g,
405 replacement: function (match) {
406 return '})},[]'
407 }
408 },
409 {
410 pattern: /webpackJsonp\(\[0\],{[\s\S]+webpack<<startcurrentmodule>>/i,
411 replacement: function (match) {
412 return 'webpackJsonp([0],{"'
413 }
414 },
415 {
416 pattern: /"use strict";[\s\S]+"use strict";/g,
417 replacement: '"use strict";'
418 },
419 {
420 pattern: new RegExp("__webpack_require__\\(\/\\*(.*)\\)", 'g'),
421 replacement: function (match) {
422 return match
423 .replace("/*!", "'")
424 .replace(/\*\/(.*?)\){1}/i, "')")
425 .replace(/ /g, "")
426 .replace(/'(.*?)'/i, function (requireModulePath) {
427 requireModulePath = requireModulePath.replace(/'/g, "");
428 if (requireModulePath.indexOf(".") === 0) {
429 requireModulePath = path.resolve(path.dirname(destPath), requireModulePath);
430 requireModulePath = requireModulePath.replace(/\\/g, "/");
431 for (var i = 0; i < basePaths.length; i++) {
432 requireModulePath = requireModulePath.replace(utils.root(basePaths[i]).replace(/\\/g, "/"), "");
433 }
434 requireModulePath = requireModulePath
435 .replace(utils.root('TenantResources').replace(/\\/g, "/") + '/~/', "")
436 .replace(utils.root('.').replace(/\\/g, "/") + '/~/', "")
437 .replace(utils.root('.').replace(/\\/g, "/"), "")
438 .trim("/");
439 if (requireModulePath.indexOf("/") === 0)
440 requireModulePath = requireModulePath.substring(1, requireModulePath.length);
441 if (requireModulePath.indexOf("node_modules/") === 0)
442 requireModulePath = requireModulePath.replace(/node_modules\//i, "");
443 if (destPath.indexOf(requireModulePath + '.js') > -1) {
444 console.log('have recursive import self : ' + destPath);
445 }
446 }
447
448 return "'" + requireModulePath.toLowerCase().replace("@omnia/foundation/extensibility/typings/", "@omnia/foundation/extensibility/") + "'";
449 });
450 }
451 },
452 {
453 skip: !isSelfResolveModule,
454 pattern: /webpackJsonp\(\[0\],{[\s\S]+":/g,
455 replacement: function (match) {
456 var moduleId = match.match(/"(.*?)"/)[1]
457 return "omfExecuteModules.push('" + moduleId + "'); ";
458 },
459 insertToEOF: true
460 },
461 {
462 pattern: /;;/g,
463 replacement: ';'
464 },
465 ])
466 ]
467 }), function (err, stats) {
468 if (err) throw new gutil.PluginError("webpack", err);
469 })
470 .plugin("done", function () {
471 if (allowLog)
472 console.log('bundle completed - ' + filePath);
473 if (callBack !== undefined)
474 callBack();
475 });
476 }
477 else {
478 if (callBack !== undefined)
479 callBack();
480 }
481
482 function checkResolveSelfModule(content) {
483 return content.indexOf('.OmniaControl({') > -1
484 || content.indexOf('.OmniaAdminControl({') > -1
485 || content.indexOf('.OmniaControlTemplate({') > -1
486 || content.indexOf('.TemplateId(') > -1
487 || content.indexOf('.GlueToolbarItem(') > -1
488 || content.indexOf('.GluePaneContent(') > -1
489 || content.indexOf('.GlueTopbarItem(') > -1
490 || content.indexOf('.GluePaneTab(') > -1
491 || content.indexOf('Extensibility_1.TemplateId') > -1
492 || content.indexOf('Extensibility_1.OmniaControl') > -1
493 || content.indexOf('<<webpack-resolve-module>>') > -1
494 }
495}
496
497function isMatchIgnoreFiles(ignoreFiles, filePath) {
498 var isMatch = false
499 for (var i = 0; i < ignoreFiles.length; i++) {
500 if (filePath.indexOf(ignoreFiles[i]) > -1) {
501 isMatch = true;
502 return isMatch;
503 }
504 }
505
506 return isMatch;
507}
508
509function enableRunAot() {
510 var result = true;
511 var processPath = process.cwd().replace(/\\/g, "/");
512
513 if (fs.existsSync(processPath + '/environment.json')) {
514 try {
515 var config = require(processPath + '/environment.json');
516 if (config.Angular && config.Angular && config.Angular.AOT && config.Angular.AOT.RunOnBuild === false)
517 result = false
518 }
519 catch (err) {
520 console.log(err);
521 }
522 }
523
524 return result;
525}
526
527function mergeConfig() {
528 appConfig = require('./config/app.json');
529 var config = core.getConfig('/TaskRunner/Tasks/Angular/task.config.json');
530 if (config !== null)
531 utils.extend(appConfig, config)
532}