Differential loading not working in Angular 12: "Uncaught SyntaxError: Unexpected token ':'"

Viewed 669

I recently came across the error of bundle size exceeding the budget limits in our Angular 12 project. While implementing several ways to reduce the bundle size, differential loading was one such way. Angular provides this as default and enables this for you once you set your target to es2015 in your tsconfig.app.json and your .browserslistrc configuration.

But to my surprise, something is not working even after following the above two steps. We are using @angular-builders/custom-webpack as our builder. In our custom webpack configuration we are just using DefinePlugin to add some environment specific variables.

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

My 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"
    ]
}

Parent 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"
    ]
}

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

As per the docs, you can verify if differential loading is working by looking at your index.html file's <script> tag:

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

My index.html's <script> tags looks like this:

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

I can't seem to find either es5 or es2015 keywords in it. Neither I could find type=module or nomodule. My bundle size surely got reduced but my project is not working either on the serve or after deployment. I am getting the below error in the console of the browser (Chrome 91.0.4472.101) which is unclear:

enter image description here

My polyfill.ts:

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

I came across this issue which states that differential loading doesn't take place during serve but for me it is also not working after deployment. Just to avoid any configurational errors I also created a fresh demo project in Angular 12 and everything is working fine there. I have also matched the values of the above files. The only differences that I found were:

  • Custom webpack is not used in the demo project
  • polyfill.ts only contained import of Zone.js

Even the demo project's index.html didn't contain the es5, es2015, module, nomodule keywords and was similar to my project's index.html.

I have spent a lot of time on this but can't find any solution. Please let me know if I am missing anything.

0 Answers
Related