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

Commit 1dedc53

Browse files
committed
fix(optimizations): comment out code instead of purge it so source-maps don't error out in some edge
comment out code instead of purge it so source-maps don't error out in some edge cases
1 parent 627f5d4 commit 1dedc53

File tree

4 files changed

+110
-54
lines changed

4 files changed

+110
-54
lines changed

src/optimization/decorators.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('optimization', () => {
1616
process.env = originalEnv;
1717
});
1818

19-
it('should purge the decorators', () => {
19+
it('should comment out the decorator statement', () => {
2020
// arrange
2121
const decoratorStatement = `
2222
IonicModule.decorators = [
@@ -247,7 +247,10 @@ some more content
247247

248248
// assert
249249
expect(result).not.toEqual(knownContent);
250-
expect(result.indexOf(decoratorStatement)).toEqual(-1);
250+
const regex = decorators.getDecoratorRegex();
251+
const matches = regex.exec(result);
252+
expect(matches).toBeTruthy();
253+
expect(result.indexOf(`/*${matches[0]}*/`)).toBeGreaterThan(0);
251254
expect(result.indexOf(additionalGeneratedContent)).toBeGreaterThan(-1);
252255
});
253256
});

src/optimization/decorators.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ export function purgeDecorators(filePath: string, fileContent: string) {
88
export function purgeIndexDecorator(filePath: string, fileContent: string) {
99
if (process.env[Constants.ENV_VAR_IONIC_ANGULAR_ENTRY_POINT] === filePath) {
1010
Logger.debug(`Purging index file decorator for ${filePath}`);
11-
return fileContent.replace(DECORATORS_REGEX, '');
11+
const DECORATORS_REGEX = getDecoratorRegex();
12+
const matches = DECORATORS_REGEX.exec(fileContent);
13+
if (matches && matches.length) {
14+
return fileContent.replace(matches[0], `/*${matches[0]}*/`);
15+
}
1216
}
1317
return fileContent;
1418
}
1519

16-
const DECORATORS_REGEX = /IonicModule.decorators.=[\s\S\n]*?([\s\S\n]*?)];/igm;
20+
export function getDecoratorRegex() {
21+
return /IonicModule.decorators.=[\s\S\n]*?([\s\S\n]*?)];/igm;
22+
}

src/optimization/treeshake.spec.ts

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { join } from 'path';
1+
import { join, relative } from 'path';
22
import * as treeshake from './treeshake';
33
import * as Constants from '../util/constants';
4+
import * as helpers from '../util/helpers';
45

56

67
let originalEnv: any = null;
@@ -1207,15 +1208,26 @@ export const AppModuleNgFactory = new import0.NgModuleFactory(AppModuleInjector,
12071208
const componentFactoryPath2 = `/Users/dan/Dev/myApp3/node_modules/ionic-angular/components/alert/alert-component.ngfactory.js`;
12081209

12091210
// act
1210-
let updatedContent = treeshake.purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath, knownContent, componentFactoryPath);
1211-
updatedContent = treeshake.purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath, updatedContent, componentFactoryPath2);
1211+
const updatedContent = treeshake.purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath, knownContent, componentFactoryPath);
1212+
const updatedContentAgain = treeshake.purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath, updatedContent, componentFactoryPath2);
12121213

12131214
// assert
1214-
expect(updatedContent).not.toEqual(knownContent);
1215-
expect(updatedContent.indexOf(knownImport)).toEqual(-1);
1216-
expect(updatedContent.indexOf(knownImport2)).toEqual(-1);
1217-
expect(updatedContent.indexOf(knownImportUsage)).toEqual(-1);
1218-
expect(updatedContent.indexOf(knownImportUsage2)).toEqual(-1);
1215+
expect(updatedContentAgain).not.toEqual(knownContent);
1216+
const knownImportOneRegex = treeshake.generateWildCardImportRegex('../../node_modules/ionic-angular/components/action-sheet/action-sheet-component.ngfactory');
1217+
const knownImportTwoRegex = treeshake.generateWildCardImportRegex('../../node_modules/ionic-angular/components/alert/alert-component.ngfactory');
1218+
const knownImportOneResults = knownImportOneRegex.exec(updatedContentAgain);
1219+
const knownImportTwoResults = knownImportTwoRegex.exec(updatedContentAgain);
1220+
const knownNamedImportOne = knownImportOneResults[1].trim();
1221+
const knownNamedImportTwo = knownImportTwoResults[1].trim();
1222+
expect(updatedContentAgain.indexOf(`/*${knownImportOneResults[0]}*/`)).toBeGreaterThanOrEqual(0);
1223+
expect(updatedContentAgain.indexOf(`/*${knownImportTwoResults[0]}*/`)).toBeGreaterThanOrEqual(0);
1224+
1225+
const removeFromConstructorRegexOne = treeshake.generateRemoveComponentFromConstructorRegex(knownNamedImportOne);
1226+
const removeFromConstructorRegexTwo = treeshake.generateRemoveComponentFromConstructorRegex(knownNamedImportTwo);
1227+
const removeFromConstructorOneResults = removeFromConstructorRegexOne.exec(updatedContentAgain);
1228+
const removeFromConstructorTwoResults = removeFromConstructorRegexTwo.exec(updatedContentAgain);
1229+
expect(updatedContentAgain.indexOf(`/*${removeFromConstructorOneResults[0]}*/`)).toBeGreaterThanOrEqual(0);
1230+
expect(updatedContentAgain.indexOf(`/*${removeFromConstructorTwoResults[0]}*/`)).toBeGreaterThanOrEqual(0);
12191231
});
12201232
});
12211233

@@ -1235,32 +1247,32 @@ export const AppModuleNgFactory = new import0.NgModuleFactory(AppModuleInjector,
12351247
// arrange
12361248

12371249
const ifStatementOne = `
1238-
if ((token === import32.ActionSheetController)) {
1239-
return this._ActionSheetController_54;
1240-
}
1250+
if ((token === import32.ActionSheetController)) {
1251+
return this._ActionSheetController_54;
1252+
}
12411253
`;
12421254
const ifStatementTwo = `
1243-
if ((token === import33.AlertController)) {
1244-
return this._AlertController_55;
1245-
}
1255+
if ((token === import33.AlertController)) {
1256+
return this._AlertController_55;
1257+
}
12461258
`;
12471259

12481260
const getterOne = `
1249-
get _ActionSheetController_54() {
1250-
if ((this.__ActionSheetController_54 == null)) {
1251-
(this.__ActionSheetController_54 = new import32.ActionSheetController(this._App_19, this._Config_16));
1252-
}
1253-
return this.__ActionSheetController_54;
1254-
}
1261+
get _ActionSheetController_54() {
1262+
if ((this.__ActionSheetController_54 == null)) {
1263+
(this.__ActionSheetController_54 = new import32.ActionSheetController(this._App_19, this._Config_16));
1264+
}
1265+
return this.__ActionSheetController_54;
1266+
}
12551267
`;
12561268

12571269
const getterTwo = `
1258-
get _AlertController_55() {
1259-
if ((this.__AlertController_55 == null)) {
1260-
(this.__AlertController_55 = new import33.AlertController(this._App_19, this._Config_16));
1261-
}
1262-
return this.__AlertController_55;
1263-
}
1270+
get _AlertController_55() {
1271+
if ((this.__AlertController_55 == null)) {
1272+
(this.__AlertController_55 = new import33.AlertController(this._App_19, this._Config_16));
1273+
}
1274+
return this.__AlertController_55;
1275+
}
12641276
`;
12651277

12661278
const knownContent = `
@@ -1916,22 +1928,47 @@ export const AppModuleNgFactory = new import0.NgModuleFactory(AppModuleInjector,
19161928
//# sourceMappingURL=app.module.ngfactory.js.map
19171929
`;
19181930

1931+
const nodeModulesPath = '/Users/dan/Dev/myApp3/node_modules';
1932+
19191933
const appModuleNgFactoryPath = `/Users/dan/Dev/myApp3/src/app/app.module.ngfactory.js`;
1920-
const controllerPath = `/Users/dan/Dev/myApp3/node_modules/ionic-angular/components/action-sheet/action-sheet-controller.js`;
1921-
const controllerPath2 = `/Users/dan/Dev/myApp3/node_modules/ionic-angular/components/alert/alert-controller.js`;
1934+
const controllerPath = join(nodeModulesPath, 'ionic-angular', 'components', 'action-sheet', 'action-sheet-controller.js');
1935+
const controllerPath2 = join(nodeModulesPath, 'ionic-angular', 'components', 'alert', 'alert-controller.js');
19221936

19231937
// act
19241938

19251939
let updatedContent = treeshake.purgeProviderControllerImportAndUsage(appModuleNgFactoryPath, knownContent, controllerPath);
1926-
updatedContent = treeshake.purgeProviderControllerImportAndUsage(appModuleNgFactoryPath, knownContent, controllerPath2);
1940+
updatedContent = treeshake.purgeProviderControllerImportAndUsage(appModuleNgFactoryPath, updatedContent, controllerPath2);
19271941

19281942
// assert
19291943
expect(updatedContent).not.toEqual(knownContent);
1930-
/*expect(updatedContent.indexOf(ifStatementOne)).toEqual(-1);
1931-
expect(updatedContent.indexOf(ifStatementTwo)).toEqual(-1);
1932-
expect(updatedContent.indexOf(getterOne)).toEqual(-1);
1933-
expect(updatedContent.indexOf(getterTwo)).toEqual(-1);
1934-
*/
1944+
const relativeImportPathOne = helpers.changeExtension(relative(nodeModulesPath, controllerPath), '');
1945+
const relativeImportPathTwo = helpers.changeExtension(relative(nodeModulesPath, controllerPath2), '');
1946+
1947+
const importRegexOne = treeshake.generateWildCardImportRegex(relativeImportPathOne);
1948+
const importRegexTwo = treeshake.generateWildCardImportRegex(relativeImportPathTwo);
1949+
const importResultOne = importRegexOne.exec(updatedContent);
1950+
const importResultTwo = importRegexTwo.exec(updatedContent);
1951+
expect(updatedContent.indexOf(`/*${importResultOne[0]}*/`)).toBeGreaterThanOrEqual(0);
1952+
expect(updatedContent.indexOf(`/*${importResultTwo[0]}*/`)).toBeGreaterThanOrEqual(0);
1953+
1954+
const namedImportOne = importResultOne[1].trim();
1955+
const namedImportTwo = importResultTwo[1].trim();
1956+
1957+
const purgeGetterRegExOne = treeshake.generateRemoveGetterFromImportRegex(namedImportOne);
1958+
const purgeGetterResultsOne = purgeGetterRegExOne.exec(updatedContent);
1959+
const purgeIfRegExOne = treeshake.generateRemoveIfStatementRegex(namedImportOne);
1960+
const purgeIfResultsOne = purgeIfRegExOne.exec(updatedContent);
1961+
1962+
const purgeGetterRegExTwo = treeshake.generateRemoveGetterFromImportRegex(namedImportTwo);
1963+
1964+
const purgeGetterResultsTwo = purgeGetterRegExTwo.exec(updatedContent);
1965+
const purgeIfRegExTwo = treeshake.generateRemoveIfStatementRegex(namedImportTwo);
1966+
const purgeIfResultsTwo = purgeIfRegExTwo.exec(updatedContent);
1967+
1968+
expect(updatedContent.indexOf(`/*${purgeGetterResultsOne[0]}*/`)).toBeGreaterThanOrEqual(0);
1969+
expect(updatedContent.indexOf(`/*${purgeIfResultsOne[0]}*/`)).toBeGreaterThanOrEqual(0);
1970+
expect(updatedContent.indexOf(`/*${purgeGetterResultsTwo[0]}*/`)).toBeGreaterThanOrEqual(0);
1971+
expect(updatedContent.indexOf(`/*${purgeIfResultsTwo[0]}*/`)).toBeGreaterThanOrEqual(0);
19351972
});
19361973
});
19371974

@@ -1999,8 +2036,12 @@ export const AppModuleNgFactory = new import0.NgModuleFactory(AppModuleInjector,
19992036

20002037
// assert
20012038
expect(updatedContent).not.toEqual(knownContent);
2002-
expect(updatedContent.indexOf(classOne)).toEqual(-1);
2003-
expect(updatedContent.indexOf(classTwo)).toEqual(-1);
2039+
const regexOne = treeshake.generateIonicModulePurgeProviderRegex(classOne);
2040+
const regexTwo = treeshake.generateIonicModulePurgeProviderRegex(classTwo);
2041+
const resultsOne = regexOne.exec(updatedContent);
2042+
const resultsTwo = regexTwo.exec(updatedContent);
2043+
expect(updatedContent.indexOf(`/*${resultsOne[0]}*/`)).toBeGreaterThanOrEqual(0);
2044+
expect(updatedContent.indexOf(`/*${resultsTwo[0]}*/`)).toBeGreaterThanOrEqual(0);
20042045
});
20052046
});
20062047
});

src/optimization/treeshake.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,14 @@ export function purgeUnusedImportsAndExportsFromIndex(indexFilePath: string, ind
171171
// replace the import if it's found
172172
let results: RegExpExecArray = null;
173173
while ((results = importRegex.exec(indexFileContent)) && results.length) {
174-
indexFileContent = indexFileContent.replace(importRegex, '');
174+
indexFileContent = indexFileContent.replace(importRegex, `/*${results[0]}*/`);
175175
}
176176

177177
results = null;
178178
const exportRegex = generateExportRegex(importPath);
179179
Logger.debug(`[treeshake] purgeUnusedImportsFromIndex: Removing exports with path ${importPath}`);
180180
while ((results = exportRegex.exec(indexFileContent)) && results.length) {
181-
indexFileContent = indexFileContent.replace(exportRegex, '');
181+
indexFileContent = indexFileContent.replace(exportRegex, `/*${results[0]}*/`);
182182
}
183183
}
184184

@@ -188,12 +188,12 @@ export function purgeUnusedImportsAndExportsFromIndex(indexFilePath: string, ind
188188

189189
function generateImportRegex(relativeImportPath: string) {
190190
const cleansedString = escapeStringForRegex(relativeImportPath);
191-
return new RegExp(`import.*?{(.+)}.*?from.*?'${cleansedString}';`);
191+
return new RegExp(`^import.*?{(.+)}.*?from.*?['"\`]${cleansedString}['"\`];`, 'gm');
192192
}
193193

194194
function generateExportRegex(relativeExportPath: string) {
195195
const cleansedString = escapeStringForRegex(relativeExportPath);
196-
return new RegExp(`export.*?{(.+)}.*?from.*?'${cleansedString}';`);
196+
return new RegExp(`^export.*?{(.+)}.*?from.*?'${cleansedString}';`, 'gm');
197197
}
198198

199199
export function purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath: string, appModuleNgFactoryContent: string, componentFactoryPath: string) {
@@ -205,11 +205,14 @@ export function purgeComponentNgFactoryImportAndUsage(appModuleNgFactoryPath: st
205205
const importRegex = generateWildCardImportRegex(importPath);
206206
const results = importRegex.exec(appModuleNgFactoryContent);
207207
if (results && results.length >= 2) {
208-
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(importRegex, '');
208+
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(importRegex, `/*${results[0]}*/`);
209209
const namedImport = results[1].trim();
210210
Logger.debug(`[treeshake] purgeComponentNgFactoryImportAndUsage: Purging code using named import ${namedImport}`);
211211
const purgeFromConstructor = generateRemoveComponentFromConstructorRegex(namedImport);
212-
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(purgeFromConstructor, '');
212+
const purgeFromConstructorResults = purgeFromConstructor.exec(appModuleNgFactoryContent);
213+
if (purgeFromConstructorResults && purgeFromConstructorResults.length) {
214+
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(purgeFromConstructor, `/*${purgeFromConstructorResults[0]}*/`);
215+
}
213216
}
214217
Logger.debug(`[treeshake] purgeComponentNgFactoryImportAndUsage: Starting to purge component ngFactory import/export ... DONE`);
215218
return appModuleNgFactoryContent;
@@ -236,7 +239,7 @@ export function purgeProviderControllerImportAndUsage(appModuleNgFactoryPath: st
236239
if (purgeGetterResults && purgeIfResults) {
237240

238241
Logger.debug(`[treeshake] purgeProviderControllerImportAndUsage: Purging imports ${namedImport}`);
239-
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(importRegex, '');
242+
appModuleNgFactoryContent = appModuleNgFactoryContent.replace(importRegex, `/*${results[0]}*/`);
240243

241244
Logger.debug(`[treeshake] purgeProviderControllerImportAndUsage: Purging getter logic using ${namedImport}`);
242245
const getterContentToReplace = purgeGetterResults[0];
@@ -257,29 +260,32 @@ export function purgeProviderControllerImportAndUsage(appModuleNgFactoryPath: st
257260
export function purgeProviderClassNameFromIonicModuleForRoot(indexFileContent: string, providerClassName: string) {
258261
Logger.debug(`[treeshake] purgeProviderClassNameFromIonicModuleForRoot: Purging reference in the ionicModule forRoot method ...`);
259262
const regex = generateIonicModulePurgeProviderRegex(providerClassName);
260-
indexFileContent = indexFileContent.replace(regex, '');
263+
const results = regex.exec(indexFileContent);
264+
if (results && results.length) {
265+
indexFileContent = indexFileContent.replace(regex, `/*${results[0]}*/`);
266+
}
261267
Logger.debug(`[treeshake] purgeProviderClassNameFromIonicModuleForRoot: Purging reference in the ionicModule forRoot method ... DONE`);
262268
return indexFileContent;
263269
}
264270

265-
function generateWildCardImportRegex(relativeImportPath: string) {
271+
export function generateWildCardImportRegex(relativeImportPath: string) {
266272
const cleansedString = escapeStringForRegex(relativeImportPath);
267273
return new RegExp(`import.*?as(.*?)from '${cleansedString}';`);
268274
}
269275

270-
function generateRemoveComponentFromConstructorRegex(namedImport: string) {
276+
export function generateRemoveComponentFromConstructorRegex(namedImport: string) {
271277
return new RegExp(`${namedImport}\..*?,`);
272278
}
273279

274280
export function generateRemoveGetterFromImportRegex(namedImport: string) {
275-
const regexString = `(get _(.*?)_(\\d*)\\(\\) {([\\s\\S][^}]*?)${namedImport}([\\s\\S]*?)}([\\s\\S]*?)})`;
281+
const regexString = `(get _.*?_\\d*\\(\\) {[\\s\\S][^}]*?${namedImport}[\\s\\S]*?}[\\s\\S]*?})`;
276282
return new RegExp(regexString);
277283
}
278284

279-
function generateRemoveIfStatementRegex(namedImport: string) {
285+
export function generateRemoveIfStatementRegex(namedImport: string) {
280286
return new RegExp(`if \\(\\(token === ${namedImport}.([\\S]*?)\\)\\) {([\\S\\s]*?)}`, `gm`);
281287
}
282288

283-
function generateIonicModulePurgeProviderRegex(className: string) {
284-
return new RegExp(`(^([\\s]*)${className},\\n)`, `m`);
289+
export function generateIonicModulePurgeProviderRegex(className: string) {
290+
return new RegExp(`${className},`, `gm`);
285291
}

0 commit comments

Comments
 (0)