运行 ng serve 与 ng build 时,index.html 中的差异加载脚本引用不同 [英] Differential loading script references in index.html different when running ng serve vs. ng build

查看:34
本文介绍了运行 ng serve 与 ng build 时,index.html 中的差异加载脚本引用不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

升级到 Angular 8 后,ng build 会生成一个支持差异加载的正确 index.html,但是 ng serve 会生成一个不同的 index.html,其中只包含对某些内容的引用生成的es5"脚本.因此,该应用无法在 IE 11 等 ES5 浏览器中运行.

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.

到目前为止我有:

  • 确认该应用在 Chrome 等现代 ES2015+ 浏览器中按预期运行
  • 在 Angular 8 升级之前确认该应用可在 IE 11 上运行
  • 将 IE 11 中的 index.html 源代码与 ng build 在 dist 目录中生成的源代码进行比较,可以看到脚本引用的差异(参见下面的示例代码)
  • 在 Github 和 stackoverflow 上搜索 angular 和 angular-cli 问题以解决类似问题
  • 尝试在 angular.json 中使用和不使用即将弃用的 es5BrowserSupport 选项构建和服务
  • 更新到最新版本的@angular-devkit 和@angular 包
  • 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

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

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

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

Here is the browserlist file with IE 11 support enabled:

> 0.5%
last 4 versions
IE 11
not dead

tsconfig.json:

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 中生成预期结果:

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>

实际结果

ng serve 正在向 IE 11 提供一个 index.html,其中只包含 ES5 版本的 pollfills.js:

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>

推荐答案

经过更多的挖掘,我发现了这个 GitHub 上的讨论 表明 ng serveng build --watch 在默认情况下禁用差异加载.这似乎是出于性能原因(差异加载需要运行 2 个构建,ES5 和非 ES5).有一种解决方法可以使用 ES5 包而不是默认包.

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.

这篇关于运行 ng serve 与 ng build 时,index.html 中的差异加载脚本引用不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆