运行ng serve与ng build时index.html中的差异加载脚本引用不同

时间:2019-06-10 15:57:03

标签: angular angular-cli angular8

升级到Angular 8之后,ng build会生成一个支持差异加载的适当index.html,但是ng serve会生成一个仅包含对某些生成的“ es5”脚本的引用的index.html。因此,该应用程序无法在IE 11等ES5浏览器中使用。

到目前为止,我有:

  • 确认该应用程序在Chrome等现代ES2015 +浏览器中按预期运行
  • 确认该应用在Angular 8升级之前可在IE 11上运行
  • 将IE 11中的index.html源与从ng build在dist目录中生成的源进行了比较,可以看到脚本引用的不同(请参见下面的示例代码)
  • 在Github和stackoverflow上搜索Angle和angular-cli问题以寻找类似问题
  • 尝试使用angular.json中的es5BrowserSupport选项(无论是否即将弃用)来构建和提供服务
  • 已更新为@ angular-devkit和@angular软件包的最新版本

我正在使用的存储库包含一个应用程序项目和一个库项目。以下是Angular 8升级后angular.json中的相关架构师目标:

      "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"
            }
          }
        },

以下是启用了IE 11支持的浏览器列表文件:

> 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
  },
}

预期结果

ng build在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>

实际结果

ng serve正在为IE 11提供index.html,其中仅包含pollfills.js的ES5版本:

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

2 个答案:

答案 0 :(得分:0)

这是您代码的正确行为。AngularCLi将检测浏览器并在运行时像这样注入polyfill脚本

enter image description here

因此,如果您使用的是旧版浏览器,则将使用没有模块标记的脚本

您可以阅读更多here

答案 1 :(得分:0)

经过进一步的挖掘,我发现此discussion on GitHub表示根据设计,默认情况下ng serveng build --watch的差分加载是禁用的。这样做似乎是出于性能方面的考虑(差异加载需要运行2个版本(ES5和非ES5))。有一种解决方法可以使用ES5捆绑包代替默认捆绑包。