stencil
stencil copied to clipboard
index.js in dist/esm folder is empty and will cause component not being load in html pages
Stencil version:
@stencil/[email protected]
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/[email protected]/dist/index.js
Steps to reproduce:
- create a new project by running
npm init stenciland choosecomponent - run
npm install - run
npm build - check the content of
distfolder 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/[email protected]/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};
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?
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! ✌️
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'
@mlynch, would you know why this happens? What's the documentation missing in this regard?
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!
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.

What was the last version where this was working? I've tried all the way back to 2.12 and all indexes are empty.
I recently built using stencil 3.0.0 and still happens. generates only 1 line with this comment

Still valid in 4.0.0. I added the fix from @wolthers manually : https://github.com/ivoba/obfuscate-wc/blob/main/src/index.ts
We ran into this at version 4.7 as well.
Yeap this is still an issue
I don't remember if I got to this place by my own mistakes, but I see a few things:
src/index.tsjust saysexport * from './components'- There is no
./src/components/index.ts - Even If I add a
./src/components/index.tswithexport { MyComponent } from './my-component/my-component'it doesn't work. However, if I add a trailing slash to the index export likeexport * 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.
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 https://github.com/peterpeterparker/web-social-share/pull/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/[email protected]/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.
@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:
-
collectionDir: the purpose of this is not clear, and the concept ofcollectionis only mentioned otherwise briefly in the "Publishing A Component Library" Package.json section, and in the Ember Legacy section. -
A
dist-collectionoutput target is mentioned in thetransformAliasedImportPathsInCollectionsection, but that output target isn't documented anywhere else. -
The script tag usage gives the example
<script type="module" src='https://cdn.jsdelivr.net/npm/[email protected]/dist/myname.js'></script>but thedistoutput target doesn't generate a file like that. The example you gave is the only way that works. -
The "Importing the dist library" sections describe the step:
Add an
importwithin the root component:import my-componentBut 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 emptyindexfiles.
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
@mattclough1 thanks for the feedback. I have ingested separate tickets into our team backlog to:
- move the generation of
collectionfiles 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 🙏