How to convert webpack configuration from a vue.config.js to quasar.conf.js (CKEditor-vue docs)



  • Apologies for a slightly long post. To be quite honest I’m totally over my head here.

    I have been spoiled by frameworks like Quasar into never needing to learn how webpack works/is set up - until now:

    I am trying to add CKEditor to my project, a WYSIWYG that supports Vue, but unfortunately it requires you to configure/chain webpack through vue.config.js (The docs assume that you have built your project using the Vue CLI). I understand vaguely that quasar is performing a lot of what vue.config does under the hood, but I don’t know enough about Webpack to debug my efforts or know if I’m on the right track.

    Assuming that this is even possible, I am attempting to convert the vue.config.js instructions that they provide in their docs to something that meshes with quasar.conf

    Here is their config:

    module.exports = {
    	// The source of CKEditor is encapsulated in ES6 modules. By default, the code
    	// from the node_modules directory is not transpiled, so you must explicitly tell
    	// the CLI tools to transpile JavaScript files in all ckeditor5-* modules.
    	transpileDependencies: [
    		/ckeditor5-[^/\]+[/\]src[/\].+\.js$/,
    	],
    
    	configureWebpack: {
    		plugins: [
    			// CKEditor needs its own plugin to be built using webpack.
    			new CKEditorWebpackPlugin( {
    				// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
    				language: 'en'
    			} )
    		]
    	},
    
    	css: {
    		loaderOptions: {
    			// Various modules in the CKEditor source code import .css files.
    			// These files must be transpiled using PostCSS in order to load properly.
    			postcss: styles.getPostCssConfig( {
    				themeImporter: {
    					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
    				},
    				minify: true
    			} )
    		}
    	},
    
    	chainWebpack: config => {
    		// Vue CLI would normally use its own loader to load .svg files. The icons used by
    		// CKEditor should be loaded using raw-loader instead.
    
    		// Get the default rule for *.svg files.
    		const svgRule = config.module.rule( 'svg' );
    
    		// Then you can either:
    		//
    		// * clear all loaders for existing 'svg' rule:
    		//
    		//		svgRule.uses.clear();
    		//
    		// * or exclude ckeditor directory from node_modules:
    		svgRule.exclude.add( __dirname + '/node_modules/@ckeditor' );
    
    		// Add an entry for *.svg files belonging to CKEditor. You can either:
    		//
    		// * modify the existing 'svg' rule:
    		//
    		//		svgRule.use( 'raw-loader' ).loader( 'raw-loader' );
    		//
    		// * or add a new one:
    		config.module
    			.rule( 'cke-svg' )
    			.test( /ckeditor5-[^/\]+[/\]theme[/\]icons[/\][^/\]+\.svg$/ )
    			.use( 'raw-loader' )
    			.loader( 'raw-loader' );
    	}
    };
    

    Here is what I have so far in quasar.conf:

    build: {
          scopeHoisting: true,
          vueRouterMode: "hash", // available values: 'hash', 'history'
          showProgress: true,
          gzip: false,
          analyze: false,
          transpile: true,
          transpileDependencies: [
            /ckeditor5-[^/\]+[/\]src[/\].+\.js$/,
          ],
          // Options below are automatically set depending on the env, set them if you want to override
          // preloadChunks: false,
          extractCSS: true,
          // https://quasar.dev/quasar-cli/cli-documentation/handling-webpack
          extendWebpack(cfg) { 
            cfg.plugins.push(new CKEditorWebpackPlugin( {
                // The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
                language: 'en'
            } ))
          },
    
          chainWebpack(chain, { isServer, isClient }) {
            const svgRule = chain.module.rule( 'svg' );
            svgRule.exclude.add( __dirname + '/node_modules/@ckeditor' );
            chain.module
            .rule( 'cke-svg' )
            .test( /ckeditor5-[^/\]+[/\]theme[/\]icons[/\][^/\]+\.svg$/ )
            .use( 'raw-loader' )
            .loader( 'raw-loader' );
          }
        },
    

    The missing piece:

    css: {
    		loaderOptions: {
    			// Various modules in the CKEditor source code import .css files.
    			// These files must be transpiled using PostCSS in order to load properly.
    			postcss: styles.getPostCssConfig( {
    				themeImporter: {
    					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
    				},
    				minify: true
    			} )
    		}
    	}
    

    From reading the docs, it seems like maybe Quasar handles this through .postcssrc.js, although I have no idea how to structure that file.
    In general, does it look like I’m on the right track? Any ideas about how to handle that CSS section?
    The error I’m getting atm when rendering the component ‘Cannot read property ‘getAttribute’ of null’ appears to be related to how SVG is being loaded through webpack, but of course out of context this probably doesn’t mean too much, and the stack trace isn’t too helpful when the issue is with webpack.

    And if anyone out there has any experience working with CKEditor + Quasar I’d love to hear about it. Still evaluating if it’s worth the effort.



  • @dmoylan

    In the thread on ckeditor github( you posted there too):
    https://github.com/ckeditor/ckeditor5/issues/6389

    ‘ajmas’ mentioned in his post that CK Editor 4 does work. In the same post he updated he later says that he got ckeditor 5 working.

    btw did you see this doc for Ckeditor install:
    https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs.html#quick-start



  • @dobbel Yes I did see that - ajmas was referring to a pre-built configuration. That works just fine, assuming you want a vanilla WYSIWYG editor. However I am only interested in CKEditor because of a particular track-changes plugin they have (not available in CKEditor 4). Adding plugins requires that you build from source and configure webpack.

    I am pretty well acquainted with their documentation at this point, from wasting a day or so trying to get this running. Will probably move on to evaluating other options unless someone has an idea of how quasar.conf might be fiddling with the webpack configuration that CKEditor wants.



  • @dmoylan

    Would be a shame if it’s not resolved. Being able to use ckeditor would be a great addition to Quasar. I am sure that some of the Quasar experts know how to fix this. Maybe you could ask on the Discord channel or PR them.



  • @qyloxe

    Hi, I was wondering if you as an webpack expert, would be willing to you take another peek at this integrate CKEditor5 with Quasar. I have the feeling they’ve almost solved it but are missing the css config part in webpack.( see opening post)

    I think it would be a nice perk for Quasar to be able to use CKEditor.



  • @dobbel sorry, I don’t like ckeditor - it’s not open source. I do prefer quasar-tiptap:
    https://github.com/donotebase/quasar-tiptap



  • For anyone that happens to stumble upon this…I was able to get CKEditor working in Quasar by building their editor from source according to their documentation and then exporting it as my own NPM package. This article is a pretty good starting point. (It doesn’t tell you anything you can’t eventually find in their documentation, but it will definitely save you time because of how convoluted things are).
    Repo/docs for vue component

    You can then npm install the package you created, as well as the @ckeditor/ckeditor5-vue package, and then import both modules into your component and configure it from there.

    Basically the mistake I was making was attempting to combine their source into the code of my own project - this is technically be possible (but dumb) for someone who understands how quasar.conf is exposing webpack’s config.

    import CustomEditor from '@my_npm_user/my_package_name/build/ckeditor.js'
    import CKEditor from '@ckeditor/ckeditor5-vue';
    
    export default {
        data() {
            return {
                editor: CustomEditor, //The editor built from source: ckeditor5-vue is just a superficial wrapper of this element.
                editorData: '<p>Content of the editor.</p>',
                editorConfig: {
                    // The configuration of the editor.
                }
            }
        }
    }
    

    And in defence of CKEditor: I believe it is in fact mostly open-source, (not to get into the nitty-gritty about open source, but they do employ the term pretty often on their site) and I believe the licensing is only limited when using some of their “premium” features, such as collaboration. The licensing is fairly permissive for small companies or individuals using the standard features.

    You will find that this is the case pretty much across the board for editors with quality collaboration software, which I can’t fault anyone for: I know from my own failures just how much hard work and skill must go in to these features.

    Oh and thanks @dobbel for trying to enlist some help in this, you’ve been an awesome forum-citizen here and elsewhere I’ve seen.


Log in to reply