1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var events_1 = require("events");
|
4 | var path_1 = require("path");
|
5 | var webpackApi = require("webpack");
|
6 | var logger_1 = require("./logger/logger");
|
7 | var config_1 = require("./util/config");
|
8 | var Constants = require("./util/constants");
|
9 | var errors_1 = require("./util/errors");
|
10 | var events_2 = require("./util/events");
|
11 | var helpers_1 = require("./util/helpers");
|
12 | var interfaces_1 = require("./util/interfaces");
|
13 | var eventEmitter = new events_1.EventEmitter();
|
14 | var INCREMENTAL_BUILD_FAILED = 'incremental_build_failed';
|
15 | var INCREMENTAL_BUILD_SUCCESS = 'incremental_build_success';
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | var pendingPromises = [];
|
26 | function webpack(context, configFile) {
|
27 | configFile = config_1.getUserConfigFile(context, taskInfo, configFile);
|
28 | var logger = new logger_1.Logger('webpack');
|
29 | return webpackWorker(context, configFile)
|
30 | .then(function () {
|
31 | context.bundleState = interfaces_1.BuildState.SuccessfulBuild;
|
32 | logger.finish();
|
33 | })
|
34 | .catch(function (err) {
|
35 | context.bundleState = interfaces_1.BuildState.RequiresBuild;
|
36 | throw logger.fail(err);
|
37 | });
|
38 | }
|
39 | exports.webpack = webpack;
|
40 | function webpackUpdate(changedFiles, context, configFile) {
|
41 | var logger = new logger_1.Logger('webpack update');
|
42 | var webpackConfig = getWebpackConfig(context, configFile);
|
43 | logger_1.Logger.debug('webpackUpdate: Starting Incremental Build');
|
44 | var promisetoReturn = runWebpackIncrementalBuild(false, context, webpackConfig);
|
45 | events_2.emit(events_2.EventType.WebpackFilesChanged, null);
|
46 | return promisetoReturn.then(function (stats) {
|
47 |
|
48 | pendingPromises = [];
|
49 | logger_1.Logger.debug('webpackUpdate: Incremental Build Done, processing Data');
|
50 | return webpackBuildComplete(stats, context, webpackConfig);
|
51 | }).then(function () {
|
52 | context.bundleState = interfaces_1.BuildState.SuccessfulBuild;
|
53 | return logger.finish();
|
54 | }).catch(function (err) {
|
55 | context.bundleState = interfaces_1.BuildState.RequiresBuild;
|
56 | if (err instanceof errors_1.IgnorableError) {
|
57 | throw err;
|
58 | }
|
59 | throw logger.fail(err);
|
60 | });
|
61 | }
|
62 | exports.webpackUpdate = webpackUpdate;
|
63 | function webpackWorker(context, configFile) {
|
64 | var webpackConfig = getWebpackConfig(context, configFile);
|
65 | var promise = null;
|
66 | if (context.isWatch) {
|
67 | promise = runWebpackIncrementalBuild(!context.webpackWatch, context, webpackConfig);
|
68 | }
|
69 | else {
|
70 | promise = runWebpackFullBuild(webpackConfig);
|
71 | }
|
72 | return promise
|
73 | .then(function (stats) {
|
74 | return webpackBuildComplete(stats, context, webpackConfig);
|
75 | });
|
76 | }
|
77 | exports.webpackWorker = webpackWorker;
|
78 | function webpackBuildComplete(stats, context, webpackConfig) {
|
79 | if (helpers_1.getBooleanPropertyValue(Constants.ENV_PRINT_WEBPACK_DEPENDENCY_TREE)) {
|
80 | logger_1.Logger.debug('Webpack Dependency Map Start');
|
81 | var dependencyMap = helpers_1.webpackStatsToDependencyMap(context, stats);
|
82 | helpers_1.printDependencyMap(dependencyMap);
|
83 | logger_1.Logger.debug('Webpack Dependency Map End');
|
84 | }
|
85 |
|
86 |
|
87 | var files = [];
|
88 | stats.compilation.modules.forEach(function (webpackModule) {
|
89 | if (webpackModule.resource) {
|
90 | files.push(webpackModule.resource);
|
91 | }
|
92 | else if (webpackModule.context) {
|
93 | files.push(webpackModule.context);
|
94 | }
|
95 | else if (webpackModule.fileDependencies) {
|
96 | webpackModule.fileDependencies.forEach(function (filePath) {
|
97 | files.push(filePath);
|
98 | });
|
99 | }
|
100 | });
|
101 | var trimmedFiles = files.filter(function (file) { return file && file.length > 0; });
|
102 | context.moduleFiles = trimmedFiles;
|
103 | return setBundledFiles(context);
|
104 | }
|
105 | function setBundledFiles(context) {
|
106 | var bundledFilesToWrite = context.fileCache.getAll().filter(function (file) {
|
107 | return path_1.dirname(file.path).indexOf(context.buildDir) >= 0 && (file.path.endsWith('.js') || file.path.endsWith('.js.map'));
|
108 | });
|
109 | context.bundledFilePaths = bundledFilesToWrite.map(function (bundledFile) { return bundledFile.path; });
|
110 | }
|
111 | exports.setBundledFiles = setBundledFiles;
|
112 | function runWebpackFullBuild(config) {
|
113 | return new Promise(function (resolve, reject) {
|
114 | var callback = function (err, stats) {
|
115 | if (err) {
|
116 | reject(new errors_1.BuildError(err));
|
117 | }
|
118 | else {
|
119 | var info = stats.toJson();
|
120 | if (stats.hasErrors()) {
|
121 | reject(new errors_1.BuildError(info.errors));
|
122 | }
|
123 | else if (stats.hasWarnings()) {
|
124 | logger_1.Logger.debug(info.warnings);
|
125 | resolve(stats);
|
126 | }
|
127 | else {
|
128 | resolve(stats);
|
129 | }
|
130 | }
|
131 | };
|
132 | var compiler = webpackApi(config);
|
133 | compiler.run(callback);
|
134 | });
|
135 | }
|
136 | exports.runWebpackFullBuild = runWebpackFullBuild;
|
137 | function runWebpackIncrementalBuild(initializeWatch, context, config) {
|
138 | var promise = new Promise(function (resolve, reject) {
|
139 |
|
140 | eventEmitter.on(INCREMENTAL_BUILD_FAILED, function (err) {
|
141 | logger_1.Logger.debug('Webpack Bundle Update Failed');
|
142 | eventEmitter.removeAllListeners();
|
143 | handleWebpackBuildFailure(resolve, reject, err, promise, pendingPromises);
|
144 | });
|
145 | eventEmitter.on(INCREMENTAL_BUILD_SUCCESS, function (stats) {
|
146 | logger_1.Logger.debug('Webpack Bundle Updated');
|
147 | eventEmitter.removeAllListeners();
|
148 | handleWebpackBuildSuccess(resolve, reject, stats, promise, pendingPromises);
|
149 | });
|
150 | if (initializeWatch) {
|
151 | startWebpackWatch(context, config);
|
152 | }
|
153 | });
|
154 | pendingPromises.push(promise);
|
155 | return promise;
|
156 | }
|
157 | function handleWebpackBuildFailure(resolve, reject, error, promise, pendingPromises) {
|
158 |
|
159 | if (pendingPromises.length > 0 && pendingPromises[pendingPromises.length - 1] === promise) {
|
160 |
|
161 | reject(new errors_1.BuildError(error));
|
162 | return;
|
163 | }
|
164 |
|
165 | reject(new errors_1.IgnorableError());
|
166 | }
|
167 | function handleWebpackBuildSuccess(resolve, reject, stats, promise, pendingPromises) {
|
168 |
|
169 | if (pendingPromises.length > 0 && pendingPromises[pendingPromises.length - 1] === promise) {
|
170 | logger_1.Logger.debug('handleWebpackBuildSuccess: Resolving with Webpack data');
|
171 | resolve(stats);
|
172 | return;
|
173 | }
|
174 |
|
175 | logger_1.Logger.debug('handleWebpackBuildSuccess: Rejecting with ignorable error');
|
176 | reject(new errors_1.IgnorableError());
|
177 | }
|
178 | function startWebpackWatch(context, config) {
|
179 | logger_1.Logger.debug('Starting Webpack watch');
|
180 | var compiler = webpackApi(config);
|
181 | context.webpackWatch = compiler.watch({}, function (err, stats) {
|
182 | if (err) {
|
183 | eventEmitter.emit(INCREMENTAL_BUILD_FAILED, err);
|
184 | }
|
185 | else {
|
186 | eventEmitter.emit(INCREMENTAL_BUILD_SUCCESS, stats);
|
187 | }
|
188 | });
|
189 | }
|
190 | function getWebpackConfig(context, configFile) {
|
191 | configFile = config_1.getUserConfigFile(context, taskInfo, configFile);
|
192 | var webpackConfigDictionary = config_1.fillConfigDefaults(configFile, taskInfo.defaultConfigFile);
|
193 | var webpackConfig = getWebpackConfigFromDictionary(context, webpackConfigDictionary);
|
194 | webpackConfig.entry = config_1.replacePathVars(context, webpackConfig.entry);
|
195 | webpackConfig.output.path = config_1.replacePathVars(context, webpackConfig.output.path);
|
196 | return webpackConfig;
|
197 | }
|
198 | exports.getWebpackConfig = getWebpackConfig;
|
199 | function getWebpackConfigFromDictionary(context, webpackConfigDictionary) {
|
200 |
|
201 | if (context.runAot) {
|
202 | return webpackConfigDictionary['prod'];
|
203 | }
|
204 | return webpackConfigDictionary['dev'];
|
205 | }
|
206 | exports.getWebpackConfigFromDictionary = getWebpackConfigFromDictionary;
|
207 | function getOutputDest(context) {
|
208 | var webpackConfig = getWebpackConfig(context, null);
|
209 | return path_1.join(webpackConfig.output.path, webpackConfig.output.filename);
|
210 | }
|
211 | exports.getOutputDest = getOutputDest;
|
212 | var taskInfo = {
|
213 | fullArg: '--webpack',
|
214 | shortArg: '-w',
|
215 | envVar: 'IONIC_WEBPACK',
|
216 | packageConfig: 'ionic_webpack',
|
217 | defaultConfigFile: 'webpack.config'
|
218 | };
|