javascriptionic-frameworkweb-componentstenciljs

How to initialize ionics "auto-lazy loading" stencil components properly?


TLDR; I want to initialize all components at once using the @ionic/core npm package instead of initialize() and for each component defineCustomElement()

I started digging into ionic without frameworks (plain web components) and npm i the @ionic/core package. It's documentation says it has some "auto lazy-loading" stencil components to use out of the box by including the respective script tags (find the docs here). This works without problems, like:

<!DOCTYPE html>
<html class="hydrated">
  <head>
    <meta charset="utf-8" />
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"
    ></script>
    <script
      nomodule
      src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"
    ></script>
    <link
      href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <ion-button>Hello Button</ion-button>
  </body>
</html>

Also importing from @ionic/core/components and then initializing manually works well:

import { initialize } from "@ionic/core/components";
import { defineCustomElement } from "@ionic/core/components/ion-button";

initialize();//initializes ionic and prepares the html
defineCustomElement();//initializes a certain type of element

The latter is said to be especially for projects using bundlers like webpack as only those components will be included in the package that were used. While I understand why this is, I don't want it in my project. I want all components to be initialized like in the first example but I don't want to use the CDN, I want to use the npm package and just once call some function like initialize. As the CDN and the npm packages are said to be equal I thought I could just look after the path @ionic/core/dist/ionic/ionic.esm.js but apperently this file does not exist in my node_modules. Now I'm a bit stuck. Anyone a suggestion how I can make this work?

I don't want to use the CDN because I use lot's of other libs in my project and manage everything via npm and it would anoy me to know I have this single dependency that needs special handling. Others than that I plan to build for iOS and Android natively with capacitor but have no experience and am unsure if the CDN usage would create problems in terms of offline functionality of the app.


Solution

  • Ok, I found it.

    Stencil acutally even uses ionic as the example. Find the solution here. To make it short. A Stencil built component library will have a folder "loader" in it's output. This contains a file index.es2017. You can import { defineCustomElements } from "@ionic/core/loader/index.es2017";. defineCustomElements() will also initialize() the app with default config. I'm unsure if there is a better way to do things but explicitly calling initialize() before defineCustomElements() let's you then also pass a custom config (e.g. to switch modes from md to ios).