taco
taco
DDeno
Created by taco on 2/27/2025 in #help
Vite + Codemirror in SvelteKit 4 broken due to @codemirror/state being loaded twice
4 replies
DDeno
Created by taco on 2/27/2025 in #help
Vite + Codemirror in SvelteKit 4 broken due to @codemirror/state being loaded twice
You can reproduce this by setting up the basic codemirror editor within a +page.svelte. This page is a stripped-down version of what I have.
<script>
import { onMount } from 'svelte';

import { json } from '@codemirror/lang-json';
import { editorFromTextarea } from '$lib/codemirror';
import { EditorView, basicSetup } from 'codemirror';

/**
* @function editorFromTextarea
* @param {HTMLTextAreaElement} field
* @param {Array<import('@codemirror/state').Extension>} extensions
* @returns {import('@codemirror/view').EditorView}
*/
export const editorFromTextarea = (field, ...extensions) => {
if (!field.parentNode) {
throw new Error('Parent node missing');
}
const view = new EditorView({
extensions: [basicSetup, ...extensions],
doc: field.value,
});

field.parentNode.insertBefore(view.dom, field);
field.style.display = 'none';
if (field.form) {
field.form.addEventListener('submit', () => {
field.value = view.state.doc.toString();
});
}
return view;
};
/** @type {HTMLTextAreaElement} */
let textareaElement;

onMount(() => {
const textareaView = editorFromTextarea(
textareaElement,
json(),
EditorView.updateListener.of((view) => {
if (view.docChanged) {
try {
console.log(view.state.doc.toString());
} catch {}
}
}),
);
}
</script>
<textarea bind:this={textareaElement} id="textareaElement" name="textareaElement" value="Text Content"></textarea>
<script>
import { onMount } from 'svelte';

import { json } from '@codemirror/lang-json';
import { editorFromTextarea } from '$lib/codemirror';
import { EditorView, basicSetup } from 'codemirror';

/**
* @function editorFromTextarea
* @param {HTMLTextAreaElement} field
* @param {Array<import('@codemirror/state').Extension>} extensions
* @returns {import('@codemirror/view').EditorView}
*/
export const editorFromTextarea = (field, ...extensions) => {
if (!field.parentNode) {
throw new Error('Parent node missing');
}
const view = new EditorView({
extensions: [basicSetup, ...extensions],
doc: field.value,
});

field.parentNode.insertBefore(view.dom, field);
field.style.display = 'none';
if (field.form) {
field.form.addEventListener('submit', () => {
field.value = view.state.doc.toString();
});
}
return view;
};
/** @type {HTMLTextAreaElement} */
let textareaElement;

onMount(() => {
const textareaView = editorFromTextarea(
textareaElement,
json(),
EditorView.updateListener.of((view) => {
if (view.docChanged) {
try {
console.log(view.state.doc.toString());
} catch {}
}
}),
);
}
</script>
<textarea bind:this={textareaElement} id="textareaElement" name="textareaElement" value="Text Content"></textarea>
4 replies