Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit d26b44c

Browse files
committed
fix(source-maps): always generate source map, then purge them if not needed in postprocess step
1 parent 02dfff8 commit d26b44c

File tree

10 files changed

+176
-31
lines changed

10 files changed

+176
-31
lines changed

config/rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var rollupConfig = {
1919
* sourceMap: If true, a separate sourcemap file will
2020
* be created.
2121
*/
22-
sourceMap: process.env.IONIC_GENERATE_SOURCE_MAP === 'true' ? true : false,
22+
sourceMap: true,
2323

2424
/**
2525
* format: The format of the generated bundle

config/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module.exports = {
1010
filename: '[name].js',
1111
devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
1212
},
13-
devtool: process.env.IONIC_GENERATE_SOURCE_MAP === 'true' ? process.env.IONIC_SOURCE_MAP_TYPE : '',
13+
devtool: process.env.IONIC_SOURCE_MAP_TYPE,
1414

1515
resolve: {
1616
extensions: ['.ts', '.js', '.json'],

src/build.spec.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as clean from './clean';
99
import * as lint from './lint';
1010
import * as minify from './minify';
1111
import * as ngc from './ngc';
12+
import * as postprocess from './postprocess';
1213
import * as preprocess from './preprocess';
1314
import * as sass from './sass';
1415
import * as transpile from './transpile';
@@ -26,15 +27,16 @@ describe('build', () => {
2627
});
2728

2829

29-
spyOn(bundle, 'bundle').and.returnValue(Promise.resolve());
30-
spyOn(copy, 'copy').and.returnValue(Promise.resolve());
31-
spyOn(minify, 'minifyCss').and.returnValue(Promise.resolve());
32-
spyOn(minify, 'minifyJs').and.returnValue(Promise.resolve());
33-
spyOn(lint, 'lint').and.returnValue(Promise.resolve());
34-
spyOn(ngc, 'ngc').and.returnValue(Promise.resolve());
35-
spyOn(preprocess, 'preprocess').and.returnValue(Promise.resolve());
36-
spyOn(sass, 'sass').and.returnValue(Promise.resolve());
37-
spyOn(transpile, 'transpile').and.returnValue(Promise.resolve());
30+
spyOn(bundle, bundle.bundle.name).and.returnValue(Promise.resolve());
31+
spyOn(copy, copy.copy.name).and.returnValue(Promise.resolve());
32+
spyOn(minify, minify.minifyCss.name).and.returnValue(Promise.resolve());
33+
spyOn(minify, minify.minifyJs.name).and.returnValue(Promise.resolve());
34+
spyOn(lint, lint.lint.name).and.returnValue(Promise.resolve());
35+
spyOn(ngc, ngc.ngc.name).and.returnValue(Promise.resolve());
36+
spyOn(postprocess, postprocess.postprocess.name).and.returnValue(Promise.resolve());
37+
spyOn(preprocess, preprocess.preprocess.name).and.returnValue(Promise.resolve());
38+
spyOn(sass, sass.sass.name).and.returnValue(Promise.resolve());
39+
spyOn(transpile, transpile.transpile.name).and.returnValue(Promise.resolve());
3840
});
3941

4042
it('should do a prod build', () => {
@@ -79,6 +81,7 @@ describe('build', () => {
7981
expect(bundle.bundle).toHaveBeenCalled();
8082
expect(sass.sass).toHaveBeenCalled();
8183
expect(lint.lint).toHaveBeenCalled();
84+
expect(postprocess.postprocess).toHaveBeenCalled();
8285
expect(preprocess.preprocess).toHaveBeenCalled();
8386
expect(ngc.ngc).not.toHaveBeenCalled();
8487
expect(minify.minifyJs).not.toHaveBeenCalled();
@@ -162,17 +165,18 @@ describe('test project requirements before building', () => {
162165
process.env[Constants.ENV_APP_ENTRY_POINT] = 'src/app/main.ts';
163166
process.env[Constants.ENV_TS_CONFIG] = 'tsConfig.js';
164167

165-
spyOn(bundle, 'bundle').and.returnValue(Promise.resolve());
166-
spyOn(clean, 'clean');
167-
spyOn(copy, 'copy').and.returnValue(Promise.resolve());
168-
spyOn(minify, 'minifyCss').and.returnValue(Promise.resolve());
169-
spyOn(minify, 'minifyJs').and.returnValue(Promise.resolve());
170-
spyOn(lint, 'lint').and.returnValue(Promise.resolve());
171-
spyOn(ngc, 'ngc').and.returnValue(Promise.resolve());
172-
spyOn(preprocess, 'preprocess').and.returnValue(Promise.resolve());
173-
spyOn(sass, 'sass').and.returnValue(Promise.resolve());
174-
spyOn(transpile, 'transpile').and.returnValue(Promise.resolve());
175-
spyOn(helpers, 'readFileAsync').and.callFake(() => {
168+
spyOn(bundle, bundle.bundle.name).and.returnValue(Promise.resolve());
169+
spyOn(clean, clean.clean.name);
170+
spyOn(copy, copy.copy.name).and.returnValue(Promise.resolve());
171+
spyOn(minify, minify.minifyCss.name).and.returnValue(Promise.resolve());
172+
spyOn(minify, minify.minifyJs.name).and.returnValue(Promise.resolve());
173+
spyOn(lint, lint.lint.name).and.returnValue(Promise.resolve());
174+
spyOn(ngc, ngc.ngc.name).and.returnValue(Promise.resolve());
175+
spyOn(postprocess, postprocess.postprocess.name).and.returnValue(Promise.resolve());
176+
spyOn(preprocess, preprocess.preprocess.name).and.returnValue(Promise.resolve());
177+
spyOn(sass, sass.sass.name).and.returnValue(Promise.resolve());
178+
spyOn(transpile, transpile.transpile.name).and.returnValue(Promise.resolve());
179+
spyOn(helpers, helpers.readFileAsync.name).and.callFake(() => {
176180
return Promise.resolve(`{
177181
"compilerOptions": {
178182
"sourceMap": true

src/build.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import * as Constants from './util/constants';
22
import { BuildContext, BuildState, BuildUpdateMessage, ChangedFile } from './util/interfaces';
33
import { BuildError } from './util/errors';
44
import { emit, EventType } from './util/events';
5-
import { readFileAsync, setContext } from './util/helpers';
5+
import { getBooleanPropertyValue, readFileAsync, setContext } from './util/helpers';
66
import { bundle, bundleUpdate } from './bundle';
77
import { clean } from './clean';
88
import { copy } from './copy';
99
import { lint, lintUpdate } from './lint';
1010
import { Logger } from './logger/logger';
1111
import { minifyCss, minifyJs } from './minify';
1212
import { ngc } from './ngc';
13+
import { postprocess } from './postprocess';
1314
import { preprocess, preprocessUpdate } from './preprocess';
1415
import { sass, sassUpdate } from './sass';
1516
import { templateUpdate } from './template';
@@ -42,6 +43,8 @@ function buildWorker(context: BuildContext) {
4243
return preprocess(context);
4344
}).then(() => {
4445
return buildProject(context);
46+
}).then(() => {
47+
return postprocess(context);
4548
});
4649
}
4750

@@ -122,8 +125,11 @@ function buildProject(context: BuildContext) {
122125
})
123126
.then(() => {
124127
// kick off the tslint after everything else
125-
// nothing needs to wait on its completion
126-
return lint(context);
128+
// nothing needs to wait on its completion unless bailing on lint error is enabled
129+
const result = lint(context);
130+
if (getBooleanPropertyValue(Constants.ENV_BAIL_ON_LINT_ERROR)) {
131+
return result;
132+
}
127133
})
128134
.catch(err => {
129135
throw new BuildError(err);

src/postprocess.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Logger } from './logger/logger';
2+
import { BuildContext } from './util/interfaces';
3+
import { purgeSourceMapsIfNeeded } from './util/source-maps';
4+
5+
6+
export function postprocess(context: BuildContext) {
7+
const logger = new Logger(`postprocess`);
8+
return postprocessWorker(context).then(() => {
9+
logger.finish();
10+
})
11+
.catch((err: Error) => {
12+
throw logger.fail(err);
13+
});
14+
}
15+
16+
17+
function postprocessWorker(context: BuildContext) {
18+
return purgeSourceMapsIfNeeded(context);
19+
}

src/uglifyjs.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { BuildContext, TaskInfo } from './util/interfaces';
2-
import { BuildError } from './util/errors';
3-
import { fillConfigDefaults, generateContext, getUserConfigFile } from './util/config';
41
import { join } from 'path';
2+
import * as uglify from 'uglify-js';
3+
54
import { Logger } from './logger/logger';
5+
import { fillConfigDefaults, generateContext, getUserConfigFile } from './util/config';
6+
import * as Constants from './util/constants';
7+
import { BuildError } from './util/errors';
8+
import { getBooleanPropertyValue, writeFileAsync } from './util/helpers';
9+
import { BuildContext, TaskInfo } from './util/interfaces';
610
import { runWorker } from './worker-client';
7-
import { writeFileAsync } from './util/helpers';
8-
import * as uglify from 'uglify-js';
11+
912

1013

1114
export function uglifyjs(context: BuildContext, configFile?: string) {

src/util/helpers.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as helpers from './helpers';
2+
3+
describe('helpers', () => {
4+
describe('getBooleanPropertyValue', () => {
5+
it('should return true when value is "true"', () => {
6+
// arrange
7+
const propertyName = 'test';
8+
const propertyValue = 'true';
9+
let environment: any = { };
10+
environment[propertyName] = propertyValue;
11+
process.env = environment;
12+
// act
13+
const result = helpers.getBooleanPropertyValue(propertyName);
14+
// assert
15+
expect(result).toEqual(true);
16+
});
17+
18+
it('should return false when value is undefined/null', () => {
19+
// arrange
20+
const propertyName = 'test';
21+
let environment: any = { };
22+
process.env = environment;
23+
// act
24+
const result = helpers.getBooleanPropertyValue(propertyName);
25+
// assert
26+
expect(result).toEqual(false);
27+
});
28+
29+
it('should return false when value is not "true"', () => {
30+
// arrange
31+
const propertyName = 'test';
32+
const propertyValue = 'taco';
33+
let environment: any = { };
34+
environment[propertyName] = propertyValue;
35+
process.env = environment;
36+
// act
37+
const result = helpers.getBooleanPropertyValue(propertyName);
38+
// assert
39+
expect(result).toEqual(false);
40+
});
41+
});
42+
});

src/util/helpers.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { randomBytes } from 'crypto';
22
import { basename, dirname, extname, join } from 'path';
33
import { BuildContext, File, HydratedDeepLinkConfigEntry } from './interfaces';
4-
import { createReadStream, createWriteStream, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
4+
import { createReadStream, createWriteStream, readdir, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
55
import * as osName from 'os-name';
66

77
let _context: BuildContext;
@@ -155,6 +155,17 @@ export function copyFileAsync(srcPath: string, destPath: string): Promise<any> {
155155
});
156156
}
157157

158+
export function readDirAsync(pathToDir: string): Promise<string[]> {
159+
return new Promise((resolve, reject) => {
160+
readdir(pathToDir, (err: Error, fileNames: string[]) => {
161+
if (err) {
162+
return reject(err);
163+
}
164+
resolve(fileNames);
165+
});
166+
});
167+
}
168+
158169
export function createFileObject(filePath: string): File {
159170
const content = readFileSync(filePath).toString();
160171
return {

src/util/source-maps.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { join } from 'path';
2+
import * as Constants from './constants';
3+
import * as sourceMaps from './source-maps';
4+
import * as helpers from './helpers';
5+
6+
describe('source maps', () => {
7+
describe('purgeSourceMapsIfNeeded', () => {
8+
it('should return a resolved promise when purging source maps isnt needed', () => {
9+
// arrange
10+
let env: any = {};
11+
env[Constants.ENV_VAR_GENERATE_SOURCE_MAP] = 'true';
12+
process.env = env;
13+
// act
14+
const resultPromise = sourceMaps.purgeSourceMapsIfNeeded(null);
15+
// assert
16+
return resultPromise;
17+
});
18+
19+
it('should return a promise call unlink on all files with a .map extensin', () => {
20+
// arrange
21+
let env: any = {};
22+
env[Constants.ENV_VAR_GENERATE_SOURCE_MAP] = null;
23+
process.env = env;
24+
const buildDir = '/some/fake/build/dir';
25+
const context = { buildDir: buildDir };
26+
27+
spyOn(helpers, helpers.readDirAsync.name).and.returnValue(Promise.resolve(['test.js', 'test.js.map', 'test2.js', 'test2.js.map']));
28+
const unlinkSpy = spyOn(helpers, helpers.unlinkAsync.name).and.returnValue(Promise.resolve());
29+
30+
// act
31+
const resultPromise = sourceMaps.purgeSourceMapsIfNeeded(context);
32+
33+
// assert
34+
return resultPromise.then(() => {
35+
expect(unlinkSpy.calls.argsFor(0)[0]).toEqual(join(buildDir, 'test.js.map'));
36+
expect(unlinkSpy.calls.argsFor(1)[0]).toEqual(join(buildDir, 'test2.js.map'));
37+
});
38+
});
39+
});
40+
});

src/util/source-maps.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { join } from 'path';
2+
import * as Constants from './constants';
3+
import { getBooleanPropertyValue, readDirAsync, unlinkAsync } from './helpers';
4+
import { BuildContext } from './interfaces';
5+
6+
export function purgeSourceMapsIfNeeded(context: BuildContext) {
7+
if (getBooleanPropertyValue(Constants.ENV_VAR_GENERATE_SOURCE_MAP)) {
8+
// keep the source maps and just return
9+
return Promise.resolve();
10+
}
11+
return readDirAsync(context.buildDir).then((fileNames: string[]) => {
12+
const sourceMaps = fileNames.filter(fileName => fileName.endsWith('.map'));
13+
const fullPaths = sourceMaps.map(sourceMap => join(context.buildDir, sourceMap));
14+
const promises: Promise<any>[] = [];
15+
for (const fullPath of fullPaths) {
16+
promises.push(unlinkAsync(fullPath));
17+
}
18+
return Promise.all(promises);
19+
});
20+
}

0 commit comments

Comments
 (0)