1

We are trying to build an Angular Element (with Angular 7) that should be used in an AngularJS project. The output .js file is 5 MB large ... to much.

An analysis with webpack-bundle-analyzer shows that most space is used by dependencies that are also needed in the AngularJS project - it should not be necessary to have the libraries two times in the code.

So my thought was to declare those dependencies as peerDependencies in package.json. I hoped that the output file would become smaller. But unfortunately the build result with peerDependencies is the same in size. Am I misunderstanding the concept of peerDependencies or do I need a special build parameter?

"dependencies": {
    "@angular/animations": "^7.2.7",
    "@angular/cdk": "^7.3.3",
    "@angular/common": "^7.2.7",
    "@angular/compiler": "^7.2.7",
    "@angular/core": "^7.2.7",
    "@angular/elements": "^7.2.7",
    "@angular/forms": "^7.2.7",
    "@angular/http": "^7.2.7",
    "@angular/material": "^7.3.3",
    "@angular/platform-browser": "^7.2.7",
    "@angular/platform-browser-dynamic": "^7.2.7",
    "@angular/router": "^7.2.7",
    "@angular/upgrade": "^7.2.7",
    "dateformat": "^3.0.2",
    "in-view": "^0.6.1",
    "keycode": "^2.1.9",
    "lodash": "^4.17.5",
    "material-design-icons": "^3.0.1",
    "ng2-nouislider": "^1.7.13",
    "nouislider": "^12.1.0",
    "reflect-metadata": "^0.1.12",
    "rxjs": "6.4.0",
    "rxjs-compat": "^6.0.0-rc.0",
    "zone.js": "^0.8.29"
  },
  "peerDependencies": {
    "compass-mixins": "^0.12.10",
    "core-js": "^2.5.4",
    "devextreme": "^18.2.6",
    "devextreme-angular": "^18.2.6",
    "devextreme-intl": "^18.2.6",
    "jquery": "^3.0.0",
    "muuri": "0.5.4",
    "moment": "^2.22.2"
  },
 "devDependencies": {
    "@angular-devkit/build-angular": "~0.10.0",
    "@angular/cli": "~7.3.4",
    "@angular/compiler-cli": "7.2.7",
    "@angular/language-service": "~7.2.7",
    "@angular/platform-server": "7.2.7",
    "@types/dateformat": "^1.0.1",
    "@types/jasmine": "^2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/jquery": "^3.2.12",
    "@types/node": "^8.9.5",
    "clang-format": "^1.0.32",
    "core-js": "^2.5.4",
    "codelyzer": "~4.5.0",
    "compass-mixins": "^0.12.10",
    "css-loader": "^0.28.7",
    "del": "^3.0.0",
    "devextreme": "^18.2.6",
    "devextreme-angular": "^18.2.6",
    "devextreme-intl": "^18.2.6",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "file-loader": "^1.1.1",
    "fs-extra": "^4.0.1",
    "html-loader": "^0.5.1",
    "html-webpack-plugin": "^3.2.0",
    "jasmine-core": "^2.99.0",
    "jquery": "^3.0.0",
    "karma": "~4.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-typescript": "^4.0.0",
    "lodash.throttle": "^4.1.1",
    "moment": "^2.22.2",
    "muuri": "0.5.4",
    "ng-packagr": "^5.1.0",
    "ng-annotate-webpack-plugin": "^0.2.1-pre",
    "ng-focus-if": "^1.0.7",
    "node-sass": "^4.10.0",
    "node-sass-json-importer": "^3.0.2",
    "pre-commit": "^1.2.2",
    "properties-loader": "0.0.1",
    "protractor": "~5.4.0",
    "sass-loader": "^7.0.1",
    "script-loader": "^0.7.2",
    "source-map-loader": "^0.2.1",
    "style-loader": "^0.21.0",
    "ts-loader": "^4.2.0",
    "ts-node": "~7.0.0",
    "tslint": "^5.11.0",
    "typescript": "3.2.4",
    "webpack-bundle-analyzer": "^3.0.3"
  }

For example, 1,88 MB of disk space is needed by the Devextreme dependency, also as peer dependency.

user1916076
  • 145
  • 1
  • 16
  • 1
    Do you need to bundle this? It's not a distributed library. It's a package. So the host package is responsible for bundling this, no? The host package should just install this package. – Rafael Apr 17 '19 at 08:14
  • The basic idea was: the AngularJS host should not need to know about our Angular 7 framework and just include the generated, framework agnostic JavaScript - a Custom Component built by Angular Elements. I think when our project is used as a package, the host has to care about Angular 7, too ... or am I wrong? – user1916076 Apr 17 '19 at 08:49
  • 2
    I think you somewhat answered your own question. Your intention is to deploy the angular element as self-bootstrapping, so it'll need its own dependencies irregardless of the host environment. Peer dependencies are for reducing package duplication which sounds like a different issue. – Rafael Apr 17 '19 at 09:19
  • 1
    Thank you for the clarification... so I guess we need to think again about the scenario. – user1916076 Apr 17 '19 at 10:01

1 Answers1

2

The peer dependency part is already covered in the commetns and it is clear that you like to share the dependencies of your Angular Element. The problem is, that this is not officially supported yet.

A solution might be ngx-build-plus.

With this plugin for the CLI it is possible to share dependencies among Angular Elements. This is described in step 5:

Create a file webpack.extra.js with a partial webpack config that tells webpack to exclude packages like @angular/core:

module.exports = {
    "externals": {
        "rxjs": "rxjs",
        "@angular/core": "ng.core",
        "@angular/common": "ng.common",
        "@angular/platform-browser": "ng.platformBrowser",
        "@angular/elements": "ng.elements"
    }
}
jowey
  • 7,581
  • 6
  • 27
  • 46
  • Thank you for the hint. I prepared the project as it was instructed in the linked page. The reduction works for the above mentioned dependencies, the bundle size is reduced to 4.7 MB (from 5 MB). Unfortunately, when I add the biggest dependency "devextreme" to the externals list, it does not affect the output size at all. – user1916076 May 09 '19 at 11:24
  • 1
    As I'm not experienced with DevExtreme sadly I can't give you a further tip, but I hope you will figure it out. – jowey May 09 '19 at 14:04