2

There seems to be a change if not a bug to how Angular8 packages up index.html that is breaking my deployment.

The scripts at the bottom of the index.html in the dist folder no longer have type="text/javascript"

<script src="runtime-es2015.b1e01c6054a9feffbeda.js" type="module"></script>
<script src="polyfills-es2015.dd0ef0c762416a11ccfe.js" type="module"></script>
<script src="runtime-es5.b1e01c6054a9feffbeda.js" nomodule></script><script src="polyfills-es5.ad2e20378bba1e661425.js" nomodule></script>
<script src="scripts.03e042f1f102bf0e2ed8.js"></script><script src="main-es2015.59f62c10fb8246590dad.js" type="module"></script><script src="main-es5.d5d8d375e147ae1da6f0.js" nomodule></script></body>

After deploy, I get errors in chrome and firefox like:

Loading module from “https://yarrascrape.appspot.com/runtime-es2015.b1e01c6054a9feffbeda.js” was blocked because of a disallowed MIME type (“text/plain”).

or

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec.

This would likely affect different types of web servers.

I am using AppEngine with python runtime. I have attempted to set the mime type in the app.yaml with variations like:

- url: /(.*\.(js))$
  secure: always
  static_files: \1
  upload: (.*)
  http_headers:
    content_type: text/javascript

- url: /(.*)
  secure: always
  static_files: \1
  upload: (.*)
  http_headers:
    content_type: text/javascript

This hasn't worked. Either the approach is wrong, or my yaml is wrong.

After the build, as an experiment, I manually edited dist/index.html and inserted type="text/javascript" to all the scripts at the bottom of the file. This works, but I am looking for a viable solution.

Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
intotecho
  • 4,925
  • 3
  • 39
  • 54

3 Answers3

3

In this context:

  • Google AppEngine standard python environment
  • Angular 8
  • recent Chrome version

I don't encounter any problem with this new Angular version 8, and Google AppEngine standard deployment.

My handler in GAE looks like this :

handlers:
- url: /(.+\.js)
  static_files: app/\1
  upload: app/(.+\.js)

This change in Angular 8 is due to new differential loading feature. Now, ng build is building 2 versions of each JS bundle. A old ES5 syntax, and a new modern ES2015 version (JS module).

You can read more details here : https://angular.io/guide/deployment#differential-loading

You may opt-out of this change by setting your target back to es5 in your tsconfig.json

Maybe it could be a first workaround option, the time to understand the real problem.

Updated

As requested, here is the full app.yaml content. These handlers rules could be optimized. Here, I kept them in a detailed form with each file type.

runtime: python27
threadsafe: true
api_version: 1

handlers:
- url: /(.+\.js)
  static_files: app/\1
  upload: app/(.+\.js)

- url: /(.+\.css)
  static_files: app/\1
  upload: app/(.+\.css)

- url: /(.+\.png)
  static_files: app/\1
  upload: app/(.+\.png)

- url: /(.+\.jpg)
  static_files: app/\1
  upload: app/(.+\.jpg)

- url: /(.+\.svg)
  static_files: app/\1
  upload: app/(.+\.svg)

- url: /favicon.ico
  static_files: app/favicon.ico
  upload: app/favicon.ico

- url: /(.+\.json)
  static_files: app/\1
  upload: app/(.+\.json)

- url: /(.+)
  static_files: app/index.html
  upload: app/index.html

- url: /
  static_files: app/index.html
  upload: app/index.html
Thierry Falvo
  • 5,892
  • 2
  • 21
  • 39
  • That fixes it! I had to change tsconfig.json in two places. the target and the "lib". – intotecho Jul 02 '19 at 06:40
  • You're handler change worked for me @Thierry thanks. Could you possible post your entire app.yaml? I've been going off the one posted in [this answer](https://stackoverflow.com/questions/39782506/deploying-basic-angular-2-app-to-google-app-engine) and I got the above mime-type error in angular 8 – Nicholas Jul 09 '19 at 03:45
  • 1
    You're welcome. Answer updated with full `app.yaml` content. – Thierry Falvo Jul 09 '19 at 09:15
  • Updating chrome was important for me and setting "outputPath": "dist/" as described in https://github.com/aws-amplify/amplify-cli/issues/1995 – Simon Oct 18 '19 at 21:19
0

My tech stack is a bit different (ie., I'm not using Python), but this may be of help:

I encountered the same issue/browser errors with a MEAN Stack app (with Angular 8/ Node v11.6.0) that I've been working on when running ng build --prod (which is supposed to run AOT- Ahead of Time Compilation by default, but it was failing to compile in a way that could be read by Chrome + Firefox for some reason that I can't explain). After visiting the Angular docs (https://angular.io/guide/aot-compiler), I tried running ng build --aot instead of ng build --prod before running my node server and the issue went away.

Hope this helps:-)

0

My Angular 13 production build .js files were statically served with text/plain mime-type by Google Cloud Platform Standard App Engine subsequently making my application fail to use them with error message:

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec.

Fix was explicitly specifying mime-type for served .js files in .yaml file.

runtime: nodejs16
service: default
handlers:
    # Serve all JS files with text/javascript mime-type
    - url: /(.*\.js)$
      static_files: dist/\1
      upload: dist/(.*\.js)$
      mime_type: text/javascript
    
    # Serve all static files with urls ending with a file extension
    - url: /(.*\..+)$
      static_files: dist/\1
      upload: dist/(.*\..+)$
    
    # catch all handler to index.html
    - url: /.*
      static_files: dist/index.html
      upload: dist/index.html
Maz T
  • 1,184
  • 13
  • 18