UNPKG

14.6 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10var __generator = (this && this.__generator) || function (thisArg, body) {
11 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13 function verb(n) { return function (v) { return step([n, v]); }; }
14 function step(op) {
15 if (f) throw new TypeError("Generator is already executing.");
16 while (_) try {
17 if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
18 if (y = 0, t) op = [0, t.value];
19 switch (op[0]) {
20 case 0: case 1: t = op; break;
21 case 4: _.label++; return { value: op[1], done: false };
22 case 5: _.label++; y = op[1]; op = [0]; continue;
23 case 7: op = _.ops.pop(); _.trys.pop(); continue;
24 default:
25 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29 if (t[2]) _.ops.pop();
30 _.trys.pop(); continue;
31 }
32 op = body.call(thisArg, _);
33 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35 }
36};
37Object.defineProperty(exports, "__esModule", { value: true });
38var util_1 = require("./build/util");
39var bundle_1 = require("./bundle");
40var clean_1 = require("./clean");
41var copy_1 = require("./copy");
42var deep_linking_1 = require("./deep-linking");
43var lint_1 = require("./lint");
44var logger_1 = require("./logger/logger");
45var minify_1 = require("./minify");
46var ngc_1 = require("./ngc");
47var postprocess_1 = require("./postprocess");
48var preprocess_1 = require("./preprocess");
49var sass_1 = require("./sass");
50var template_1 = require("./template");
51var transpile_1 = require("./transpile");
52var Constants = require("./util/constants");
53var errors_1 = require("./util/errors");
54var events_1 = require("./util/events");
55var helpers_1 = require("./util/helpers");
56var interfaces_1 = require("./util/interfaces");
57function build(context) {
58 helpers_1.setContext(context);
59 var logger = new logger_1.Logger("build " + (context.isProd ? 'prod' : 'dev'));
60 return buildWorker(context)
61 .then(function () {
62 // congrats, we did it! (•_•) / ( •_•)>⌐■-■ / (⌐■_■)
63 logger.finish();
64 })
65 .catch(function (err) {
66 if (err.isFatal) {
67 throw err;
68 }
69 throw logger.fail(err);
70 });
71}
72exports.build = build;
73function buildWorker(context) {
74 return __awaiter(this, void 0, void 0, function () {
75 var promises, results, tsConfigContents;
76 return __generator(this, function (_a) {
77 switch (_a.label) {
78 case 0:
79 promises = [];
80 promises.push(util_1.validateRequiredFilesExist(context));
81 promises.push(util_1.readVersionOfDependencies(context));
82 return [4 /*yield*/, Promise.all(promises)];
83 case 1:
84 results = _a.sent();
85 tsConfigContents = results[0][1];
86 return [4 /*yield*/, util_1.validateTsConfigSettings(tsConfigContents)];
87 case 2:
88 _a.sent();
89 return [4 /*yield*/, buildProject(context)];
90 case 3:
91 _a.sent();
92 return [2 /*return*/];
93 }
94 });
95 });
96}
97function buildProject(context) {
98 // sync empty the www/build directory
99 clean_1.clean(context);
100 buildId++;
101 var copyPromise = copy_1.copy(context);
102 return util_1.scanSrcTsFiles(context)
103 .then(function () {
104 if (helpers_1.getBooleanPropertyValue(Constants.ENV_PARSE_DEEPLINKS)) {
105 return deep_linking_1.deepLinking(context);
106 }
107 })
108 .then(function () {
109 var compilePromise = (context.runAot) ? ngc_1.ngc(context) : transpile_1.transpile(context);
110 return compilePromise;
111 })
112 .then(function () {
113 return preprocess_1.preprocess(context);
114 })
115 .then(function () {
116 return bundle_1.bundle(context);
117 })
118 .then(function () {
119 var minPromise = (context.runMinifyJs) ? minify_1.minifyJs(context) : Promise.resolve();
120 var sassPromise = sass_1.sass(context)
121 .then(function () {
122 return (context.runMinifyCss) ? minify_1.minifyCss(context) : Promise.resolve();
123 });
124 return Promise.all([
125 minPromise,
126 sassPromise,
127 copyPromise
128 ]);
129 })
130 .then(function () {
131 return postprocess_1.postprocess(context);
132 })
133 .then(function () {
134 if (helpers_1.getBooleanPropertyValue(Constants.ENV_ENABLE_LINT)) {
135 // kick off the tslint after everything else
136 // nothing needs to wait on its completion unless bailing on lint error is enabled
137 var result = lint_1.lint(context, null, false);
138 if (helpers_1.getBooleanPropertyValue(Constants.ENV_BAIL_ON_LINT_ERROR)) {
139 return result;
140 }
141 }
142 })
143 .catch(function (err) {
144 throw new errors_1.BuildError(err);
145 });
146}
147function buildUpdate(changedFiles, context) {
148 return new Promise(function (resolve) {
149 var logger = new logger_1.Logger('build');
150 buildId++;
151 var buildUpdateMsg = {
152 buildId: buildId,
153 reloadApp: false
154 };
155 events_1.emit(events_1.EventType.BuildUpdateStarted, buildUpdateMsg);
156 function buildTasksDone(resolveValue) {
157 // all build tasks have been resolved or one of them
158 // bailed early, stopping all others to not run
159 parallelTasksPromise.then(function () {
160 // all parallel tasks are also done
161 // so now we're done done
162 var buildUpdateMsg = {
163 buildId: buildId,
164 reloadApp: resolveValue.requiresAppReload
165 };
166 events_1.emit(events_1.EventType.BuildUpdateCompleted, buildUpdateMsg);
167 if (!resolveValue.requiresAppReload) {
168 // just emit that only a certain file changed
169 // this one is useful when only a sass changed happened
170 // and the webpack only needs to livereload the css
171 // but does not need to do a full page refresh
172 events_1.emit(events_1.EventType.FileChange, resolveValue.changedFiles);
173 }
174 var requiresLintUpdate = false;
175 for (var _i = 0, changedFiles_1 = changedFiles; _i < changedFiles_1.length; _i++) {
176 var changedFile = changedFiles_1[_i];
177 if (changedFile.ext === '.ts') {
178 if (changedFile.event === 'change' || changedFile.event === 'add') {
179 requiresLintUpdate = true;
180 break;
181 }
182 }
183 }
184 if (requiresLintUpdate) {
185 // a ts file changed, so let's lint it too, however
186 // this task should run as an after thought
187 if (helpers_1.getBooleanPropertyValue(Constants.ENV_ENABLE_LINT)) {
188 lint_1.lintUpdate(changedFiles, context, false);
189 }
190 }
191 logger.finish('green', true);
192 logger_1.Logger.newLine();
193 // we did it!
194 resolve();
195 });
196 }
197 // kick off all the build tasks
198 // and the tasks that can run parallel to all the build tasks
199 var buildTasksPromise = buildUpdateTasks(changedFiles, context);
200 var parallelTasksPromise = buildUpdateParallelTasks(changedFiles, context);
201 // whether it was resolved or rejected, we need to do the same thing
202 buildTasksPromise
203 .then(buildTasksDone)
204 .catch(function () {
205 buildTasksDone({
206 requiresAppReload: false,
207 changedFiles: changedFiles
208 });
209 });
210 });
211}
212exports.buildUpdate = buildUpdate;
213/**
214 * Collection of all the build tasks than need to run
215 * Each task will only run if it's set with eacn BuildState.
216 */
217function buildUpdateTasks(changedFiles, context) {
218 var resolveValue = {
219 requiresAppReload: false,
220 changedFiles: []
221 };
222 return loadFiles(changedFiles, context)
223 .then(function () {
224 // DEEP LINKING
225 if (helpers_1.getBooleanPropertyValue(Constants.ENV_PARSE_DEEPLINKS)) {
226 return deep_linking_1.deepLinkingUpdate(changedFiles, context);
227 }
228 })
229 .then(function () {
230 // TEMPLATE
231 if (context.templateState === interfaces_1.BuildState.RequiresUpdate) {
232 resolveValue.requiresAppReload = true;
233 return template_1.templateUpdate(changedFiles, context);
234 }
235 // no template updates required
236 return Promise.resolve();
237 })
238 .then(function () {
239 // TRANSPILE
240 if (context.transpileState === interfaces_1.BuildState.RequiresUpdate) {
241 resolveValue.requiresAppReload = true;
242 // we've already had a successful transpile once, only do an update
243 // not that we've also already started a transpile diagnostics only
244 // build that only needs to be completed by the end of buildUpdate
245 return transpile_1.transpileUpdate(changedFiles, context);
246 }
247 else if (context.transpileState === interfaces_1.BuildState.RequiresBuild) {
248 // run the whole transpile
249 resolveValue.requiresAppReload = true;
250 return transpile_1.transpile(context);
251 }
252 // no transpiling required
253 return Promise.resolve();
254 })
255 .then(function () {
256 // PREPROCESS
257 return preprocess_1.preprocessUpdate(changedFiles, context);
258 })
259 .then(function () {
260 // BUNDLE
261 if (context.bundleState === interfaces_1.BuildState.RequiresUpdate) {
262 // we need to do a bundle update
263 resolveValue.requiresAppReload = true;
264 return bundle_1.bundleUpdate(changedFiles, context);
265 }
266 else if (context.bundleState === interfaces_1.BuildState.RequiresBuild) {
267 // we need to do a full bundle build
268 resolveValue.requiresAppReload = true;
269 return bundle_1.bundle(context);
270 }
271 // no bundling required
272 return Promise.resolve();
273 })
274 .then(function () {
275 // SASS
276 if (context.sassState === interfaces_1.BuildState.RequiresUpdate) {
277 // we need to do a sass update
278 return sass_1.sassUpdate(changedFiles, context).then(function (outputCssFile) {
279 var changedFile = {
280 event: Constants.FILE_CHANGE_EVENT,
281 ext: '.css',
282 filePath: outputCssFile
283 };
284 context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile });
285 resolveValue.changedFiles.push(changedFile);
286 });
287 }
288 else if (context.sassState === interfaces_1.BuildState.RequiresBuild) {
289 // we need to do a full sass build
290 return sass_1.sass(context).then(function (outputCssFile) {
291 var changedFile = {
292 event: Constants.FILE_CHANGE_EVENT,
293 ext: '.css',
294 filePath: outputCssFile
295 };
296 context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile });
297 resolveValue.changedFiles.push(changedFile);
298 });
299 }
300 // no sass build required
301 return Promise.resolve();
302 })
303 .then(function () {
304 return resolveValue;
305 });
306}
307function loadFiles(changedFiles, context) {
308 // UPDATE IN-MEMORY FILE CACHE
309 var promises = [];
310 var _loop_1 = function (changedFile) {
311 if (changedFile.event === Constants.FILE_DELETE_EVENT) {
312 // remove from the cache on delete
313 context.fileCache.remove(changedFile.filePath);
314 }
315 else {
316 // load the latest since the file changed
317 var promise = helpers_1.readFileAsync(changedFile.filePath);
318 promises.push(promise);
319 promise.then(function (content) {
320 context.fileCache.set(changedFile.filePath, { path: changedFile.filePath, content: content });
321 });
322 }
323 };
324 for (var _i = 0, changedFiles_2 = changedFiles; _i < changedFiles_2.length; _i++) {
325 var changedFile = changedFiles_2[_i];
326 _loop_1(changedFile);
327 }
328 return Promise.all(promises);
329}
330/**
331 * parallelTasks are for any tasks that can run parallel to the entire
332 * build, but we still need to make sure they've completed before we're
333 * all done, it's also possible there are no parallelTasks at all
334 */
335function buildUpdateParallelTasks(changedFiles, context) {
336 var parallelTasks = [];
337 if (context.transpileState === interfaces_1.BuildState.RequiresUpdate) {
338 parallelTasks.push(transpile_1.transpileDiagnosticsOnly(context));
339 }
340 return Promise.all(parallelTasks);
341}
342var buildId = 0;