Skip to content

bind:this does not work in code outside of the app itself #2937

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

Closed
ArthurClemens opened this issue Jun 2, 2019 · 10 comments
Closed

bind:this does not work in code outside of the app itself #2937

ArthurClemens opened this issue Jun 2, 2019 · 10 comments

Comments

@ArthurClemens
Copy link

bind:this only seems to work when the code is located in the same module as the app code.

This is problematic for library code such as a UI component library.

To demonstrate the problem, I've created a minimal Button component inside a (mini) monorepo.

When using the exact same Button code, the binding only works for the local Svelte module.

These do not work (as in: they do render but without the binding):

import { Button } from "lib-with-bind-this"
import ButtonFromPath from "../../lib-with-bind-this/src/Button.svelte"

This does work:

import LocalButton from "./LocalButton.svelte"

I've created a small demo project that shows the behavior:
https://github.com/ArthurClemens/test-bind-this (instructions provided).

@mrkishi
Copy link
Member

mrkishi commented Jun 2, 2019

This problem is related to the discussion at #2896 (since they closed that one, we can keep track of it here): Svelte components can't properly consume other pre-compiled Svelte components because you end up with multiple, distinct svelte/internal modules that do not share information.

I believe we need to figure out an internal api for Svelte to connect third-party components' internals at instantiation.

In the meanwhile, if these components can share the same build process, consider using the package.json's svelte: property to tell bundlers where to get the components' source from and make Svelte a peerDependency instead.

@ArthurClemens
Copy link
Author

How do I use package.json's svelte: property?

@mrkishi
Copy link
Member

mrkishi commented Jun 3, 2019

Just point it to your package's main source file (be that a .svelte file or a .js exporting multiple components). See https://github.com/rollup/rollup-plugin-svelte/#pkgsvelte.

@ArthurClemens
Copy link
Author

Including svelte in package.json doesn't help my case: the binding still doesn't work.

@mrkishi
Copy link
Member

mrkishi commented Jun 4, 2019

You also need to make svelte a peerDependency, which means removing it from the component's (subpackage) node_modules as well.

@ArthurClemens
Copy link
Author

@ValentinH
Copy link

It seems to be the same issue that I have on #2620, is it?

ArthurClemens added a commit to ArthurClemens/polythene that referenced this issue Jun 10, 2019
@prashantsail
Copy link

prashantsail commented Jun 17, 2019

Hi All,
I am using webpack(4.34.0) to bundle svelte(3.5.1) components.
and I am running into the same issue as well.

As suggested by @mrkishi, my app & components could potentially share the same build process.

So, in my component's package.json

  1. I have added svelte: property
  2. I have also added svelte under peerDependencies

After this when I build my app I run into following error -
... Module not found: Error: Can't resolve 'svelte' in '...<svelte component path> ...'
... Module not found: Error: Can't resolve 'svelte/internal' in '...<svelte component path> ...'

Could any one help me with steps\pointers to fix this.


Also looking at @Conduitry's reply here , does it mean that the issue will be solved only if we use rollup and rollup-plugin-svelte for bundling ?

@prashantsail
Copy link

Update

My team has used webpack's resolve.alias field to solve the problem.

Summarizing my environment(updated) details and the steps that helped us:

Environment

"svelte": "3.6.3",
"svelte-loader": "2.13.3"
"webpack": "4.35.2"
"webpack-cli": "3.3.5"

Steps

  1. In my component's package.json

    • I have added svelte: property (Refer svelte-loader's readme)
    • I have also added svelte under peerDependencies
  2. In my app's webpack.config.js

resolve: {
    mainFields: ['svelte'],
    alias: {
        svelte: path.resolve('node_modules','svelte')
    },
    extensions: ['.mjs', '.js', '.svelte']
},

From what I understood, rollup has a rollup-plugin-node-resolve plugin which has a dedupe config and achieves something similar.
This article helped us understand and come up with the above solution

I am also open to any suggestions\feedback OR a more appropriate way of handling this issue.

@Conduitry
Copy link
Member

@prashantsail Thank you very much for that! The webpack templates now have resolve.alias in their config and the Rollup templates are using the dedupe option to rollup-plugin-node-resolve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants