andrewjk / tiptap-svelte

A port of tiptap (a renderless rich-text editor for Vue) to Svelte
31 stars 4 forks source link

RangeError: Adding different instances of a keyed plugin (plugin$1) #2

Open zwz opened 4 years ago

zwz commented 4 years ago

I created my editor based on the svelte template . I copied the content of tiptap-svelte-example/src/route/read-only/index.svelte (and modified the paths for the import) to the App.svelte.

MyEditor.zip To simplify the reproduce-process, just download the attachment and extract it into this repo directory (make MyEditor a sibling to tiptap-svelte-examples)

After npm install && npm run dev, you will see this error in your browser console.

andrewjk commented 4 years ago

I think that's caused by multiple versions of prosemirror libraries being imported.

When using Webpack to build you can set aliases to fix this problem:

const alias = {
    svelte: path.resolve('node_modules', 'svelte'),
    'prosemirror-model': path.resolve('node_modules', 'prosemirror-model'),
    'prosemirror-state': path.resolve('node_modules', 'prosemirror-state'),
    'prosemirror-tables': path.resolve('node_modules', 'prosemirror-tables')
}

But I haven't had any luck fixing this when using Rollup (which is what the default svelte template uses).

To get around this for the time being you may have to use the Svelte Webpack template and set up aliases as above.

If you really want to use Rollup you can hack around this problem by renaming all plugins in Editor.js, starting around line 198:

plugins: [
    ...
].map((plugin, index) => {
    if (plugin.key.startsWith('plugin')) {
        plugin.key = 'plugin' + index;
    }
    return plugin;
}),
zwz commented 4 years ago

Well, I definitely want it to work with Rollup without hacking around the source code.

But I did not install multiple version of prosemirror. As you can see in MyEditor package.json, there is no prosemirror-* stuff.

I also tried soft-linking everything in node_modules to MyEditor's, but it does not help either.

zwz commented 4 years ago

I added console.log(this.plugins) at line 195 in Editor.js, and found out the Link extension introduces a plugin plugin$1. So I comment out the Link extension in App.svelte. But it then reports another RangeError (with name plugin$).

Then I added another console.log at line 196 in Editor.js to show the content the plugins option for the EditorState creation. It shows as

0: Plugin {props: {…}, spec: {…}, key: "plugin$8"}
1: Plugin$2 {props: {…}, spec: {…}, key: "plugin$"}
2: Plugin$2 {props: {…}, spec: {…}, key: "plugin$1"}
3: Plugin$2 {props: {…}, spec: {…}, key: "plugin$2"}
4: Plugin$2 {props: {…}, spec: {…}, key: "plugin$3"}
5: Plugin {props: {…}, spec: {…}, key: "plugin$"}
6: Plugin {props: {…}, spec: {…}, key: "plugin$1"}
7: Plugin {props: {…}, spec: {…}, key: "plugin$2"}
8: Plugin {props: {…}, spec: {…}, key: "plugin$3"}
9: Plugin {props: {…}, spec: {…}, key: "plugin$4"}
10: Plugin {props: {…}, spec: {…}, key: "plugin$5"}
11: Plugin {props: {…}, spec: {…}, key: "plugin$6"}
12: Plugin {props: {…}, spec: {…}, key: "plugin$7"}
13: Plugin {props: {…}, spec: {…}, key: "plugin$9"}
14: Plugin {props: {…}, spec: {…}, key: "plugin$10"}
15: Plugin {props: {…}, spec: {…}, key: "plugin$11"}
16: Plugin {props: {…}, spec: {…}, key: "plugin$12"}
17: Plugin {props: {…}, spec: {…}, key: "editable$"}
18: Plugin {props: {…}, spec: {…}, key: "plugin$13"}
19: Plugin {props: {…}, spec: {…}, key: "plugin$14"}

It seems that 1-4 have duplicated key to 5-8. But 1-4 have props: {transformPasted: ƒ} while 5-8 have props: {handleKeyDown: ƒ}.

BTW, if I comment out all the extensions in App.svelte, the error goes away.

andrewjk commented 4 years ago

It's not due to anything you've installed, it's something to do with the way Svelte/Rollup pulls in dependencies (including the prosemirror libraries which are used in tiptap-svelte, tiptap-svelte-extensions etc).

It looks like you can get things to work by adding the prosemirror libraries as devDependencies to your editor project:

yarn add -D prosemirror-history prosemirror-model prosemirror-state prosemirror-tables prosemirror-transform prosemirror-utils prosemirror-view

And then changing the dedupe option in rollup.config.js to look like this:

dedupe: importee =>
    importee === 'svelte' ||
    importee.startsWith('svelte/') ||
    importee === 'prosemirror-history' ||
    importee === 'prosemirror-model' ||
    importee === 'prosemirror-state' ||
    importee === 'prosemirror-tables' ||
    importee === 'prosemirror-transform' ||
    importee === 'prosemirror-utils' ||
    importee === 'prosemirror-view'

I'm not sure whether this is a great way to do things but it seems to work.

zwz commented 4 years ago

Well, I guess I got you. Thank you for your explanation.