简体   繁体   English

将基本的Angular 2应用程序部署到Google App Engine

[英]Deploying basic Angular 2 app to Google App Engine

I can use Angular 2 to create basic front-end applications and can use python to create back-ends with endpoints on Google App engine. 我可以使用Angular 2创建基本的前端应用程序,并可以使用python在Google App引擎上创建带端点的后端。 I can't however seem to figure out how to put the two together and deploy them with the cloud SDK. 然而,我似乎无法弄清楚如何将两者放在一起并使用云SDK部署它们。

Here is a basic example where I can't even host a simple angular2 app with no back-end calls on GAE. 这是一个基本的例子,我甚至无法在GAE上托管一个没有后端调用的简单angular2应用程序。 I have taken the dist folder after building with angular2 CLI and tried to connect to it with the app.yaml file. 在使用angular2 CLI构建后,我已经使用了dist文件夹,并尝试使用app.yaml文件连接到该文件夹​​。 It seems to work in the browser developer (dev_appserver.py app.yaml) although I get some 404 errors in SDK with the GET requests to do with my index.html file I think. 它似乎在浏览器开发人员(dev_appserver.py app.yaml)中工作,虽然我在SDK中遇到404错误,我认为我的index.html文件有GET请求。 I then create a blank index.yaml file and try to deploy it but get a 404 Error at the appspot.com location. 然后我创建一个空白的index.yaml文件并尝试部署它,但在appspot.com位置获得404错误。 This is the app.yaml file: 这是app.yaml文件:

application:
version:
runtime: python27
threadsafe: true
api_version: 1

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: (.*)/
  static_files: dist\1/index.html
  upload: dist

- url: (.*)
  static_files: dist\1
  upload: dist

I really have no idea what I am doing wrong. 我真的不知道我做错了什么。 Do I need some kind of a main.application python back-end to connect to the dist files or? 我是否需要某种main.application python后端来连接dist文件或? Do I need to include node modules or some other kind or files from Angular2? 我是否需要在Angular2中包含节点模块或其他类型的文件? Any help would be massively appreciated! 任何帮助都将受到大力赞赏! Thanks 谢谢

For the latest versions of Angular 4 and App Engine I built the following: 对于最新版本的Angular 4和App Engine,我构建了以下内容:

service: stage
runtime: python27
api_version: 1
threadsafe: true

skip_files:
- ^(?!dist)  # Skip any files not in the dist folder

handlers:
# Routing for bundles to serve directly
- url: /((?:inline|main|polyfills|styles|vendor)\.[a-z0-9]+\.bundle\.js)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  upload: dist/.*

# Routing for a prod styles.bundle.css to serve directly
- url: /(styles\.[a-z0-9]+\.bundle\.css)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  upload: dist/.*

# Routing for typedoc, assets and favicon.ico to serve directly
- url: /((?:assets|docs)/.*|favicon\.ico)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  upload: dist/.*

# Any other requests are routed to index.html for angular to handle so we don't need hash URLs
- url: /.*
  secure: always
  redirect_http_response_code: 301
  static_files: dist/index.html
  upload: dist/index\.html
  http_headers:
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    X-Frame-Options: DENY

Looking for feedback on how this could be improved. 寻求有关如何改进的反馈意见。

I now update the handlers in my app.yaml file to look like this for static uploads to the google cloud platform. 我现在更新app.yaml文件中的处理程序,以便静态上传到google云平台。 There was issues with Angular Router if the regular expression wasn't like this. 如果正则表达式不是这样的话,Angular Router会出现问题。 Dist folder is output from angular cli ng build : Dist文件夹从角度克隆ng build输出:

handlers:
- url: /favicon.ico
  static_files: dist/favicon.ico
  upload: dist/assets/favicon.ico

- url: /(.*\.(gif|png|jpg|css|js)(|\.map))$
  static_files: dist/\1
  upload: dist/(.*)(|\.map)

- url: /(.*)
  static_files: dist/index.html
  upload: dist/index.html

UPDATE: 更新:

For production ng build --prod , this is how my app.yaml file would look: 对于生产ng build --prod ,这是我的app.yaml文件的外观:

runtime: python27
threadsafe: true
api_version: 1

handlers:
- url: /(.*\.(gif|png|jpeg|jpg|css|js|ico))$
  static_files: dist/\1
  upload: dist/(.*)
- url: /(.*)
  static_files: dist/index.html
  upload: dist/index.html

I would add any other file types in the dist folder to the regex grouping characters in the first handler: (gif|png|jpeg|jpg|css|js|ico) 我会在dist文件夹中将任何其他文件类型添加到第一个处理程序中的正则表达式分组字符: (gif|png|jpeg|jpg|css|js|ico)

For Angular 6, the file structure changed somewhat. 对于Angular 6,文件结构有所改变。 The following is based on @Rob's answer, but updated for an Angular 6 with a service-worker enabled. 以下内容基于@ Rob的答案,但针对已启用服务工作者的Angular 6进行了更新。 Be sure to replace "my-app" with the folder name of your app. 请务必将“my-app”替换为您应用的文件夹名称。

service: stage
runtime: python27
api_version: 1
threadsafe: true

skip_files:
- ^(?!dist)  # Skip any files not in the dist folder

handlers:
# Routing for bundles to serve directly
- url: /((?:runtime|main|polyfills|styles|vendor)\.[a-z0-9]+\.js)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/\1
  upload: dist/my-app/.*

# Routing for bundle maps to serve directly
- url: /((?:runtime|main|polyfills|styles|vendor)\.[a-z0-9]+\.js\.map)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/\1
  upload: dist/my-app/.*

# Routing for a prod styles.bundle.css to serve directly
- url: /(styles\.[a-z0-9]+\.css)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/\1
  upload: dist/my-app/.*

# Routing for typedoc, assets, and favicon.ico to serve directly
- url: /((?:assets|docs)/.*|favicon\.ico)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/\1
  upload: dist/my-app/.*

# Routing for service worker files serve directly
- url: /(manifest\.json|ngsw\.json|ngsw-worker\.js|safety-worker\.js|worker-basic\.min\.js|ngsw_worker\.es6\.js\.map)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/\1
  upload: dist/my-app/.*

# Any other requests are routed to index.html for angular to handle so we don't need hash URLs
- url: /.*
  secure: always
  redirect_http_response_code: 301
  static_files: dist/my-app/index.html
  upload: dist/my-app/index\.html
  http_headers:
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    X-Frame-Options: DENY

It looks like your regular expression match is in the wrong spot. 看起来你的正则表达式匹配在错误的位置。 Try this format: 试试这种格式:

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico
- url: /
  static_files: dist/index.html
  upload: dist/index.html
- url: /(.*)
  static_files: dist/\1
  upload: dist/(.*)

This comes from testing and some oddities we encountered while creating the Static Hosting tutorial on App Engine . 这来自测试以及我们在App Engine上创建静态托管教程时遇到的一些奇怪之处。

Replace your app.yaml with the following. 用以下内容替换app.yaml。 It will work! 它会工作!

application: you-app-name-here
version: 1
runtime: python
api_version: 1

default_expiration: "30d"

handlers:
- url: /(.*\.(appcache|manifest))
  mime_type: text/cache-manifest
  static_files: static/\1
  upload: static/(.*\.(appcache|manifest))
  expiration: "0m"

- url: /(.*\.atom)
  mime_type: application/atom+xml
  static_files: static/\1
  upload: static/(.*\.atom)
  expiration: "1h"

- url: /(.*\.crx)
  mime_type: application/x-chrome-extension
  static_files: static/\1
  upload: static/(.*\.crx)

- url: /(.*\.css)
  mime_type: text/css
  static_files: static/\1
  upload: static/(.*\.css)

- url: /(.*\.eot)
  mime_type: application/vnd.ms-fontobject
  static_files: static/\1
  upload: static/(.*\.eot)

- url: /(.*\.htc)
  mime_type: text/x-component
  static_files: static/\1
  upload: static/(.*\.htc)

- url: /(.*\.html)
  mime_type: text/html
  static_files: static/\1
  upload: static/(.*\.html)
  expiration: "1h"

- url: /(.*\.ico)
  mime_type: image/x-icon
  static_files: static/\1
  upload: static/(.*\.ico)
  expiration: "7d"

- url: /(.*\.js)
  mime_type: text/javascript
  static_files: static/\1
  upload: static/(.*\.js)

- url: /(.*\.json)
  mime_type: application/json
  static_files: static/\1
  upload: static/(.*\.json)
  expiration: "1h"

- url: /(.*\.m4v)
  mime_type: video/m4v
  static_files: static/\1
  upload: static/(.*\.m4v)

- url: /(.*\.mp4)
  mime_type: video/mp4
  static_files: static/\1
  upload: static/(.*\.mp4)

- url: /(.*\.(ogg|oga))
  mime_type: audio/ogg
  static_files: static/\1
  upload: static/(.*\.(ogg|oga))

- url: /(.*\.ogv)
  mime_type: video/ogg
  static_files: static/\1
  upload: static/(.*\.ogv)

- url: /(.*\.otf)
  mime_type: font/opentype
  static_files: static/\1
  upload: static/(.*\.otf)

- url: /(.*\.rss)
  mime_type: application/rss+xml
  static_files: static/\1
  upload: static/(.*\.rss)
  expiration: "1h"

- url: /(.*\.safariextz)
  mime_type: application/octet-stream
  static_files: static/\1
  upload: static/(.*\.safariextz)

- url: /(.*\.(svg|svgz))
  mime_type: images/svg+xml
  static_files: static/\1
  upload: static/(.*\.(svg|svgz))

- url: /(.*\.swf)
  mime_type: application/x-shockwave-flash
  static_files: static/\1
  upload: static/(.*\.swf)

- url: /(.*\.ttf)
  mime_type: font/truetype
  static_files: static/\1
  upload: static/(.*\.ttf)

- url: /(.*\.txt)
  mime_type: text/plain
  static_files: static/\1
  upload: static/(.*\.txt)

- url: /(.*\.unity3d)
  mime_type: application/vnd.unity
  static_files: static/\1
  upload: static/(.*\.unity3d)

- url: /(.*\.webm)
  mime_type: video/webm
  static_files: static/\1
  upload: static/(.*\.webm)

- url: /(.*\.webp)
  mime_type: image/webp
  static_files: static/\1
  upload: static/(.*\.webp)

- url: /(.*\.woff)
  mime_type: application/x-font-woff
  static_files: static/\1
  upload: static/(.*\.woff)

- url: /(.*\.xml)
  mime_type: application/xml
  static_files: static/\1
  upload: static/(.*\.xml)
  expiration: "1h"

- url: /(.*\.xpi)
  mime_type: application/x-xpinstall
  static_files: static/\1
  upload: static/(.*\.xpi)

# image files
- url: /(.*\.(bmp|gif|ico|jpeg|jpg|png))
  static_files: static/\1
  upload: static/(.*\.(bmp|gif|ico|jpeg|jpg|png))

# audio files
- url: /(.*\.(mid|midi|mp3|wav))
  static_files: static/\1
  upload: static/(.*\.(mid|midi|mp3|wav))  

# windows files
- url: /(.*\.(doc|exe|ppt|rtf|xls))
  static_files: static/\1
  upload: static/(.*\.(doc|exe|ppt|rtf|xls))

# compressed files
- url: /(.*\.(bz2|gz|rar|tar|tgz|zip))
  static_files: static/\1
  upload: static/(.*\.(bz2|gz|rar|tar|tgz|zip))

# index files
- url: /(.+)/
  static_files: static/\1/index.html
  upload: static/(.+)/index.html
  expiration: "15m"

- url: /(.+)
  static_files: static/\1/index.html
  upload: static/(.+)/index.html
  expiration: "15m"

# site root
- url: /
  static_files: static/index.html
  upload: static/index.html
  expiration: "15m"

first build your angular project by running the following command 首先通过运行以下命令构建角度项目

--ng build prod

the after the build is done create an app.yaml file in the root folder of your project and paste the following code: 构建完成后,在项目的根文件夹中创建app.yaml文件并粘贴以下代码:

# [START runtime]
runtime: python27
threadsafe: yes
# [END runtime]

handlers:

- url: /(.+)
 static_files: dist/\1
 upload: dist/(.*)

- url: /
 static_files: dist/index.html
 upload: dist/index.html

# Temporary setting to keep gcloud from uploading not required files for 
deployment
skip_files:
- ^node_modules$
- ^app\.yaml
- ^README\..*
- \.gitignore
- ^\.git$
- ^grunt\.js
- ^src$
- ^e2e$
- \.editorconfig
- ^karma\.config\.js
- ^package\.json
- ^protractor\.conf\.js
- ^tslint\.json

after this run: 在这次运行之后:

gcloud app deploy

If you're using custom fonts, you may use this template: 如果您使用的是自定义字体,则可以使用此模板:

handlers:
  # Routing for bundles to serve directly
  - url: /(.*\.(gif|png|jpeg|jpg|css|js|ico))$
    static_files: dist/\1
    upload: dist/(.*)

  - url: /assets/fonts/(.*\.(eot|woff|woff2|svg))$
    static_files: dist/assets/fonts/\1
    upload: dist/assets/fonts/(.*)

  - url: /.*
    static_files: dist/index.html
    upload: dist/index.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM