Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

index.js in dist/esm folder is empty and will cause component not being load in html pages #2826

Closed
RezaRahmati opened this issue Feb 13, 2021 · 15 comments
Assignees
Labels
Bug: Validated This PR or Issue is verified to be a bug within Stencil

Comments

@RezaRahmati
Copy link

RezaRahmati commented Feb 13, 2021

Stencil version:

 @stencil/core@2.4.0

I'm submitting a:

[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:
in the dist folder, index.js content is

export * from './esm/index.js';

Then in the esm folder, content of index.js is empty

Expected behavior:
There should be something is index.js otherwise nothing will be loaded when referencing like
https://cdn.jsdelivr.net/npm/@zoot-ai/widget@0.1.31/dist/index.js

Steps to reproduce:

  • create a new project by running npm init stencil and choose component
  • run npm install
  • run npm build
  • check the content of dist folder
    Related code:

I tried to load my component in jsfiddle by this code, but whenDefined is never resolved
(I added https://cdn.jsdelivr.net/npm/@zoot-ai/widget@0.1.31/dist/index.js as reference in my jsfiddle)

(async () => {
  await customElements.whenDefined('zoot-widget');
  
  const myComp = document.querySelector('zoot-widget');
})();
// insert any relevant code here

Other information:

I take a look at ionic, and seems file is not empty
https://cdn.jsdelivr.net/npm/@ionic/core/dist/index.js

export * from './esm-es5/index.js';

and
https://cdn.jsdelivr.net/npm/@ionic/core/dist/esm-es5/index.js

import"./index-e806d1f6.js";export{g as getPlatforms,i as isPlatform}from"./ionic-global-9d5c8ee3.js";import"./helpers-90f46169.js";export{c as createAnimation}from"./animation-54fe0237.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD}from"./index-d8cfb4a8.js";export{iosTransitionAnimation}from"./ios.transition-ef5e0e5f.js";export{mdTransitionAnimation}from"./md.transition-eb3c0fab.js";export{g as getTimeGivenProgression}from"./cubic-bezier-eea9a7a9.js";import"./gesture-controller-31cb6bb9.js";export{createGesture}from"./index-f49d994d.js";export{I as IonicSafeString}from"./index-9e3fe806.js";import"./hardware-back-button-4a6b37fb.js";export{m as menuController}from"./index-3a75d1af.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./overlays-12c20431.js";var setupConfig=function(o){var e=window;var r=e.Ionic;if(r&&r.config&&r.config.constructor.name!=="Object"){console.error("ionic config was already initialized");return}e.Ionic=e.Ionic||{};e.Ionic.config=Object.assign(Object.assign({},e.Ionic.config),o);return e.Ionic.config};var getMode=function(){var o=window;var e=o&&o.Ionic&&o.Ionic.config;if(e){if(e.mode){return e.mode}else{return e.get("mode")}}return"md"};export{getMode,setupConfig};
@Robbson
Copy link

Robbson commented May 25, 2021

Any news on this?
Since we switched to Stencil Core 2.5.x this prevents us from using the dist output target at all in our app.
Which means that right now only the non-lazy loaded custom bundle output target can be used, right?

@thescientist13
Copy link

thescientist13 commented Dec 14, 2021

Just wanted to share my experience running into this issue as well. Was looking to use web-social-share, which is generated by Stencil but found too that all its ESM entry points are empty.

The module and esXXXX fields in the package's package.json ultimately resolve to dist/esm/index.js, which is empty. This leads to the issue observed in the OP for me as well.


As an interim solution / work around for anyone curious, I forked the library and changed its module field to point to ./dist/websocialshare/websocialshare.esm.js. As I use import maps for local development, everything was fine, but for production bundling where I use Rollup, because that file imports another file that use variables in dynamic imports

import(`./${n}.entry.js`).then(...)

I had to add the dynamic-import-vars plugin, then things worked. 🙌

Hope this could get fixed for creators and consumers alike! ✌️

@wolthers
Copy link

Just ran into this issue, and figured out that I need to export the components from src/index for it to work.

export { MyButton } from './components/my-button/my-button'

@karthikeyan-arumugam-1558

@mlynch, would you know why this happens? What's the documentation missing in this regard?

@tanner-reits
Copy link
Member

Hi @RezaRahmati and everyone else experiencing this 👋

So sorry this has sat so long. I was able to quickly verify this is a problem with the latest version of Stencil. It appears @wolthers found a workaround, but I'll still go ahead and get this labeled so the team can take a look at what's going on and see what we can do on our end. Thanks again for the issue!

@tanner-reits tanner-reits added Bug: Validated This PR or Issue is verified to be a bug within Stencil and removed triage labels Sep 2, 2022
@jonathandewitt-dev
Copy link

Thanks for your hard work @tanner-reits!

I'm experiencing this issue also, but @wolthers' workaround only got me one step further before something else impeded me.

When I import the component class from the dist folder into my demo, I get this error message: Cannot set properties of undefined (setting '$lazyInstance$'). I'm not sure if this should be its own issue, or if it's related to the fact that we are already hacking around in this area.

image

@ivancuric
Copy link

What was the last version where this was working? I've tried all the way back to 2.12 and all indexes are empty.

@alevilar
Copy link

alevilar commented Feb 4, 2023

I recently built using stencil 3.0.0 and still happens. generates only 1 line with this comment

image

@ivoba
Copy link

ivoba commented Sep 14, 2023

Still valid in 4.0.0.
I added the fix from @wolthers manually :
https://github.com/ivoba/obfuscate-wc/blob/main/src/index.ts

@florianmartens
Copy link

We ran into this at version 4.7 as well.

@rwaskiewicz rwaskiewicz added Bug: Validated This PR or Issue is verified to be a bug within Stencil and removed Bug: Validated This PR or Issue is verified to be a bug within Stencil labels Dec 4, 2023
@jxe142
Copy link

jxe142 commented Dec 13, 2023

Yeap this is still an issue

@christian-bromann christian-bromann self-assigned this Jan 17, 2024
@mattclough1
Copy link

mattclough1 commented Jan 29, 2024

I don't remember if I got to this place by my own mistakes, but I see a few things:

  1. src/index.ts just says export * from './components'
  2. There is no ./src/components/index.ts
  3. Even If I add a ./src/components/index.ts with export { MyComponent } from './my-component/my-component' it doesn't work. However, if I add a trailing slash to the index export like export * from './components/ it works fine.

Edit
I take that back. It looks like it works, but what I actually get in dist/esm/index.js is something like

export { M as MyComponent } from './my-component-10a8969a.js';
import './index-168a83d7.js';

//# sourceMappingURL=index.js.map

Where MyComponent is just the class, doesn't register it, and index-168a83d7.js only exports

export { Fragment as F, bootstrapLazy as b, h, promiseResolve as p, registerInstance as r, setNonce as s };

but doesn't seem to execute anything, relevant? The usage documentation for dist output is also a little confusing to me. I'm not sure how it's supposed to be used.

@christian-bromann
Copy link
Member

christian-bromann commented Feb 2, 2024

Hey you all 👋

I looked into the issue and hope I can shed some light into this. We have internal discussions within the Stencil team and work on creating and prioritising tickets to tackle this.

I can't speak much about the issue from the OP since I don't have a reproducible example and I can't say for sure if the issue has been solved since v2.4.0.

To @thescientist13 comment:

The module and esXXXX fields in the package's package.json ultimately resolve to dist/esm/index.js, which is empty. This leads to the issue observed in the OP for me as well.

I looked into the project and was able to get an ESM export working after some tweaks summarized in peterpeterparker/web-social-share#63

Just ran into this issue, and figured out that I need to export the components from src/index for it to work.

@wolthers I would not recommend doing this. I would consider code within src/index.ts to be for utility code, e.g. stuff that doesn't get rendered anywhere. If you like to create an output that allows you to import the compiled web component somewhere, I suggest to set the following Stencil output target:

    {
      type: 'dist-custom-elements',
      customElementsExportBehavior: 'single-export-module',
      externalRuntime: false
    }

This creates a standalone ESM component in dist/components/<project-name>.js that exports the WebComponent class as well as a helper function defineCustomElement to register the component to the CustomElementRegistry.

When I import the component class from the dist folder into my demo, I get this error message: Cannot set properties of undefined (setting '$lazyInstance$').

@jonathandewitt-dev I assume you tried to manually register the component from dist/esm which doesn't work since it can't run as standalone web component and only works in Stencils lazy loading context. Try to just import 'dist/esm/<project-name>.js' instead or import a standalone version of the component as mentioned above.

I recently built using stencil 3.0.0 and still happens. generates only 1 line with this comment

@alevilar this is "kinda" expected behavior since this file is suppose to be for your package code (stuff that doesn't need rendering like utility functions etc.). This is very confusing and we intend to clean up this confusion.

I'm not sure how it's supposed to be used.

@mattclough1 there are basically two ways to distribute Stencil components right now:

1. Through CDN or Custom Static Host

This makes it technically very easy to distribute components of a design system. You just push it to NPM and use any CDN to pull Stencils lazy loading mechanism, access any component but only load the ones you need.

For example if I create a “foobar-design-system” through the component starter utility and push it to NPM. All I need to do, to access the components in my web app is injecting a script into the page, e.g.:

<script type="module" src="https://unpkg.com/foobar-design-system@0.0.1/dist/foobar-design-system/foobar-design-system.esm.js"></script>

This loads a minified version of the bootstrap logic that knows about all components but only loads the ones that are initiated in my application.

2. As Component Library

The other way of integrating Stencil components in any arbitrary project is through importing them directly. Stencil currently allows you either import the component directly and have you register it to the Custom Element Registry:

import { AnotherComponent } from 'foobar-design-system/dist/components/another-component.js'
import { MyComponent } from 'foobar-design-system/dist/components/my-component.js'

customElements.define('my-component', MyComponent)
customElements.define('another-component', AnotherComponent)

or import a helper do that for you:

import { defineCustomElement as defineAnotherComponent } from 'foobar-design-system/dist/components/another-component.js'
import { defineCustomElement as defineMyComponent } from 'foobar-design-system/dist/components/my-component.js'

defineAnotherComponent()
defineMyComponent()

Again, this is not very clear based from our docs and the component starter tool. We intend to clear up this confusion.

@mattclough1
Copy link

mattclough1 commented Feb 6, 2024

@christian-bromann thanks! Yeah the dist-custom-elements documentation is pretty clear. Just reading through the dist docs again so I can summarize some points of confusion:

  1. collectionDir: the purpose of this is not clear, and the concept of collection is only mentioned otherwise briefly in the "Publishing A Component Library" Package.json section, and in the Ember Legacy section.

  2. A dist-collection output target is mentioned in the transformAliasedImportPathsInCollection section, but that output target isn't documented anywhere else.

  3. The script tag usage gives the example <script type="module" src='https://cdn.jsdelivr.net/npm/my-name@0.0.1/dist/myname.js'></script> but the dist output target doesn't generate a file like that. The example you gave is the only way that works.

  4. The "Importing the dist library" sections describe the step:

    Add an import within the root component: import my-component

    But what is my-component? Is it a component or is that supposed to be the name of the component library? If it's a component, this import path doesn't make any sense for this output target, and if it's the component library, this doesn't work due to the empty index files.

For my own purposes I've actually gone ahead and just made the main and module properties point to dist/foobar-design-system/foobar-design-system.(esm/cjs).js (though the CLI complains about this, which is also a little annoying) so that consumers can just import 'foobar-design-system' once to get lazy-loaded components in the application. I figure if the component library needs to export utilities they can be aliased via the package.json's exports

@christian-bromann
Copy link
Member

@mattclough1 thanks for the feedback. I have ingested separate tickets into our team backlog to:

  • move the generation of collection files into a separate output target and document its usage
  • document distribution strategies and ways to consume Stencil components
  • make a set of updates to our Stencil starter project to reduce confusions around project exports and structure

I will go ahead and close this issue. I am happy to answer any questions in case folks have more questions. Thanks for all your input 🙏

ju-Skinner added a commit to Kajabi/pine that referenced this issue Mar 8, 2024
need to use the components/index.js file for the time being.

there is a known bug and Stencil is currently working on it.

you can find more out [here](ionic-team/stencil#2826)
ju-Skinner added a commit to Kajabi/pine that referenced this issue Mar 8, 2024
need to use the components/index.js file for the time being.

there is a known bug and Stencil is currently working on it.

you can find more out [here](ionic-team/stencil#2826)
ju-Skinner added a commit to Kajabi/pine-icons that referenced this issue Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug: Validated This PR or Issue is verified to be a bug within Stencil
Projects
None yet
Development

No branches or pull requests