Skip to content

Commit 6817bcc

Browse files
authored
fix(core): ensure the UMDs are importing things correctly for the lazy modules (#2676)
1 parent ae26b35 commit 6817bcc

17 files changed

+113
-50
lines changed

sample/angular.json

+1-31
Original file line numberDiff line numberDiff line change
@@ -129,37 +129,7 @@
129129
"main": "server.ts",
130130
"tsConfig": "tsconfig.server.json",
131131
"bundleDependencies": true,
132-
"externalDependencies": [
133-
"firebase",
134-
"@firebase/analytics",
135-
"@firebase/analytics-types",
136-
"@firebase/app",
137-
"@firebase/app-types",
138-
"@firebase/auth",
139-
"@firebase/auth-interop-types",
140-
"@firebase/auth-types",
141-
"@firebase/component",
142-
"@firebase/database",
143-
"@firebase/database-types",
144-
"@firebase/firestore",
145-
"@firebase/firestore-types",
146-
"@firebase/functions",
147-
"@firebase/functions-types",
148-
"@firebase/installations",
149-
"@firebase/installations-types",
150-
"@firebase/logger",
151-
"@firebase/messaging",
152-
"@firebase/messaging-types",
153-
"@firebase/performance",
154-
"@firebase/performance-types",
155-
"@firebase/polyfill",
156-
"@firebase/remote-config",
157-
"@firebase/remote-config-types",
158-
"@firebase/storage",
159-
"@firebase/storage-types",
160-
"@firebase/util",
161-
"@firebase/webchannel-wrapper"
162-
]
132+
"externalDependencies": [ ]
163133
},
164134
"configurations": {
165135
"production": {

sample/firebase.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
"value": "public,max-age=31536000,immutable"
1616
}
1717
]
18+
}, {
19+
"source": "*-sw.js",
20+
"headers": [
21+
{
22+
"key": "Cache-Control",
23+
"value": "no-cache"
24+
}
25+
]
1826
}
1927
],
2028
"rewrites": [
@@ -26,7 +34,7 @@
2634
}
2735
],
2836
"functions": {
29-
"source": "functions"
37+
"source": "dist/sample"
3038
},
3139
"emulators": {
3240
"functions": {

sample/firestore-protos.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
path: './node_modules/@firebase/firestore/dist/src/protos',
3+
filter: /\.proto$/,
4+
pathTransform: (path: string) => {
5+
const name = path.split('./node_modules/@firebase/firestore/dist/')[1];
6+
return `file-loader?name=${name}!${path}`;
7+
}
8+
};

sample/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"@types/jasminewd2": "~2.0.3",
5151
"codelyzer": "^6.0.0",
5252
"concurrently": "^5.3.0",
53+
"dir-loader": "^0.3.0",
5354
"express": "^4.17.1",
5455
"express-serve-static-core": "^0.1.1",
5556
"firebase-admin": "^8.13.0",

sample/server.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ngExpressEngine } from '@nguniversal/express-engine';
44
import * as express from 'express';
55
import { join } from 'path';
66

7-
import { AppServerModule } from './src/main.server';
7+
import { AppServerModule, } from './src/main.server';
88
import { APP_BASE_HREF } from '@angular/common';
99
import { existsSync } from 'fs';
1010

@@ -14,6 +14,9 @@ global['XMLHttpRequest'] = require('xhr2');
1414
global['WebSocket'] = require('ws');
1515
/* tslint:enable:no-string-literal */
1616

17+
// include the protos required to bundle firestore
18+
import 'dir-loader!./firestore-protos';
19+
1720
// The Express app is exported so that it can be used by serverless Functions.
1821
export function app() {
1922
const server = express();
@@ -22,7 +25,7 @@ export function app() {
2225

2326
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
2427
server.engine('html', ngExpressEngine({
25-
bootstrap: AppServerModule,
28+
bootstrap: AppServerModule
2629
}));
2730

2831
server.set('view engine', 'html');

sample/src/app/app-routing.module.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@ import { NgModule } from '@angular/core';
22
import { Routes, RouterModule } from '@angular/router';
33
import { HomeComponent } from './home/home.component';
44
import { ProtectedComponent } from './protected/protected.component';
5-
import { AngularFireAuthGuard } from '@angular/fire/auth-guard';
5+
import { AngularFireAuthGuard, canActivate, isNotAnonymous } from '@angular/fire/auth-guard';
66
import { SecondaryComponent } from './secondary/secondary.component';
77

88
const routes: Routes = [
9-
{ path: '', component: HomeComponent, outlet: 'primary' },
10-
{ path: '', component: SecondaryComponent, outlet: 'secondary' },
11-
{ path: '', component: SecondaryComponent, outlet: 'tertiary' },
9+
{ path: '', component: HomeComponent, outlet: 'primary', pathMatch: 'prefix' },
10+
{ path: '', component: SecondaryComponent, outlet: 'secondary', pathMatch: 'prefix' },
11+
{ path: '', component: SecondaryComponent, outlet: 'tertiary', pathMatch: 'prefix' },
1212
{ path: 'protected', component: ProtectedComponent, canActivate: [AngularFireAuthGuard] },
13+
{ path: 'lazy', loadChildren: () => import('./protected-lazy/protected-lazy.module').then(m => m.ProtectedLazyModule) },
1314
{ path: 'protected-lazy',
1415
loadChildren: () => import('./protected-lazy/protected-lazy.module').then(m => m.ProtectedLazyModule),
1516
canActivate: [AngularFireAuthGuard] },
1617
{ path: 'protected', component: ProtectedComponent, canActivate: [AngularFireAuthGuard], outlet: 'secondary' },
1718
{ path: 'protected', component: ProtectedComponent, canActivate: [AngularFireAuthGuard], outlet: 'tertiary' },
1819
{ path: 'protected-lazy',
1920
loadChildren: () => import('./protected-lazy/protected-lazy.module').then(m => m.ProtectedLazyModule),
20-
canActivate: [AngularFireAuthGuard],
21+
...canActivate(() => isNotAnonymous),
2122
outlet: 'secondary' },
2223
];
2324

sample/src/app/app.component.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,21 @@ import { FirebaseApp } from '@angular/fire';
44
@Component({
55
selector: 'app-root',
66
template: `
7-
<a [routerLink]="[{ outlets: { primary: [] }}]">Home</a> | <a [routerLink]="[{ outlets: { primary: ['protected'] }}]">Protected</a> | <a [routerLink]="[{ outlets: { primary: ['protected-lazy'] }}]">Protected Lazy</a> | <a [routerLink]="[{ outlets: { primary: ['protected-lazy', 'asdf'] }}]">Protected Lazy Deep</a> | <a [routerLink]="[{ outlets: { primary: ['protected-lazy', '1', 'bob'] }}]">Protected Lazy Deep</a>
7+
<h1>AngularFire kitchen sink</h1>
8+
<h2>Primary outlet</h2>
9+
<nav>
10+
<a [routerLink]="[{ outlets: { primary: [] }}]">Home</a> |
11+
<a [routerLink]="[{ outlets: { primary: ['protected'] }}]">Protected</a> |
12+
<a [routerLink]="[{ outlets: { primary: ['lazy'] }}]">Lazy</a> |
13+
<a [routerLink]="[{ outlets: { primary: ['protected-lazy'] }}]">Protected Lazy</a> |
14+
<a [routerLink]="[{ outlets: { primary: ['protected-lazy', 'asdf'] }}]">Protected Lazy Deep</a> |
15+
<a [routerLink]="[{ outlets: { primary: ['protected-lazy', '1', 'bob'] }}]">Protected Lazy Deep</a></nav>
816
<router-outlet></router-outlet>
9-
<a [routerLink]="[{ outlets: { secondary: [] }}]">Home</a> | <a [routerLink]="[{ outlets: { secondary: ['protected'] }}]">Protected</a> | <a [routerLink]="[{ outlets: { secondary: ['protected-lazy'] }}]">Protected Lazy</a>
17+
<h2>Secondary outlet</h2>
18+
<nav><a [routerLink]="[{ outlets: { secondary: [] }}]">Home</a> | <a [routerLink]="[{ outlets: { secondary: ['protected'] }}]">Protected</a> | <a [routerLink]="[{ outlets: { secondary: ['protected-lazy'] }}]">Protected Lazy (no anonymous)</a></nav>
1019
<router-outlet name="secondary"></router-outlet>
11-
<a [routerLink]="[{ outlets: { tertiary: [] }}]">Home</a> | <a [routerLink]="[{ outlets: { tertiary: ['protected'] }}]">Protected</a>
20+
<h2>Yet anther outlet</h2>
21+
<nav><a [routerLink]="[{ outlets: { tertiary: [] }}]">Home</a> | <a [routerLink]="[{ outlets: { tertiary: ['protected'] }}]">Protected</a></nav>
1222
<router-outlet name="tertiary"></router-outlet>
1323
`,
1424
styles: [``]

sample/src/app/app.module.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ import { UpboatsComponent } from './upboats/upboats.component';
8383
{ provide: USE_FIRESTORE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 8080] : undefined },
8484
{ provide: USE_FUNCTIONS_EMULATOR, useValue: environment.useEmulators ? ['localhost', 5001] : undefined },
8585
{ provide: NEW_ORIGIN_BEHAVIOR, useValue: true },
86-
{ provide: FUNCTIONS_ORIGIN, useFactory: () => isDevMode() ? undefined : location.origin },
86+
{ provide: FUNCTIONS_ORIGIN, useFactory: () => isDevMode() || typeof location === 'undefined' ? undefined : location.origin },
8787
{ provide: REMOTE_CONFIG_SETTINGS, useFactory: () => isDevMode() ? { minimumFetchIntervalMillis: 10_000 } : {} },
8888
{ provide: REMOTE_CONFIG_DEFAULTS, useValue: { background_color: 'red' } },
8989
{ provide: USE_DEVICE_LANGUAGE, useValue: true },

sample/src/app/app.server.module.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
import { NgModule } from '@angular/core';
1+
import { isDevMode, NgModule } from '@angular/core';
22
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
33

44
import { AppModule } from './app.module';
55
import { AppComponent } from './app.component';
6+
import { APP_BASE_HREF } from '@angular/common';
67

78
@NgModule({
89
imports: [
910
AppModule,
1011
ServerModule,
1112
ServerTransferStateModule
1213
],
14+
providers: [
15+
{ provide: APP_BASE_HREF, useFactory: () => isDevMode() ? '/us-central1/ssr' : '/ssr' },
16+
],
1317
bootstrap: [AppComponent],
1418
})
1519
export class AppServerModule {}

sample/src/app/protected-lazy/protected-lazy.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<p>protected-lazy works!</p>
1+
<p>lazy works!</p>
22

33
<ul>
44
<li *ngFor="let item of snapshot | async">
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<p>secondary works!</p>
1+
<p>I'm another outlet!</p>

sample/tsconfig.server.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
},
1111
"files": [
1212
"src/main.server.ts",
13-
"server.ts"
13+
"server.ts",
14+
"firestore-protos.ts"
1415
],
1516
"angularCompilerOptions": {
1617
"entryModule": "./src/app/app.server.module#AppServerModule"

sample/yarn.lock

+29-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
tslib "^2.0.0"
231231

232232
"@angular/fire@../dist/packages-dist":
233-
version "6.1.0"
233+
version "6.1.1"
234234
dependencies:
235235
tslib "^2.0.0"
236236

@@ -2890,6 +2890,11 @@ big-integer@^1.6.17:
28902890
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e"
28912891
integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==
28922892

2893+
big.js@^3.1.3:
2894+
version "3.2.0"
2895+
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
2896+
integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
2897+
28932898
big.js@^5.2.2:
28942899
version "5.2.2"
28952900
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@@ -4728,6 +4733,14 @@ dir-glob@^3.0.1:
47284733
dependencies:
47294734
path-type "^4.0.0"
47304735

4736+
dir-loader@^0.3.0:
4737+
version "0.3.0"
4738+
resolved "https://registry.yarnpkg.com/dir-loader/-/dir-loader-0.3.0.tgz#715b4a129a34e8e371c533625f3d7dc8428f2abe"
4739+
integrity sha1-cVtKEpo06ONxxTNiXz19yEKPKr4=
4740+
dependencies:
4741+
loader-utils "^0.2.9"
4742+
object-assign "^4.0.1"
4743+
47314744
dns-equal@^1.0.0:
47324745
version "1.0.0"
47334746
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@@ -7562,6 +7575,11 @@ json3@^3.3.2:
75627575
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
75637576
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
75647577

7578+
json5@^0.5.0:
7579+
version "0.5.1"
7580+
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
7581+
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
7582+
75657583
json5@^1.0.1:
75667584
version "1.0.1"
75677585
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@@ -7897,6 +7915,16 @@ [email protected], loader-utils@^2.0.0:
78977915
emojis-list "^3.0.0"
78987916
json5 "^2.1.2"
78997917

7918+
loader-utils@^0.2.9:
7919+
version "0.2.17"
7920+
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
7921+
integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
7922+
dependencies:
7923+
big.js "^3.1.3"
7924+
emojis-list "^2.0.0"
7925+
json5 "^0.5.0"
7926+
object-assign "^4.0.1"
7927+
79007928
loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
79017929
version "1.4.0"
79027930
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"

src/auth/public_api.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
2+
import 'firebase/auth'; // removed in build process when not UMD
3+
14
export * from './auth';
25
export * from './auth.module';

src/firestore/firestore.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import {
2424
FirebaseApp
2525
} from '@angular/fire';
2626
import { isPlatformServer } from '@angular/common';
27-
import 'firebase/firestore';
2827
import firebase from 'firebase/app';
28+
import 'firebase/firestore';
2929
import { USE_EMULATOR as USE_AUTH_EMULATOR } from '@angular/fire/auth';
3030
import { ɵfetchInstance, ɵlogAuthEmulatorError } from '@angular/fire';
3131

src/functions/public_api.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
2+
import 'firebase/functions'; // removed in build process when not UMD
3+
14
export * from './functions';
25
export * from './functions.module';

tools/build.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,28 @@ async function measure(module: string) {
9494
return { size, gzip };
9595
}
9696

97+
async function fixImportForLazyModules() {
98+
await Promise.all(LAZY_MODULES.map(async module => {
99+
const packageJson = JSON.parse((await readFile(dest(module, 'package.json'))).toString());
100+
const entries = Array.from(new Set(Object.values(packageJson).filter(v => typeof v === 'string' && v.endsWith('.js')))) as string[];
101+
// TODO don't hardcode esm2015 here, perhaps we should scan all the entry directories
102+
// e.g, if ng-packagr starts building other non-flattened entries we'll lose the dynamic import
103+
entries.push(`../esm2015/${module}/public_api.js`); // the import isn't pulled into the ESM public_api
104+
await Promise.all(entries.map(async path => {
105+
const source = (await readFile(dest(module, path))).toString();
106+
let newSource: string;
107+
if (path.endsWith('.umd.js')) {
108+
// in the UMD for lazy modules replace the dyanamic import
109+
newSource = source.replace(`import('firebase/${module}')`, 'rxjs.of(undefined)');
110+
} else {
111+
// in everything else get rid of the global side-effect import
112+
newSource = source.replace(new RegExp(`^import 'firebase/${module}'.+$`, 'gm'), '');
113+
}
114+
await writeFile(dest(module, path), newSource);
115+
}));
116+
}));
117+
}
118+
97119
async function buildLibrary() {
98120
await proxyPolyfillCompat();
99121
await spawnPromise('npx', ['ng', 'build']);
@@ -103,7 +125,8 @@ async function buildLibrary() {
103125
copy(join(process.cwd(), 'docs'), dest('docs')),
104126
compileSchematics(),
105127
replacePackageJsonVersions(),
106-
replacePackageCoreVersion()
128+
replacePackageCoreVersion(),
129+
fixImportForLazyModules(),
107130
]);
108131
}
109132

0 commit comments

Comments
 (0)