node.js - Differentiell laddning fungerar inte i Angular 12: "Uncaught SyntaxError: Unexpected token ':'"


Jag stötte nyligen på felet att paketstorleken överskrider budgetgränserna i vårt Angular 12-projekt. När jag implementerade flera sätt att minska paketstorleken var differential loading ett sådant sätt. Angular tillhandahåller detta som standard och aktiverar det åt dig när du anger din target till es2015 i din tsconfig.app.json och din .browserslistrc-konfiguration.

Men till min förvåning fungerar något inte ens efter att ha följt de ovanstående två stegen. Vi använder @angular-builders/custom-webpack som vår byggare. I vår anpassade webpack-konfiguration använder vi bara DefinePlugin för att lägga till några miljöspecifika variabler.

Min angular.json:

"architect": {
    "build": {
        "builder": "@angular-builders/custom-webpack:browser",
        "options": {
            "outputPath": "dist/apps/my-project",
            "index": "apps/my-project/src/index.html",
            "main": "apps/my-project/src/main.ts",
            "polyfills": "apps/my-project/src/polyfills.ts",
            "tsConfig": "apps/my-project/tsconfig.app.json",
            "aot": true,
            "customWebpackConfig": {
                "path": "apps/my-project/webpack.config.js",
                "mergeRules": {
                    "externals": "replace"
                }
            }
        },
        "configurations": {
            "prod": {
                "outputPath": "dist/apps/my-project-prod",
                "customWebpackConfig": {
                    "path": "apps/my-project/webpack.prod.partial.js",
                    "mergeRules": {
                        "externals": "replace"
                    }
                },
                "baseHref": "https://my-project.com/",
                "fileReplacements": [
                    {
                        "replace": "apps/my-project/src/environments/environment.ts",
                        "with": "apps/my-project/src/environments/environment.prod.ts"
                    }
                ],
                "index": {
                    "input": "apps/my-project/src/index.prod.html",
                    "output": "/index.html"
                },
                "optimization": true,
                "outputHashing": "all",
                "sourceMap": false,
                "namedChunks": false,
                "aot": true,
                "extractLicenses": true,
                "vendorChunk": false,
                "buildOptimizer": true,
                "budgets": [
                    {
                        "type": "initial",
                        "maximumWarning": "2mb",
                        "maximumError": "5mb"
                    }
                ]
            }
        }
    },
    "serve": {
        "builder": "@angular-builders/custom-webpack:dev-server",
        "options": {
            "host": "localhost",
            "baseHref": "http://localhost:3000",
            "port": 3000,
            "browserTarget": "my-project:build"
        },
        "configurations": {
            "prod": {
                "browserTarget": "my-project:build:prod"
            }
        }
    }
}

Min tsconfig.app.json:

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
       "outDir": "../../dist/out-tsc/apps/my-project",
        "types": ["node"],
        "typeRoots": [
            "./src/customTypes"
        ]
    },
    "exclude": [
        "src/test.ts",
        "**/*.spec.ts"
    ],
    "files": [
        "src/main.ts",
        "src/polyfills.ts",
    ],
    "include": [
        "src/**/*.ts"
    ]
}

Förälder tsconfig.json:

{
    "compileOnSave": false,
    "compilerOptions": {
        "inlineSources": true,
        "sourceMap": true,
        "declaration": false,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "importHelpers": true,
        "target": "es2015",
        "module": "es2020",
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2018",
            "dom"
        ],
        "skipLibCheck": true,
        "skipDefaultLibCheck": true,
        "baseUrl": "./"
    },
    "exclude": [
        "node_modules",
        "tmp"
    ]
}

Min .browserslistrc:

last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11

Enligt dokumentationen kan du kontrollera om differential laddning fungerar genom att titta på index.html-filens <script>-tagg:

<body>
  <app-root></app-root>
  <script src="runtime-es2015.js" type="module"></script>
  <script src="runtime-es5.js" nomodule></script>
  <script src="polyfills-es2015.js" type="module"></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="vendor-es5.js" nomodule></script>
  <script src="main-es2015.js" type="module"></script>
  <script src="main-es5.js" nomodule></script>
</body>

Mina index.html-taggar <script> ser ut så här:

<script src="runtime.f03314b4ecbf857f30db.js" defer></script>
<script src="polyfills.b4a4dc722533999c6a79.js" defer></script>
<script src="scripts.d0fcd864b87b7eb9e1e6.js" defer></script>
<script src="vendor.2070a0076d5aa66a3b91.js" defer></script>
<script src="main.c7fdac1323ac33ecb488.js" defer></script>

Jag verkar inte kunna hitta vare sig es5 eller es2015-nyckelord i det. Inte heller kunde jag hitta type=module eller nomodule. Min paketstorlek har säkert minskat, men mitt projekt fungerar varken på servern eller efter distributionen. Jag får följande fel i webbläsarens konsol (Chrome 91.0.4472.101) vilket är oklart:

Min polyfill.ts:

import 'core-js/es/reflect';
import '@angular/localize/init';
import 'zone.js/dist/zone';
(window as any)['global'] = window;

Jag stötte på detta problem som säger att differential loading inte sker under serve men för mig fungerar det inte heller efter distribuering. För att undvika några konfigurationsfel skapade jag även ett nytt demo-projekt i Angular 12 och där fungerar allt bra. Jag har också matchat värdena i ovanstående filer. De enda skillnaderna jag hittade var:

  • Anpassad webpack används inte i demoprojektet
  • polyfill.ts innehöll endast import av Zone.js

Även demonstrationsprojektets index.html innehöll inte es5, es2015, module, nomodule nyckelord och var liknande min projekts index.html.

Jag har lagt mycket tid på detta men kan inte hitta någon lösning. Vänligen låt mig veta om jag missar något.