Differential loading script references in index.html different when running ng serve vs. ng build

China☆狼群 提交于 2019-12-08 00:40:39

问题


After upgrading to Angular 8, ng build generates a proper index.html that supports differential loading however ng serve generates a different index.html that contains references to only some of the generated 'es5' scripts. As a result, the app does not work in ES5 browsers like IE 11.

So far I have:

  • confirmed the app runs as expected in modern ES2015+ browsers like Chrome
  • confirmed the app worked on IE 11 prior to the Angular 8 upgrade
  • compared index.html source in IE 11 to source generated in dist directory from ng build, can see differences in script references (see sample code below)
  • searched angular and angular-cli issues on Github and stackoverflow for similar problems
  • tried building and serving with and without the soon to be deprecated es5BrowserSupport option in angular.json
  • updated to the latest versions of @angular-devkit and @angular packages

The repository I am working on contains an application project and a library project. Here are the relevant architect targets from angular.json after the Angular 8 upgrade:

      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/ng-shared-components-tester",
            "index": "projects/ng-shared-components-tester/src/index.html",
            "main": "projects/ng-shared-components-tester/src/main.ts",
            "polyfills": "projects/ng-shared-components-tester/src/polyfills.ts",
            "tsConfig": "projects/ng-shared-components-tester/tsconfig.app.json",
            "assets": [
              "projects/ng-shared-components-tester/src/favicon.ico",
              "projects/ng-shared-components-tester/src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "projects/ng-shared-components-tester/src/styles.css",
              "node_modules/abc-emerald-standards/dist/emerald/assets/css/default.css",
              "node_modules/abc-emerald-standards/dist/emerald/assets/css/forms.css"
            ],
            "scripts": [],
            "es5BrowserSupport": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "projects/ng-shared-components-tester/src/environments/environment.ts",
                  "with": "projects/ng-shared-components-tester/src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "ng-shared-components-tester:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ng-shared-components-tester:build:production"
            }
          }
        },

Here is the browserlist file with IE 11 support enabled:

> 0.5%
last 4 versions
IE 11
not dead

tsconfig.json:

{
  "compileOnSave": false,
  "compilerOptions": {
    "importHelpers": true,
    "outDir": "./dist/out-tsc",
    "baseUrl": "./",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "module": "esnext",
    "paths": {
      "@abc/ng-shared-components": [
        "dist/abc/ng-shared-components"
      ],
      "@abc/ng-shared-components/*": [
        "dist/abc/ng-shared-components/*"
      ]
    }
  },
  "angularCompilerOptions": {
    "annotateForClosureCompiler": true,
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  },
}

Expected Result

ng build is generated the expected result in dist/ng-shared-components-tester/index.html:

<body>
  <app-root></app-root>
  <script src="runtime-es2015.js" type="module"></script>
  <script src="polyfills-es2015.js" type="module"></script>
  <script src="runtime-es5.js" nomodule></script>
  <script src="polyfills-es5.js" nomodule></script>
  <script src="styles-es2015.js" type="module"></script>
  <script src="styles-es5.js" nomodule></script>
  <script src="vendor-es2015.js" type="module"></script>
  <script src="main-es2015.js" type="module"></script>
  <script src="vendor-es5.js" nomodule></script>
  <script src="main-es5.js" nomodule></script>
</body>

Actual Result

ng serve is serving up an index.html to IE 11 that only contains the ES5 version of pollfills.js:

<body>
  <app-root></app-root>
  <script src="runtime.js"></script>
  <script src="polyfills-es5.js" nomodule></script>
  <script src="polyfills.js"></script><script src="styles.js"></script>
  <script src="vendor.js"></script>
  <script src="main.js"></script>
</body>

回答1:


After a little more digging I found this discussion on GitHub that indicates differential loading is disabled by default for ng serve and ng build --watch by design. This appears to be done for performance reasons (differential loading requires 2 builds to run, ES5 and non-ES5). There is a workaround to use ES5 bundles instead of the default bundles.




回答2:


That is the correct behavior of your code .Angular CLi will detect the browser and inject the polyfill script at the runtime like this

So if you are using older browser version you will the script that have nomodule tag

You can read it more here



来源:https://stackoverflow.com/questions/56529710/differential-loading-script-references-in-index-html-different-when-running-ng-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!