【问题标题】:Deploying basic Angular 2 app to Google App Engine将基本的 Angular 2 应用程序部署到 Google App Engine
【发布时间】:2017-02-08 11:59:48
【问题描述】:

我可以使用 Angular 2 创建基本的前端应用程序,并且可以使用 python 在 Google App 引擎上创建带有端点的后端。但是,我似乎无法弄清楚如何将两者放在一起并使用云 SDK 部署它们。

这是一个基本示例,我什至无法在 GAE 上托管一个没有后端调用的简单 angular2 应用程序。我在使用 angular2 CLI 构建后获取了 dist 文件夹,并尝试使用 app.yaml 文件连接到它。它似乎在浏览器开发人员(dev_appserver.py app.yaml)中工作,尽管我在 SDK 中收到一些 404 错误,GET 请求与我认为的 index.html 文件有关。然后,我创建了一个空白 index.yaml 文件并尝试部署它,但在 appspot.com 位置出现 404 错误。这是 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

我真的不知道我做错了什么。我需要某种 main.application python 后端来连接到 dist 文件吗?我是否需要包含来自 Angular2 的节点模块或其他类型或文件?任何帮助将不胜感激!谢谢

【问题讨论】:

标签: google-app-engine angular app.yaml google-cloud-sdk


【解决方案1】:

对于 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

寻求有关如何改进的反馈。

【讨论】:

  • 目前为止最好的答案。如果我发现和改进我会回来的。谢谢
  • @Rob 我会将其设置为接受的答案。您是否曾经将这种或任何其他类型的 sever-side rendering 合并到部署中?
  • 不,我在登录后构建了一个网络应用程序,所以我不担心搜索引擎。
  • 我试过这个,但现在突然间而不是我的 js/css 文件,index.html 文件正在被提供
  • 这适用于 Angular 6 吗?我收到“错误:未找到请求的 URL / 未在此服务器上找到”。错误。
【解决方案2】:

我现在更新我的 app.yaml 文件中的处理程序,使其看起来像这样,以便静态上传到谷歌云平台。如果正则表达式不是这样,Angular Router 就会出现问题。 Dist 文件夹是从 angular cli 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

更新:

对于生产 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

我会将 dist 文件夹中的任何其他文件类型添加到第一个处理程序中的正则表达式分组字符:(gif|png|jpeg|jpg|css|js|ico)

【讨论】:

  • 有什么文档可以参考吗?你是怎么想出来的?
  • 为什么我们在 nodejs 平台上使用 python27 运行时?
  • 在本次问答时,我在应用引擎上的所有应用程序后端 API 都是用 python27 编写的。如果我现在自己托管一个角度站点,我开始使用 nodejs 进行服务器端渲染:youtube.com/watch?v=VS0zsXvDJ08
【解决方案3】:

对于 Angular 6,文件结构有所改变。以下内容基于@Rob 的回答,但针对启用了服务工作者的 Angular 6 进行了更新。请务必将“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

【讨论】:

    【解决方案4】:

    看起来您的正则表达式匹配在错误的位置。试试这个格式:

    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/(.*)
    

    这来自于我们在创建Static Hosting tutorial on App Engine 时遇到的测试和一些奇怪的问题。

    【讨论】:

    • 非常感谢。真的很挣扎!
    【解决方案5】:

    将您的 app.yaml 替换为以下内容。它会起作用的!

    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"
    

    【讨论】:

    • 嗨@Ivaro18 我现在看到这是一个很好的标准 app.yaml 文件,可用于我的 angular2 项目。您将如何更改它以使路由在 apppot 刷新时起作用?我发布了另一个问题,但还没有帮助:link。任何帮助将不胜感激
    • @Nipun Madan 指的是 Nipun,我只是将 URL 替换为实际代码
    【解决方案6】:

    首先通过运行以下命令构建您的 Angular 项目

    --ng build prod
    

    构建完成后,在项目的根文件夹中创建一个 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
    

    运行后:

    gcloud app deploy
    

    【讨论】:

      【解决方案7】:

      如果您使用自定义字体,您可以使用此模板:

      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
      

      【讨论】:

        猜你喜欢
        • 2016-09-15
        • 1970-01-01
        • 1970-01-01
        • 2014-07-27
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多