Angular Universal 不适用于 Angular Google 地图
Posted
技术标签:
【中文标题】Angular Universal 不适用于 Angular Google 地图【英文标题】:Angular Universal does not work with Angular Google Maps 【发布时间】:2019-08-26 07:35:28 【问题描述】:技术:Angular Cli、Angular 7、Angular Google Maps、Firebase Functions。
问题:我正在尝试为我的 Angular 通用应用程序提供服务,但在构建时遇到 Angular 谷歌地图错误。
错误我得到:
/Users/test/Public/Leisure/leisure-app/functions/node_modules/@agm/core/services/managers/info-window-manager.js:1
(function (exports, require, module, __filename, __dirname) import
Observable from 'rxjs';
^^^^^^
SyntaxError: Unexpected token import
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
似乎 Angular Universal 不喜欢第三方库。
我关注的资源: https://hackernoon.com/deploying-angular-universal-v6-with-firebase-c86381ddd445
我的应用模块:
import AgmCoreModule from '@agm/core';
import AngularFireAuthModule from '@angular/fire/auth';
import AngularFireDatabase from '@angular/fire/database';
import AngularFireModule from '@angular/fire';
import ServiceWorkerModule from '@angular/service-worker';
import AngularFireStorageModule from '@angular/fire/storage';
import AngularFirestoreModule from '@angular/fire/firestore';
import BrowserModule from '@angular/platform-browser';
import CommonModule from '@angular/common';
import GooglePlaceModule from 'ngx-google-places-autocomplete';
import HTTP_INTERCEPTORS, HttpClientModule from '@angular/common/http';
import NgModule, NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA from '@angular/core';
import NgxErrorsModule from '@hackages/ngxerrors';
import ReactiveFormsModule, FormsModule from '@angular/forms';
import RouterModule from '@angular/router';
import TruncateModule from 'ng2-truncate';
import MetaModule from '@ngx-meta/core';
import PreventDoubleSubmitModule from 'ngx-prevent-double-submission';
// Core App
import AppComponent from './app.component';
import CoreInterceptor from './interceptor';
import environment from '../environments/environment';
// Modules
import SharedModule from './shared/shared.module';
import CoreModule from './services/core.module';
import LayoutModule from './layouts/layout.module';
// Sections
import COMPONENTS from './components/index';
import ROUTES from './app.routes';
// Guards
import AuthGuard from './guards/auth.guard';
import CreditGuard from './guards/credit.guard';
@NgModule(
declarations: [
AppComponent,
COMPONENTS
],
imports: [
CommonModule,
FormsModule,
AngularFireModule.initializeApp(environment.firebase),
AngularFireAuthModule,
AngularFirestoreModule,
AngularFireStorageModule,
// This is the Angular google maps module causing issue on build
AgmCoreModule.forRoot(
apiKey: environment.googleApiKey,
libraries: ['places']
),
GooglePlaceModule,
LayoutModule,
BrowserModule.withServerTransition( appId: 'test123' ),
PreventDoubleSubmitModule.forRoot(),
TruncateModule,
MetaModule.forRoot(),
HttpClientModule,
NgxErrorsModule,
ReactiveFormsModule,
RouterModule.forRoot(ROUTES),
CoreModule,
SharedModule,
ServiceWorkerModule.register('/ngsw-worker.js', enabled: environment.production )
],
providers: [
provide: HTTP_INTERCEPTORS, useClass: CoreInterceptor, multi: true ,
AuthGuard,
CreditGuard,
AngularFireDatabase
],
exports: [ RouterModule ],
schemas: [ NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA ],
bootstrap: [ AppComponent ]
)
export class AppModule
我运行的命令:serve:npm run build && firebase serve --only 函数
最新错误(对于 npm run serve:s-s-r):
来自 serve:s-s-r: 的错误代码:
e.Lb=function(a,b,c)a=this.ka.J[String(a)];if(!a)return!0;a=a.concat();for(var d=!0,f=0;f<a.length;++f)var g=a[f];if(g&&!g.Sa&&g.capture==b)var k=g.listener,p=g.Ob||g.src;g.Eb&&this.Le(g);d=!1!==k.call(p,c)&&d;return d&&0!=c.Be;e.jb=function(a,b,c,d)return this.ka.jb(String(a),b,c,d);var ub=h.JSON.stringify;function vb(a,b)this.Sf=100;this.ef=a;this.ug=b;this.Zb=0;this.Pb=null;vb.prototype.get=function()if(0<this.Zb)this.Zb--;var a=this.Pb;this.Pb=a.next;a.next=null;else a=this.ef();return a;vb.prototype.put=function(a)this.ug(a);this.Zb<this.Sf&&(this.Zb++, a.next=this.Pb, this.Pb=a);;function I()this.lc=this.Va=null;var xb=new vb(function()return new wb,function(a)a.reset(););I.prototype.add=function(a,b)var c=this.Af();c.set(a,b);this.lc?this.lc.next=c:this.Va=c;this.lc=c;;I.prototype.remove=function()var a=null;this.Va&&(a=this.Va, this.Va=this.Va.next, this.Va||(this.lc=null), a.next=null);return a;I.prototype.wg=function(a)xb.put(a);;I.prototype.Af=function()return xb.get();function wb()this.next=this.scope=this.Gc=null;
wb.prototype.set=function(a,b)this.Gc=a;this.scope=b;this.next=null;;wb.prototype.reset=function()this.next=this.scope=this.Gc=null;;function yb(a)h.setTimeout(function()throw a;,0);var zb;
【问题讨论】:
我在某些地方读到,您可以使用 webpack 配置文件将第三方库列入白名单。但不知道该怎么做。 this issue 中的 cmets 可能会给您一些提示。 One comment 建议使用import-export
或禁用 AoT 编译作为解决方法。 Another comment 建议将--bundle-dependencies=all
添加到ng build
命令或"bundleDependencies": "all"
到configurations
in angular.json
。
@ConnorsFan 这些链接似乎不适用于 Angular 版本 7 应用程序
@AngularM 在你说它在 v7 中不起作用之前看看这里,不知道你是否尝试过 ng
:***.com/questions/39996655/…
【参考方案1】:
TL;DR:
Source code 和 DEMO
这里的问题是@agm/core
包是用 es2015 模块编译的。结果在js代码中包含import
和export
。
要解决这个问题,您有两个主要选择:
1。将@agm/core 包编译成commonjs 格式。
您可以使用 babel 或 typescript 来编译该包。然后你需要确保你在你的函数依赖中提供了编译版本
functions/package.json
"dependencies":
...
"@agm/core": "file:./@agm/core"
,
这里我使用本地依赖,但你也可以使用自己发布的版本。
另一种方法是直接在 node_modules 中编译并发布整个 node_modules(我会避免这个):
firebase.json
"functions":
"ignore": []
如何编译?
通天塔
在根目录下安装依赖。
npm i -D @babel/cli @babel/core @babel/preset-env
使用以下脚本编译:
package.json
"postbuild": "babel node_modules/@agm/core -d functions/@agm/core --presets @babel/preset-env && node ./copy-package-json.js"
在哪里
copy-package-json.js
const fs = require('fs-extra');
const join = require('path');
(async() =>
await fs.copy(join(process.cwd(), 'node_modules/@agm/core/package.json'),
join(process.cwd(), 'functions/@agm/core/package.json'));
)();
打字稿
tsconfig.agm.json
"extends": "./tsconfig.json",
"compilerOptions":
"outDir": "./functions/@agm/core",
"types": [],
"module": "commonjs"
,
"include": [
"node_modules/@agm/core"
]
package.json
"postbuild": "tsc -p tsconfig.agm.json --allowJs && node ./copy-package-json.js"
2。生成服务器包
这是 Angular 通用 tutorial 使用的,所以我更喜欢这个解决方案。
也关注这个quide
简单的步骤:
1.安装全局依赖项
我已经安装了:
@angular/cli@7.3.8 firebase-tools@6.5.22。创建一个新的 Angular 项目
ng new angular-agm
3.添加 Angular 通用
ng add @nguniversal/express-engine --clientProject angular-agm
4.更新 server.ts
导出 express 应用,然后移除调用监听并将索引更改为 index2。
import 'zone.js/dist/zone-node';
import enableProdMode from '@angular/core';
// Express Engine
import ngExpressEngine from '@nguniversal/express-engine';
// Import module map for lazy loading
import provideModuleMap from '@nguniversal/module-map-ngfactory-loader';
import * as express from 'express';
import join from 'path';
import * as path from 'path';
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
export const app = express();
// const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
const index = require('fs')
.readFileSync(path.resolve(DIST_FOLDER, 'index2.html'), 'utf8')
.toString();
const domino = require('domino');
const win = domino.createWindow(index);
global['window'] = win;
global['document'] = win.document;
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const AppServerModuleNgFactory, LAZY_MODULE_MAP = require('./dist/server/main');
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine(
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
));
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => );
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER,
maxAge: '1y'
));
// All regular routes use the Universal engine
app.get('*', (req, res) =>
res.render('index2', req );
);
// Start up the Node server
/*app.listen(PORT, () =>
console.log(`Node Express server listening on http://localhost:$PORT`);
);*/
5.构建
npm run build:s-s-r
在哪里构建:s-s-r
"build:s-s-r": "npm run build:client-and-server-bundles && npm run compile:server && node ./tools/copy-artifacts.js",
copy-artifacts.js
const fs = require('fs-extra');
const join = require('path');
(async() =>
const src = join(process.cwd(), 'dist');
const copy = join(process.cwd(), 'functions/dist');
await fs.rename(join(src, 'browser/index.html'), join(src, 'browser/index2.html'));
await fs.remove(copy);
await fs.copy(src, copy);
)();
6.更新 functions/index.js 以使用 express 应用的内置版本
const functions = require('firebase-functions');
const app = require('./dist/server');
exports.s-s-r = functions.https.onRequest(app);
7.配置firebase.json
"hosting":
"public": "dist/browser",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
"source": "**",
"function": "s-s-r"
]
源代码可以在Github找到
另见演示https://angular-agm.firebaseapp.com/
【讨论】:
评论不用于扩展讨论;此对话是moved to chat。 目前 html 在部署时不呈现,但在本地使用 firebase serve 工作。知道为什么吗? 您是否设法找到解决 Angular Universal 的 AngularFire 错误:“TypeError: app.auth is not a function”? 很遗憾,我没有任何可重现的例子。 你能把 angularfire 和 firebase 添加到你的 github 应用,看看你是否得到同样的错误@yurzui?以上是关于Angular Universal 不适用于 Angular Google 地图的主要内容,如果未能解决你的问题,请参考以下文章
Angular Universal 错误 ReferenceError:未定义 MouseEvent
Angular 2 Universal - 使用手写笔和 pug 模板的服务器端渲染
Angular 2 Universal 中的身份验证,nodejs