ckeditor5 icon indicating copy to clipboard operation
ckeditor5 copied to clipboard

Using Vite instead of Webpack

Open lchrennew opened this issue 4 years ago • 57 comments

📝 Provide an introduction on How to build from source using Vite.js instead of Webpack.

_My code, which build editor from source, has been migrated to Vue 3+ and Vite.js, and an introduction on How to config the vite.config.js is nessesary, because the editor not works after migration.


⚠️ EDIT by @Reinmar: We shipped an experimental integration for Vite. Read more in https://github.com/ckeditor/ckeditor5/issues/9807#issuecomment-1363284224 🚀

lchrennew avatar Jun 01 '21 17:06 lchrennew

any feedback?

lchrennew avatar Jun 22 '21 22:06 lchrennew

Any news ? 😃

pierre-H avatar Jul 27 '21 09:07 pierre-H

waiting...

brucewar avatar Aug 05 '21 07:08 brucewar

ping @oleq @Reinmar 😃

pierre-H avatar Aug 05 '21 07:08 pierre-H

waiting...

lchrennew avatar Aug 05 '21 08:08 lchrennew

The current simplest approach: modify and use the build js file image @pierre-H @brucewar

lchrennew avatar Aug 05 '21 08:08 lchrennew

Could you describe your problem in more detail? Please include the steps you have already done and the results that have been produced. Also please share your configuration that allows reproducing the issue on our side.

Vite is a new thing that we have never worked on before so the more details you are able to provide, the easier it will be for us to help you.

pomek avatar Aug 05 '21 11:08 pomek

Could you describe your problem in more detail? Please include the steps you have already done and the results that have been produced. Also please share your configuration that allows reproducing the issue on our side.

Vite is a new thing that we have never worked on before so the more details you are able to provide, the easier it will be for us to help you.

More vue developer starts to use Vite.js to replace heavy weight Vue CLI / Webpack, and the following document doesn't help those using Vite.js. https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html#configuring-vueconfigjs

lchrennew avatar Aug 06 '21 01:08 lchrennew

@pomek I am faced with a similar issue as @lchrennew in a different context: I work with svelte instead of vue but the problem is likely the same:

I use Vite for development builds and rollup for production build. Vite allows instant reloading of changed code, it's really hard to not use it.

Actual problem is:

  • with official installation and use instructions from CKEditor 5, rollup builds a bundle just fine:
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
  • with the same import, Vite cannot produce a valid bundle and I get a fatal error
The requested module '/node_modules/@ckeditor/ckeditor5-build-classic/build/ckeditor.js' does not provide an export named 'default'

I can make sort of work by using:

    import '@ckeditor/ckeditor5-build-classic'
    const ClassicEditor = window['ClassicEditor']

and now this works in vitejs but of course, it breaks the build by rollup.

I spent quite a bit of time on this and could not find an include method that work for both.

In the end, it's about how vitejs handles commonjs files such as the one you produce for the classic editor bundle (and I'll be posting this at ViteJs github as well) but would be great if there was some guidance from you as to how Vitejs should be configured to properly work with CKEditor.

@lchrennew Apologies for hijacking your issue, please let me know if this is not the problem you described (and also if you found a solution!)

Side note: I could have worked around this by building from source but looks like you really need Webpack for that, find how to configure it, etc and I use rollup. But that's another story.

Best regards

weeblr avatar Oct 22 '21 07:10 weeblr

ckeditor5 seems to build fine for me in a pure vite project, with one key exception. I had to add a plugin like below to transform the SVG files properly. It also seems to break in SSR mode, but for me that's not a big deal as I can just exclude it on the server side.

((options) => {
      return {
        name: 'vite-ckeditor-svg-raw-plugin',
        transform(code, id) {
          if (options.fileRegex.test(id)) {
            // eslint-disable-next-line no-param-reassign
            code = fs.readFileSync(id, 'utf8');

            const json = JSON.stringify(code)
              .replace(/\u2028/g, '\\u2028')
              .replace(/\u2029/g, '\\u2029');
            return {
              code: `export default ${json}`,
              map: { mappings: '' },
            };
          }
        },
        generateBundle(_, bundle) {
          for (const [filename, info] of Object.entries(bundle)) {
            if (options.fileRegex.test((info as AssetInfo).name)) {
              delete bundle[filename];
            }
          }
        },
      };
    })({
      fileRegex: /@ckeditor\/.*\.svg/,
    }),

jsmnbom avatar Nov 22 '21 18:11 jsmnbom

I have the same issue The requested module '/node_modules/@ckeditor/ckeditor5-build-classic/build/ckeditor.js' does not provide an export named 'default' using React + Vite

VanjaPopovic avatar Dec 03 '21 14:12 VanjaPopovic

I have a same issue. Please push me when it's resolved.

huydq-itealteam avatar Dec 16 '21 03:12 huydq-itealteam

@jsmnbom I need detail.Please let me see you code.

gap1994 avatar Jan 10 '22 07:01 gap1994

Any update for Vue3 + Vite?

nickkrykunov avatar Jan 20 '22 18:01 nickkrykunov

I'm joining the "please update me" list.

yarduza avatar Feb 17 '22 20:02 yarduza

I have the same issue with a react project using vite. this is related to this issue as well - https://github.com/ckeditor/ckeditor5/issues/2178

EllipticElysium avatar Mar 07 '22 14:03 EllipticElysium

after a little bit of googling, i found this package which has worked for me https://www.npmjs.com/package/@originjs/vite-plugin-commonjs

keep the exact same configs you would when using webpack, but add this package and it seems to handle the issues with commonjs

EllipticElysium avatar Mar 07 '22 15:03 EllipticElysium

Hello,I have the same issue,it have resolved??

bigsnowballhehe avatar Apr 15 '22 09:04 bigsnowballhehe

I am also looking forward to a guide on using Vite instead of Webpack. In my case I was planning to implement it to a SvelteKit app, however I decided to use another rich content text editor which integrated nicely. (Tiptap)

Still I'll remain subscribed to this thread, looking forward to a find a solution

Adriman2 avatar Apr 19 '22 08:04 Adriman2

Hi folks! any new on thiw subject? i'm also struggling with this. Many thanks

fede-2110 avatar Apr 25 '22 14:04 fede-2110

We would love to see this issue resolved with our React app - trying to switch from Webpack to Vite.

chrismyer avatar May 03 '22 17:05 chrismyer

I ran into the same problem on Vue2 when trying to build ckeditor5 from source. SVG turned out to be connected based on the above, but styles did not.

Barsick132 avatar May 12 '22 09:05 Barsick132

This still remains a problem even today, I am trying to build ckEditor from source using vite, but the docs only have the old vue-cli/webpack settings. Has anyone managed to build and use from source with vite?

adelapazborrero avatar Aug 10 '22 08:08 adelapazborrero

Same issue for me

crisjohn02 avatar Aug 23 '22 08:08 crisjohn02

Hi CKEditor team & community, I'm moving a Vue2 app from Vue-CLI/webpack to Vite, and I'm also having a hard time finding a proper way to configure CKeditor with it, this is the only thing preventing us to complete the migration. With Vite getting more and more popular, and being the new default build tool for Vue, that would be very useful to have a CKEditor plugin or at least a doc explaining how to integrate it.

mfillon avatar Aug 24 '22 12:08 mfillon

I figured out how to use CKEditor 5 in a Vite application. It's not perfect but it works.

I've used https://ckeditor.com/ckeditor-5/online-builder/, put the result in a new (private) repo, ran yarn build and created a release. Then I installed this package in the main app using Github URL. I've added a wrapper component which connects @ckeditor/ckeditor5-vue2 and our editor build. Here is a simplified version without loading state, etc:

<template>
	<ckeditor-vue
		:config="config"
		:editor="editor"
		:value="value"
		@input="$emit('input', $event)"
	/>
</template>

<script lang="ts">
import CKEditorVue from '@ckeditor/ckeditor5-vue2';

export default {
	name: 'CkEditor',
	components: {
		ckeditorVue: CKEditorVue.component,
	},
	props: {
		value: {
			type: String,
			default: '',
		},
	},
	data() {
		return {
			editor: null,
		};
	},
	computed: {
		config() {
			return {
				...
			};
		},
	},
	async mounted() {
		const { default: Editor } = await import('ckeditor5-bethink');
		this.editor = Editor;
	},
};
</script>

The main downside is that whenever we need to add or configure a plugin, we have to run the build again and create a new release. It's better than being blocked from using Vite, though 🙂

rogatty avatar Aug 24 '22 19:08 rogatty

I use custom ckeditor build from https://ckeditor.com/ckeditor-5/online-builder/ and i faced with this issue for React.

In my cause its:

"react": "18.2.0", "vite": "2.9.10",

Here is solution what i found:

package.json

"ckeditor5-custom-build": "file:libs/ckeditor5",

vite.config.ts

export default defineConfig(() => {
  return {
    plugins: [react()],
    optimizeDeps: {
      include: ['ckeditor5-custom-build'],
    },
    build: {
      commonjsOptions: { exclude: ['ckeditor5-custom-build'], include: [] },
    },
  };
});

RichTextEditor.tsx

import { CKEditor, CKEditorProps } from '@ckeditor/ckeditor5-react';
import Editor from 'ckeditor5-custom-build';

export function RichTextEditor({
  defaultValue,
  ...props
}: RichTextEditorProps) {
  return (
    <EditorContainer>
      <CKEditor editor={Editor} data={defaultValue || ''} {...props} />
    </EditorContainer>
  );
}

INQTR avatar Aug 25 '22 08:08 INQTR

I got my custom build from source vue3-vite setup working with the help of @jsmnbom's plugin and ckeditor5-dev-utils.

Start with installing your dependencies... ckeditor5-vue, plugins, and theme then add CKEditor to your main.js

// raw-loader plugin ckeditor-util.js

const fs = require('fs');
const fileRegex = /@ckeditor\/.*\.svg/;
export default () => {
  return {
    name: 'vite-ckeditor-svg-raw-plugin',
    transform(code, id) {
      if (fileRegex.test(id)) {
        // eslint-disable-next-line no-param-reassign
        code = fs.readFileSync(id, 'utf8');
        const json = JSON.stringify(code)
          .replace(/\u2028/g, '\\u2028')
          .replace(/\u2029/g, '\\u2029');
        return {
          code: `export default ${json}`,
          map: { mappings: '' },
        };
      }
    },
    generateBundle(_, bundle) {
      for (const [filename, info] of Object.entries(bundle)) {
        if (fileRegex.test(info.name)) {
          delete bundle[filename];
        }
      }
    },
  };
};

vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ckeditorUtil from './src/plugins/ckeditor-util'
const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
...
export default defineConfig({
  plugins: [
    vue(),
    ckeditorUtil(),
  ],
  css: {
    postcss: {
      plugins: [
        styles.getPostCssConfig( {
          themeImporter: {
            themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ),
          },
          minify: true
        } )
      ],
    },
  },
  optimizeDeps: {
    include: [
      // 
      '@ckeditor/ckeditor5-vue',
      ...
    ],
  },
...
})

MyComponent.vue

<template>
  <div class="document-container">
    <ckeditor
      :editor="editor"
      v-model="editorData"
      :config="editorConfig"
      @ready="onReady"
    >
    </ckeditor>
  </div>
</template>

<script setup>
  import DecoupledEditor from '@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor';
  import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
  import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
  ...
  import { ref } from 'vue';

  const editor = DecoupledEditor;
  const editorConfig = {
    plugins: [
      Alignment,
      Autoformat,
      ...
    ],
    toolbar: {
      items: [
        'heading',
        '|',
        'fontSize',
        'fontFamily',
         ...
       ],
       ...
     },
   };
   // manually add the toolbar
   const onReady = (editor) => {
    // Insert the toolbar before the editable area.
    editor.ui.getEditableElement().parentElement.insertBefore(
      editor.ui.view.toolbar.element,
      editor.ui.getEditableElement()
    );
  };
 const editorData = ref('WORKS');
</script>
<style>
  // editor styles here
</style>

Styling the editor

I didn't use the CKEditorWebpackPlugin because I won't be doing localization for now, but I think you just have to add it as a plugin in vite.config.js

export default defineConfig({
  plugins: [
    vue(),
    // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin
    vuetify({
      autoImport: true,
    }),
    ckeditorUtil(),
    new CKEditorWebpackPlugin( {
      // See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
      language: 'en',

      // Append translations to the file matching the `app` name.
      translationsOutputFile: /app/
    } )
  ],
  ...
})

I hope this can help. And please feel free to correct me if I did something wrong.

chaigrb avatar Sep 08 '22 23:09 chaigrb

I add working custom build ckeditor to quasar (vite). Ugly but works: Any feedback is nice.

in boot file register ckeditor tag in app

import CKEditor from '@ckeditor/ckeditor5-vue';
import {boot} from 'quasar/wrappers'

export default boot(async ({app, router, store}) => {
  app.use(CKEditor).mount('ckeditor')
})

Add app in custom component. Since js build assign to window, I dynamic add src it. To not load component if its not available <ckeditor v-if="editorForCK" v-model="editorData" :editor="editorForCK" :config="editorConfig"/>

const editorData = ref('')
const editorConfig = ref({})
const editorForCK = ref(null)
onMounted(() => {
  const plugin = document.createElement("script");
  plugin.setAttribute(
    "src",
    "/js/ckeditor.js"
  );
  plugin.defer = true;
  document.head.appendChild(plugin);
  console.log('on mounted')
  const interval = setInterval(()=>{
    if(window.ClassicEditor){
      editorForCK.value = window.ClassicEditor
      clearInterval(interval)
    }
  },500)
})

felek000 avatar Sep 09 '22 09:09 felek000

Thanks for your suggestion @chaigrb . It works, though for the postcss config, it uses @ckeditor/ckeditor5-dev-utils, which has a peer dependency on webpack, even though the part used for postcss config doesn't seem to depend on it. It would be great to not have any webpack dependency.

mfillon avatar Nov 03 '22 09:11 mfillon