1

Angular Elements are Angular components packaged as custom elements. Each Angular Elements ship the angular core. If in a standard html page i include 5 Angular Elements components, this page download 5 times the angular core.

There is a way for include once tha angular core e download only the components code?

ar099968
  • 6,963
  • 12
  • 64
  • 127

2 Answers2

4

This is a problem that is supposed to be eliminated when the ivy renderer finally is released (https://is-angular-ivy-ready.firebaseapp.com/#/status - status didn't change in the last several months...), as it's supposed to treeshake any unused code and thus reduce the size of every element.

In the meantime you can use https://github.com/manfredsteyer/ngx-build-plus#advanced-example-externals-and-angular-elements to exclude base packages from your custom elements builds and provide those in your base application, so for example angular core, rxjs etc. are loaded only once.

EDIT: make sure you load your custom elements after the main app (by using defer or dynamically loading them) to make sure the required base scripts are loaded. You don't need to add the umd libs like mentioned in the project readme, just makes sure your base application has all those scripts (by adding them to angular.json if not already imported)

Markus Dresch
  • 5,290
  • 3
  • 20
  • 40
3

You can use ngx-build-plus and make them externals. Read This: https://www.npmjs.com/package/ngx-build-plus

Here is the final html would look like:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ElementsLoading</title>
<base href="/">

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>

<!-- Consider putting the following UMD (!) bundles -->
<!-- into a big one -->

<!-- core-js for legacy browsers -->
<script src="./assets/core-js/core.js"></script>

<!-- Zone.js -->
<!-- 
    Consider excluding zone.js when creating
    custom Elements by using the noop zone.
-->
<script src="./assets/zone.js/zone.js"></script>


<!-- Polyfills for Browsers supporting 
        Custom Elements. Needed b/c we downlevel
        to ES5. See: @webcomponents/custom-elements
-->
<script src="./assets/custom-elements/src/native-shim.js"></script>

<!-- Polyfills for Browsers not supporting
        Custom Elements. See: @webcomponents/custom-elements
-->
<script src="./assets/custom-elements/custom-elements.min.js"></script>


<!-- Rx -->
<script src="./assets/rxjs/rxjs.umd.js"></script>

<!-- Angular Packages -->
<script src="./assets/core/bundles/core.umd.js"></script>
<script src="./assets/common/bundles/common.umd.js"></script>
<script src="./assets/platform-browser/bundles/platform-browser.umd.js"></script>
<script src="./assets/elements/bundles/elements.umd.js"></script>

<!-- Calling Custom Element -->
<custom-element></custom-element>

</body>
</html>

I am able to do this and able to externalize angular modules. But I wanted to know how I can externalize my custom libraries created in angular? One thing I see is Angular creates UMD bundles where ng.core, ng.common are defined as globals (so that I can access them through window object). I tried using rollupjs to create umd bundles but it does create any globals variable like it did for angular components. I am stuck here and looking for ideas. Thanks!

Kashyap
  • 178
  • 1
  • 2
  • 11
  • I found the answer to my question. I didn't notice that `ng build --prod` creates umd bundle. This solves my issue. Thanks! – Kashyap Aug 14 '19 at 16:55
  • Please do not ask another question when answering existing one. If you have a new question you should ask a brand new one. – Dharman Aug 25 '19 at 10:13