Angular Cli Webpack, How to add or bundle external js files?

There is a subtle difference to using scripts:[] then to adding something to the <head> with <script>. Scripts from scripts:[] get added to the scripts.bundle.js that gets always loaded in the body tag and will thus be loaded AFTER scripts in <head>. Thus if script loading order matters (i.e. you need to load a global polyfill), then your only option is to manually copy scripts to a folder (e.g. with a npm script) and add this folder as an asset to .angular-cli.json.

So if you really depend on something being loaded before angular itself (Option A), then you need to copy it manually to a folder that will be included in the angular build and then you can load it manually with a <script> in <head>.

Thus, for achieving option a you have to:

  • create a vendor folder in src/
  • add this folder as an asset to .angular-cli.json:
"assets": [
    "assets",
    "favicon.ico",
     "vendor"
  ]
  • copy your vendor script node_modules/some_package/somejs.js to vendor

  • load it manually in index.html: <head> <script src="vendor/some_package/somejs.js"> </head>

However most of the time you only need this approach for packages, that need to be available globally, before everything else (i.e. certain polyfills). Kris' answer holds true for Option B and you get the benefit of the webpack build (Minification, Hashes, ...).

However if your scripts need not be globally available and if they are module-ready you can import them in src/polyfills.ts or even better import them only when you need them in your specific components.

Making scripts globally available via scripts:[] or via manually loading them brings it own set of problems and should really only be used, when it is absolutely necessary.


Last tested using angular-cli 11.x.x with Angular 11.x.x

This can be accomplished using scripts:[] in angular.json.

{
  "project": {
    "version": "1.0.0",
    "name": "my-project"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": ["assets"],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "styles.css"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.js"
      ],
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "addons": [],
  "packages": [],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "prefixInterfaces": false
  }
}

Note: As the documentation suggests in the global library installation: if you change the value of your styles (or scripts!) property, then:

Restart ng serve if you're running it,

..to see the scripts executed in a **globalcontext via the scripts.bundle.js file.

Note: As discussed in the comments below. JS libs that support UMD modules via es6 imports such as jQuery can also be imported into your typescript files using the es6 import syntax. For example: import $ from 'jquery';.