ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.52k stars 782 forks source link

bug: can't get experimentalImportInjection to work with vite #3407

Closed janniks closed 2 years ago

janniks commented 2 years ago

Prerequisites

Stencil Version

2.16.1

Current Behavior

Dynamic import failure on vite/rollup still persists.

Expected Behavior

Rebuilding with latest experimentalImportInjection should solve dynamic import failure on vite/rollup.

Steps to Reproduce

OR


Background

We have a fairly stock vue+vite sample projects in: https://github.com/hirosystems/create-stacks/tree/main/templates/template-vue → used for codesandbox

The stencil component was updated to experimentalImportInjection under 2.16.1. The component was rebuilt and released via npm as @stacks/connect-ui@5.0.6-alpha.6be82fd.0.


CC @rwaskiewicz https://github.com/ionic-team/stencil/issues/2827#issuecomment-1142399806

Code Reproduction URL

https://codesandbox.io/s/priceless-mcclintock-2x9n30

Additional Information

Is it possible to fix this issue with the @rollup/plugin-dynamic-import-vars plugin? If so how?

I've tried similar things to the following:

dynamicImportVars({
  include: "./node_modules/@stacks/connect-ui/dist/connect-ui/*",
}),

Where connect-ui is a stencil component via plain dist, but used via another dependency (connect).

janniks commented 2 years ago

@rwaskiewicz do you think there's an easy way to fix this? Otherwise it might make more sense to use dist-custom-elements and manually chunk in the vite config itself. 🤔

rwaskiewicz commented 2 years ago

@janniks

I took a look at the reproduction case and can confirm that the dynamic import is failing. Looking at create-stacks/templates/template-vue/node_modules/.vite/deps/@stacks_connect.js, it looks like Vite is currently caching a version of @stacks/connect that is not dynamically importing components. I'm able to discern this based on the following line in the file:

/*!__STENCIL_STATIC_IMPORT_SWITCH__*/

which should be replaced with the import statements for your components. I believe this is part of the root cause - although I'm not sure how @stacks/connect is generated/built, which makes it a little tricky to proceed here. Off the top of my head, I can see a few possibilities:

  1. The configuration for dynamically importing components isn't set for @stacks/connect in stencil.config.ts
  2. The configuration for dynamically importing components isn't being set correctly internally within Stencil
  3. Vite is caching an older version of Stencil, which is causing the dynamic imports to not be generated correctly.

Can you do me a favor and validate that experimentalimportinjection is set on @stacks/connect? Can you provide a reproduction case/branch that points me to how it's configured after that? I have a sneaky suspicion that it's the third option there, but wanna rule out the first two options first.

janniks commented 2 years ago

Thanks for the detailed response! 🙏

  1. I fixed the __STENCIL_STATIC_IMPORT_SWITCH__ / experimentalImportInjection not working. → released under @stacks/connect@5.0.6-alpha.a346466.0 via this pr; now I can't find the placeholder string anymore and assume it should work
  2. Added a branch to create-stacks as new reproduction: https://github.com/hirosystems/create-stacks/tree/reproduce-stencil-experimental-import


⚡️ Codesandbox of the reproduction: https://codesandbox.io/s/github/hirosystems/create-stacks/tree/reproduce-stencil-experimental-import/templates/template-vue

janniks commented 2 years ago

The @stacks/connect dependency itself loads the stencil component like this from the actual stencil component dependency @stacks/connect-ui. Does that make a difference / Could that be a problem? 😬

rwaskiewicz commented 2 years ago

The @stacks/connect dependency itself loads the stencil component like this from the actual stencil component dependency @stacks/connect-ui. Does that make a difference / Could that be a problem? 😬

Potentially, it depends what that defineCustomElements function you link to is defined/what it's doing. It's not immediately clear to me if that's a Stencil generated loader package or something else 🤔

janniks commented 2 years ago

Thanks, I'm not sure -- But yes, that's all stencil generated. Same method as used here in stencil docs, and here.

Is there a better method of loading for use in another library?

janniks commented 2 years ago

I updated to stencil core 2.17 (here) but it still doesn't work. The way we import is the same as most stencil examples / ionic use-cases. The loader is set up in the same way ionic core is.

EDIT: Works 🚀