Skip to content
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

SSR fails #71

Closed
avagru opened this issue Jun 10, 2019 · 14 comments
Closed

SSR fails #71

avagru opened this issue Jun 10, 2019 · 14 comments
Labels
pending:feedback This issue is blocked by necessary feedback.

Comments

@avagru
Copy link

avagru commented Jun 10, 2019

I tried ssr rendering via npm run build but I fails.
My project was a custom ckeditor building from source.
Below are error logs.

Application is running on http://localhost:8089
error during render : /projects/OidiBDAGosxZiX6x3KSs/notebook/s6P7Shghqj0KaGmenZPe
..../node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditor.js:10
import Editor from '@ckeditor/ckeditor5-core/src/editor/editor';
       ^^^^^^
SyntaxError: Unexpected identifier
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
@Mgsy
Copy link
Member

Mgsy commented Jun 11, 2019

Hello, can you provide exact steps to reproduce, so we'll be able to investigate the issue? Code samples also will be appreciated.

@Mgsy Mgsy added the pending:feedback This issue is blocked by necessary feedback. label Jun 11, 2019
@avagru
Copy link
Author

avagru commented Jun 15, 2019

import {Component, Prop, Vue} from 'vue-property-decorator';
import FileList from "@/components/notes/FileList.vue";
import _ from 'lodash';
import Tags from "@/components/notes/Tags.vue";
import {Note} from "@/swagger";
import FileUpload from "vue-upload-component";

import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';
import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import BlockquotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';    
import TablePlugin from '@ckeditor/ckeditor5-table/src/table';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';

import CKFinder from '../../utils/ckeditor5-ckfinder/src/ckfinder';
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';    

@Component({
    components: {Tags, FileList}
})
export default class NoteEditor extends Vue {

    @Prop({})
    private noteIndex: number;
    private isLoading: boolean = false;
    private noteCopy: Note = null;
    private editMode = false;

    private spinner = false;
    showDropTarget = false;
    private editor = null;
    private editorConfig = {
        plugins: [ 
            EssentialsPlugin,
            BoldPlugin,
            HeadingPlugin,
            ItalicPlugin,
            LinkPlugin,
            ParagraphPlugin,
            BlockquotePlugin,
            TablePlugin,
            TableToolbar,
            MediaEmbed,
            CKFinder,
            Image, 
            ImageUpload, 
            ImageToolbar, 
            ImageCaption, 
            ImageStyle 
        ],
        toolbar: {
            items: [
                'heading', 
                '|',
                'bold',
                'italic',
                'link',
                'bulletedList',
                'numberedList', 
                'imageUpload',
                'blockQuote',
                'insertTable',
                'mediaEmbed',
                'undo',
                'redo',
            ]
        },
        heading: {
            options: [
                { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
                { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
                { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
                { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' }
            ]
        },
        table: {
            contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
        },
        ckfinder: {
            uploadUrl: 'https://content.dropboxapi.com/2/files/upload',
            headerToken: {},
            notebook: "",
            noteNumber: 0,
            apiPath: "",
        },
        image: {
            toolbar: [ 'imageTextAlternative', '|', 'ImageStyle:full', 'ImageStyle:side' ]
        }
    };
    private componentLoader;


    async created() {
        this.editor = ClassicEditor;
        // this.editor = require("@ckeditor/ckeditor5-build-classic");
        if (!this.note.id) {
            this.editMode = true; // no need to take a copy
        }
        let userInfo = await this.$firebase.auth()
        let user: firebase.User = userInfo.currentUser;
        this.editorConfig.ckfinder.headerToken = await user.getIdTokenResult();
        this.editorConfig.ckfinder.uploadUrl = "https://content.dropboxapi.com/2/files/upload";
        this.editorConfig.ckfinder.notebook = this.$route.params['notebook'];
        this.editorConfig.ckfinder.noteNumber = this.note.number;
        this.editorConfig.ckfinder.apiPath =  this.$apiPath;
    }

.....

@avagru
Copy link
Author

avagru commented Jun 15, 2019

Hello, Thank you for your reply.. This is my latest trying.

@jodator
Copy link

jodator commented Jun 17, 2019

@Star0422 are you trying to render the editor on server and return it to the browser? As such I think that this will not work as the editor must be instantiated on the browser. If it is not a case please explain more clearly what you try to achieve? What framework are you using. Also some details on environment setup (node version, browser, etc) might be also helpful.

@oleq
Copy link
Member

oleq commented Jun 18, 2019

Could be a duplicate of ckeditor/ckeditor5#1511.

Also, what does the webpack config look like? Are the CKE5 dependencies transpiled?

@avagru
Copy link
Author

avagru commented Jun 22, 2019

I am trying to render the editor on server. In webpack, "npm run dev" run well. But "npm start" still fails. Node and npm are latest version. The web app is based on Vuejs. So I tried the vue app with builder from source.

@avagru
Copy link
Author

avagru commented Jun 22, 2019

This is package.json
{
"scripts": {
"dev": "webpack-serve --config=./build/webpack.dev.js",
"build": "webpack --config=./build/webpack.prod.js --hide-modules --progress",
"start": "node server"
},
"dependencies": {
"@ckeditor/ckeditor5-autoformat": "^11.0.1",
"@ckeditor/ckeditor5-basic-styles": "^11.1.0",
"@ckeditor/ckeditor5-block-quote": "^11.0.1",
"@ckeditor/ckeditor5-build-classic": "^11.2.0",
"@ckeditor/ckeditor5-ckfinder": "^11.0.1",
"@ckeditor/ckeditor5-dev-utils": "^12.0.1",
"@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.1",
"@ckeditor/ckeditor5-editor-classic": "^12.1.0",
"@ckeditor/ckeditor5-essentials": "^11.0.1",
"@ckeditor/ckeditor5-heading": "^11.0.1",
"@ckeditor/ckeditor5-image": "^13.0.1",
"@ckeditor/ckeditor5-link": "^11.0.1",
"@ckeditor/ckeditor5-list": "^12.0.1",
"@ckeditor/ckeditor5-media-embed": "^11.1.0",
"@ckeditor/ckeditor5-paragraph": "^11.0.1",
"@ckeditor/ckeditor5-table": "^12.0.1",
"@ckeditor/ckeditor5-theme-lark": "^13.0.1",
"@ckeditor/ckeditor5-vue": "^1.0.0-beta.1",
"bootstrap-vue": "^2.0.0-rc.13",
"express": "^4.16.3",
"firebase": "^5.7.3",
"install": "^0.12.2",
"lodash": "^4.17.10",
"lodash.clonedeep": "^4.5.0",
"moment": "^2.24.0",
"npm": "^6.9.0",
"portable-fetch": "^3.0.0",
"raw-loader": "^2.0.0",
"vue": "^2.5.16",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1",
"vue-server-renderer": "^2.5.16",
"vue-upload-component": "^2.8.19",
"vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"@types/lodash.clonedeep": "^4.5.5",
"@types/node": "^11.11.3",
"autoprefixer": "^9.4.5",
"connect-history-api-fallback": "^1.5.0",
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"glob-all": "^3.1.0",
"html-webpack-plugin": "^3.2.0",
"html-webpack-template": "^6.2.0",
"koa-connect": "^2.0.1",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss": "^7.0.13",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^3.0.0",
"purgecss-webpack-plugin": "^1.4.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"ts-loader": "^5.3.3",
"tsconfig-paths-webpack-plugin": "^3.0.4",
"typescript": "^3.2.2",
"vue-loader": "^15.0.10",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.8.3",
"webpack-cli": "^3.2.1",
"webpack-merge": "^4.1.2",
"webpack-node-externals": "^1.7.2",
"webpack-serve": "^2.0.3",
"webpackbar": "^3.1.5"
}
}

@farin
Copy link

farin commented Sep 27, 2019

Trying to use CKEditor-vue in Nuxt app with enabled SSR.

window is not defined

node_modules/@ckeditor/ckeditor5-vue/dist/ckeditor.js

internal/modules/cjs/loader.js:799:30
Module._compile
internal/modules/cjs/loader.js:810:10
Module._extensions..js
internal/modules/cjs/loader.js:666:32
Module.load
internal/modules/cjs/loader.js:606:12
tryModuleLoad
internal/modules/cjs/loader.js:598:3
Module._load
internal/modules/cjs/loader.js:705:19
Module.require
internal/modules/cjs/helpers.js:14:16
require
webpack:/external "@ckeditor/ckeditor5-vue":1:
Object.@ckeditor/ckeditor5-vue
webpack/bootstrap:25:
__webpack_require__

@farin
Copy link

farin commented Sep 27, 2019

unfortunatelly CKEditor module can't be even imported on server side, which makes impossible to make any workaroud except patching/rebuilding module itself

UPDATE: ok there is one easy workaround for Nuxt. Registering ckeditor component and importing all stuff just from plugin with ssr: false option (or registering there own component whichs importing CKEditor locally) Then on server side will be just empty div hydrated on client side with real editor.

@ThibaultVlacich
Copy link

UPDATE: ok there is one easy workaround for Nuxt. Registering ckeditor component and importing all stuff just from plugin with ssr: false option (or registering there own component whichs importing CKEditor locally) Then on server side will be just empty div hydrated on client side with real editor.

Can you be more specific? It's working indeed for the import of the CKEditor component, but I still have an issue when importing the editor itself in my component.

import ClassicEditor from '@ckeditor/ckeditor5-build-classic' raises an error:

ReferenceError
window is not defined

And since it's not possible for whatever reason to define the editors globally because of #9...

@farin
Copy link

farin commented Oct 17, 2019

Can you be more specific?

Yes.
Import in node env doesn't work but you can achive thet ckeditor is imported only in client env even your app is universal SSR app.

You need to do following steps:

  1. make plugin which register wrapper around component around ck editor

plugins/rich-editor.js

import Vue from 'vue'
import RichEditor from '@/components/RichEditor'

// register component from plugin to bypass SSR
Vue.component('rich-editor', RichEditor)

2 Register your plugin in nuxt config to be included only on client

nuxt.config.js

plugins: [
  { src: '~/plugins/rich-editor', ssr: false }
],
  1. Create wrapper component

components/RichEditor.vue

<template>
   <ckeditor
      :editor="editor"
      :value="value"
      :config="editorConfig"
     @input="ev => $emit('input', ev)" 
   />
</template>

<script>
import CKEditor from '@ckeditor/ckeditor5-vue'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'

export default {
  name: 'RichEditor',
  props: {
    value: [String],
    options: {
      type: [Object],
      default: () => {}
    }
  },
  components: {
    ckeditor: CKEditor.component
  },
  data() {
    return {      
      editor: ClassicEditor,
      editorConfig: this.options,
    }
  }
}
</script>
  1. Use your component anywhere you want. Bind content with standard v-model
    Dont' import RichEditor file there! Don't put RichEditor in components: { ... }.
<template>
  <div>
    <h1>My Page<h1>
    <rich-editor v-model="content" />
  </div>
</template>

Because plugin is not loaded on server side, then will be just unknown tag causing no trouble. On client side, it's regular component registered globally by plugin and page will be rendered with CKEditor as wanted..

@ThibaultVlacich
Copy link

ThibaultVlacich commented Oct 17, 2019

Thanks, it's working perfectly.

PS: According to the Nuxt documentation, we should use mode: 'client' instead of srr: false [1].

@MasterMindLegion
Copy link

@farin Hello there, I humbly thank for this great workaround for Nuxt, but if you can tell me, how to add plugins to Ck editor now? Thank you very

@avagru avagru closed this as completed Sep 18, 2020
@hanzlahabib
Copy link

@farin Hello there, I humbly thank for this great workaround for Nuxt, but if you can tell me, how to add plugins to Ck editor now? Thank you very

You can add a plugin from a web interface and build new CKEditor package for your need, or fork its repo and clone it on local make changes according to docs which state how to load different plugins in the editor, after completing this stuff push your stuff in a new branch and update it on remote,
now from this branch, you can publish npm package and use that package in your project

I hope this helps you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending:feedback This issue is blocked by necessary feedback.
Projects
None yet
Development

No branches or pull requests

8 participants