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

Commit 02b8e97

Browse files
committed
fix(deep-linking): don't force the main bundle to be re-built unless the deep link config changed
don't force the main bundle to be re-built unless the deep link config changed
1 parent 49c0afb commit 02b8e97

File tree

2 files changed

+139
-6
lines changed

2 files changed

+139
-6
lines changed

src/deep-linking.spec.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import * as helpers from './util/helpers';
99

1010
describe('Deep Linking task', () => {
1111
describe('deepLinkingWorkerImpl', () => {
12+
13+
beforeEach(() => {
14+
deepLinking.reset();
15+
});
16+
1217
it('should not update app ngmodule when it has an existing deeplink config', () => {
1318
const appNgModulePath = join('some', 'fake', 'path', 'myApp', 'src', 'app', 'app.module.ts');
1419
const context = {
@@ -26,6 +31,7 @@ describe('Deep Linking task', () => {
2631
const promise = deepLinking.deepLinkingWorkerImpl(context, null);
2732

2833
return promise.then(() => {
34+
expect(deepLinking.cachedUnmodifiedAppNgModuleFileContent).toEqual(knownFileContent);
2935
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).not.toHaveBeenCalled();
3036
expect(deeplinkUtils.updateAppNgModuleAndFactoryWithDeepLinkConfig).not.toHaveBeenCalled();
3137
});
@@ -73,12 +79,118 @@ describe('Deep Linking task', () => {
7379
const promise = deepLinking.deepLinkingWorkerImpl(context, changedFiles);
7480

7581
return promise.then(() => {
82+
expect(deepLinking.cachedDeepLinkString).toEqual(knownDeepLinkString);
7683
expect(helpers.getStringPropertyValue).toBeCalledWith(Constants.ENV_APP_NG_MODULE_PATH);
7784
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledWith(appNgModulePath, context.fileCache, context.runAot);
7885
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledWith(appNgModulePath, knownFileContent);
7986
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledWith(knownMockDeepLinkArray);
8087
expect(deeplinkUtils.updateAppNgModuleAndFactoryWithDeepLinkConfig).toHaveBeenCalledWith(context, knownDeepLinkString, changedFiles, context.runAot);
8188
});
8289
});
90+
91+
it('should update deeplink config on subsequent updates when the deeplink string is different', () => {
92+
const appNgModulePath = join('some', 'fake', 'path', 'myApp', 'src', 'app', 'app.module.ts');
93+
const context = {
94+
fileCache: new FileCache(),
95+
runAot: true
96+
};
97+
const knownFileContent = 'someFileContent';
98+
const knownDeepLinkString = 'someDeepLinkString';
99+
const knownDeepLinkString2 = 'someDeepLinkString2';
100+
const knownMockDeepLinkArray = [1];
101+
const changedFiles: ChangedFile[] = null;
102+
context.fileCache.set(appNgModulePath, { path: appNgModulePath, content: knownFileContent});
103+
104+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(appNgModulePath);
105+
spyOn(deeplinkUtils, deeplinkUtils.getDeepLinkData.name).and.returnValue(knownMockDeepLinkArray);
106+
spyOn(deeplinkUtils, deeplinkUtils.hasExistingDeepLinkConfig.name).and.returnValue(false);
107+
108+
let hasConvertDeepLinkConfigToStringBeenCalled = false;
109+
spyOn(deeplinkUtils, deeplinkUtils.convertDeepLinkConfigEntriesToString.name).and.callFake(() => {
110+
if (!hasConvertDeepLinkConfigToStringBeenCalled) {
111+
hasConvertDeepLinkConfigToStringBeenCalled = true;
112+
return knownDeepLinkString;
113+
}
114+
return knownDeepLinkString2;
115+
});
116+
117+
const spy = spyOn(deeplinkUtils, deeplinkUtils.updateAppNgModuleAndFactoryWithDeepLinkConfig.name);
118+
119+
const promise = deepLinking.deepLinkingWorkerImpl(context, changedFiles);
120+
121+
return promise.then(() => {
122+
expect(deepLinking.cachedDeepLinkString).toEqual(knownDeepLinkString);
123+
expect(helpers.getStringPropertyValue).toBeCalledWith(Constants.ENV_APP_NG_MODULE_PATH);
124+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledWith(appNgModulePath, context.fileCache, context.runAot);
125+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledWith(appNgModulePath, knownFileContent);
126+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledWith(knownMockDeepLinkArray);
127+
expect(spy.calls.first().args[0]).toEqual(context);
128+
expect(spy.calls.first().args[1]).toEqual(knownDeepLinkString);
129+
expect(spy.calls.first().args[2]).toEqual(changedFiles);
130+
expect(spy.calls.first().args[3]).toEqual(context.runAot);
131+
132+
return deepLinking.deepLinkingWorkerImpl(context, changedFiles);
133+
}).then((result) => {
134+
expect(deepLinking.cachedDeepLinkString).toEqual(knownDeepLinkString2);
135+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledTimes(2);
136+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledWith(appNgModulePath, context.fileCache, context.runAot);
137+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledTimes(2);
138+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledWith(appNgModulePath, knownFileContent);
139+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledWith(knownMockDeepLinkArray);
140+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledTimes(2);
141+
expect(spy).toHaveBeenCalledTimes(2);
142+
expect(spy.calls.mostRecent().args[0]).toEqual(context);
143+
expect(spy.calls.mostRecent().args[1]).toEqual(knownDeepLinkString2);
144+
expect(spy.calls.mostRecent().args[2]).toEqual(changedFiles);
145+
expect(spy.calls.mostRecent().args[3]).toEqual(context.runAot);
146+
});
147+
});
148+
149+
it('should not update deeplink config on subsequent updates when the deeplink string is the same', () => {
150+
const appNgModulePath = join('some', 'fake', 'path', 'myApp', 'src', 'app', 'app.module.ts');
151+
const context = {
152+
fileCache: new FileCache(),
153+
runAot: true
154+
};
155+
const knownFileContent = 'someFileContent';
156+
const knownDeepLinkString = 'someDeepLinkString';
157+
const knownMockDeepLinkArray = [1];
158+
const changedFiles: ChangedFile[] = null;
159+
context.fileCache.set(appNgModulePath, { path: appNgModulePath, content: knownFileContent});
160+
161+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(appNgModulePath);
162+
spyOn(deeplinkUtils, deeplinkUtils.getDeepLinkData.name).and.returnValue(knownMockDeepLinkArray);
163+
spyOn(deeplinkUtils, deeplinkUtils.hasExistingDeepLinkConfig.name).and.returnValue(false);
164+
165+
spyOn(deeplinkUtils, deeplinkUtils.convertDeepLinkConfigEntriesToString.name).and.returnValue(knownDeepLinkString);
166+
167+
const spy = spyOn(deeplinkUtils, deeplinkUtils.updateAppNgModuleAndFactoryWithDeepLinkConfig.name);
168+
169+
const promise = deepLinking.deepLinkingWorkerImpl(context, changedFiles);
170+
171+
return promise.then(() => {
172+
expect(deepLinking.cachedDeepLinkString).toEqual(knownDeepLinkString);
173+
expect(helpers.getStringPropertyValue).toBeCalledWith(Constants.ENV_APP_NG_MODULE_PATH);
174+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledWith(appNgModulePath, context.fileCache, context.runAot);
175+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledWith(appNgModulePath, knownFileContent);
176+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledWith(knownMockDeepLinkArray);
177+
expect(spy.calls.first().args[0]).toEqual(context);
178+
expect(spy.calls.first().args[1]).toEqual(knownDeepLinkString);
179+
expect(spy.calls.first().args[2]).toEqual(changedFiles);
180+
expect(spy.calls.first().args[3]).toEqual(context.runAot);
181+
182+
return deepLinking.deepLinkingWorkerImpl(context, changedFiles);
183+
}).then((result) => {
184+
expect(result).toEqual(knownMockDeepLinkArray);
185+
expect(deepLinking.cachedDeepLinkString).toEqual(knownDeepLinkString);
186+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledTimes(2);
187+
expect(deeplinkUtils.getDeepLinkData).toHaveBeenCalledWith(appNgModulePath, context.fileCache, context.runAot);
188+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledTimes(2);
189+
expect(deeplinkUtils.hasExistingDeepLinkConfig).toHaveBeenCalledWith(appNgModulePath, knownFileContent);
190+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledWith(knownMockDeepLinkArray);
191+
expect(deeplinkUtils.convertDeepLinkConfigEntriesToString).toHaveBeenCalledTimes(2);
192+
expect(spy).toHaveBeenCalledTimes(1);
193+
});
194+
});
83195
});
84196
});

src/deep-linking.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { convertDeepLinkConfigEntriesToString, getDeepLinkData, hasExistingDeepL
1515
* as the cached version of the App's main NgModule content will basically always
1616
* have a generated deep likn config in it.
1717
*/
18-
let cachedUnmodifiedAppNgModuleFileContent: string = null;
18+
export let cachedUnmodifiedAppNgModuleFileContent: string = null;
19+
export let cachedDeepLinkString: string = null;
1920

2021
export function deepLinking(context: BuildContext) {
2122
const logger = new Logger(`deeplinks`);
@@ -42,12 +43,26 @@ export function deepLinkingWorkerImpl(context: BuildContext, changedFiles: Chang
4243
if (!cachedUnmodifiedAppNgModuleFileContent) {
4344
cachedUnmodifiedAppNgModuleFileContent = appNgModuleFile.content;
4445
}
45-
const deepLinkConfigEntries = getDeepLinkData(appNgModulePath, context.fileCache, context.runAot);
46+
47+
// is there is an existing (legacy) deep link config, just move on and don't look for decorators
4648
const hasExisting = hasExistingDeepLinkConfig(appNgModulePath, cachedUnmodifiedAppNgModuleFileContent);
47-
if (!hasExisting && deepLinkConfigEntries && deepLinkConfigEntries.length) {
48-
// only update the app's main ngModule if there isn't an existing config
49-
const deepLinkString = convertDeepLinkConfigEntriesToString(deepLinkConfigEntries);
50-
updateAppNgModuleAndFactoryWithDeepLinkConfig(context, deepLinkString, changedFiles, context.runAot);
49+
if (hasExisting) {
50+
return [];
51+
}
52+
53+
const deepLinkConfigEntries = getDeepLinkData(appNgModulePath, context.fileCache, context.runAot) || [];
54+
if (deepLinkConfigEntries.length) {
55+
const newDeepLinkString = convertDeepLinkConfigEntriesToString(deepLinkConfigEntries);
56+
if (!cachedDeepLinkString) {
57+
// this is the first time running this, so update the build either way
58+
cachedDeepLinkString = newDeepLinkString;
59+
updateAppNgModuleAndFactoryWithDeepLinkConfig(context, newDeepLinkString, changedFiles, context.runAot);
60+
} else if (newDeepLinkString !== cachedDeepLinkString) {
61+
// we have an existing deep link string, and we have a new one, and they're different
62+
// so go ahead and update the config
63+
cachedDeepLinkString = newDeepLinkString;
64+
updateAppNgModuleAndFactoryWithDeepLinkConfig(context, newDeepLinkString, changedFiles, context.runAot);
65+
}
5166
}
5267
return deepLinkConfigEntries;
5368
});
@@ -89,3 +104,9 @@ export function deepLinkingWorkerFullUpdate(context: BuildContext) {
89104
throw logger.fail(error);
90105
});
91106
}
107+
108+
// this is purely for testing
109+
export function reset() {
110+
cachedUnmodifiedAppNgModuleFileContent = null;
111+
cachedDeepLinkString = null;
112+
}

0 commit comments

Comments
 (0)