annyoung

CKEditor5 React webpack setup 본문

카테고리 없음

CKEditor5 React webpack setup

nopsled 2021. 6. 1. 12:23
npm -v
6.14.8
node -v
v14.11.0
cat package.json| grep \"react\"
"react": "^16.13.1",

node 14.11.0, npm 6.14.8, react 16.13.1 (CRA) 기준으로 제작 되었습니다.

 

{
  "name": "copies-client",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "@ckeditor/ckeditor5-adapter-ckfinder": "^27.1.0",
    "@ckeditor/ckeditor5-alignment": "^27.1.0",
    "@ckeditor/ckeditor5-autoformat": "^27.1.0",
    "@ckeditor/ckeditor5-autosave": "^27.1.0",
    "@ckeditor/ckeditor5-basic-styles": "^27.1.0",
    "@ckeditor/ckeditor5-block-quote": "^27.1.0",
    "@ckeditor/ckeditor5-build-classic": "^27.1.0",
    "@ckeditor/ckeditor5-ckfinder": "^27.1.0",
    "@ckeditor/ckeditor5-cloud-services": "^27.1.0",
    "@ckeditor/ckeditor5-dev-webpack-plugin": "^25.2.1",
    "@ckeditor/ckeditor5-easy-image": "^27.1.0",
    "@ckeditor/ckeditor5-editor-classic": "^27.1.0",
    "@ckeditor/ckeditor5-essentials": "^27.1.0",
    "@ckeditor/ckeditor5-export-pdf": "^27.1.0",
    "@ckeditor/ckeditor5-font": "^27.1.0",
    "@ckeditor/ckeditor5-heading": "^27.1.0",
    "@ckeditor/ckeditor5-horizontal-line": "^27.1.0",
    "@ckeditor/ckeditor5-image": "^27.1.0",
    "@ckeditor/ckeditor5-indent": "^27.1.0",
    "@ckeditor/ckeditor5-link": "^27.1.0",
    "@ckeditor/ckeditor5-list": "^27.1.0",
    "@ckeditor/ckeditor5-media-embed": "^27.1.0",
    "@ckeditor/ckeditor5-paragraph": "^27.1.0",
    "@ckeditor/ckeditor5-paste-from-office": "^27.1.0",
    "@ckeditor/ckeditor5-react": "^3.0.2",
    "@ckeditor/ckeditor5-special-characters": "^27.1.0",
    "@ckeditor/ckeditor5-table": "^27.1.0",
    "@ckeditor/ckeditor5-typing": "^27.1.0",
    "css-loader": "3.4.2",
    "postcss-loader": "3.0.0",
    "react": "^16.13.1"
  },
  "devDependencies": {
    "@ckeditor/ckeditor5-core": "^27.1.0",
    "@ckeditor/ckeditor5-dev-utils": "^25.2.1",
    "@ckeditor/ckeditor5-dev-webpack-plugin": "^25.0.0",
    "@ckeditor/ckeditor5-theme-lark": "^27.1.0",
    "postcss-loader": "^3.0.0",
    "raw-loader": "^4.0.1",
    "style-loader": "^1.2.1",
    "terser-webpack-plugin": "^3.0.2",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  }
}

설치된 package.json (저는 친절하지 않으니 알아서 복사해서 붙여넣으세요.)

webpack.config.js에 ckeditor webpack plugin, dev-utils 추가

const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );

webpack.config.js에 build rules 추가

{
          test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
          use: [ 'raw-loader' ]
        },
        {
          test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
          use: [
            {
              loader: 'style-loader',
              options: {
                injectType: 'singletonStyleTag',
                attributes: {
                  'data-cke': true
                }
              }
            },
            {
              loader: 'postcss-loader',
              options: styles.getPostCssConfig( {
                themeImporter: {
                  themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
                },
                minify: true
              } )
            },
          ]
        },

중복으로 빌드되는 ckeditor5의 theme css를 제외하기 위해 or로 변경

exclude: {
    or: [cssModuleRegex, /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/],
},

 

 

import styled, {createGlobalStyle} from 'styled-components';
import {IMAGE_UPLOAD_URL} from "../constants/urls";
import {getUserToken} from "../helpers/authUtils";
import React from "react";

import {CKEditor} from "@ckeditor/ckeditor5-react";
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';

import Bold from "@ckeditor/ckeditor5-basic-styles/src/bold.js";
import Essentials from "@ckeditor/ckeditor5-essentials/src/essentials.js";
import Heading from "@ckeditor/ckeditor5-heading/src/heading.js";
import Paragraph from "@ckeditor/ckeditor5-paragraph/src/paragraph.js";
import Italic from "@ckeditor/ckeditor5-basic-styles/src/italic.js";
import Alignment from "@ckeditor/ckeditor5-alignment/src/alignment.js";
import BlockQuote from "@ckeditor/ckeditor5-block-quote/src/blockquote.js";
import Autoformat from "@ckeditor/ckeditor5-autoformat/src/autoformat.js";
import Autosave from "@ckeditor/ckeditor5-autosave/src/autosave.js";
import CKFinder from "@ckeditor/ckeditor5-ckfinder/src/ckfinder.js";
import CKFinderUploadAdapter from "@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js";
// import ExportToPDF from "@ckeditor/ckeditor5-export-pdf/src/exportpdf.js";
import FontColor from "@ckeditor/ckeditor5-font/src/fontcolor.js";
import FontFamily from "@ckeditor/ckeditor5-font/src/fontfamily.js";
import FontSize from "@ckeditor/ckeditor5-font/src/fontsize.js";
import HorizontalLine from "@ckeditor/ckeditor5-horizontal-line/src/horizontalline.js";
import Image from "@ckeditor/ckeditor5-image/src/image.js";
import ImageCaption from "@ckeditor/ckeditor5-image/src/imagecaption.js";
import ImageResize from "@ckeditor/ckeditor5-image/src/imageresize.js";
import ImageStyle from "@ckeditor/ckeditor5-image/src/imagestyle.js";
import ImageToolbar from "@ckeditor/ckeditor5-image/src/imagetoolbar.js";
import ImageUpload from "@ckeditor/ckeditor5-image/src/imageupload.js";
import Indent from "@ckeditor/ckeditor5-indent/src/indent.js";
import IndentBlock from "@ckeditor/ckeditor5-indent/src/indentblock.js";
import Link from "@ckeditor/ckeditor5-link/src/link.js";
import List from "@ckeditor/ckeditor5-list/src/list.js";
import MediaEmbed from "@ckeditor/ckeditor5-media-embed/src/mediaembed.js";
import PasteFromOffice from "@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice";
import SpecialCharacters from "@ckeditor/ckeditor5-special-characters/src/specialcharacters.js";
import SpecialCharactersEssentials from "@ckeditor/ckeditor5-special-characters/src/specialcharactersessentials.js";
import Strikethrough from "@ckeditor/ckeditor5-basic-styles/src/strikethrough.js";
import Table from "@ckeditor/ckeditor5-table/src/table.js";
import TableToolbar from "@ckeditor/ckeditor5-table/src/tabletoolbar.js";
import TextTransformation from "@ckeditor/ckeditor5-typing/src/texttransformation.js";
import Underline from "@ckeditor/ckeditor5-basic-styles/src/underline.js";
import '@ckeditor/ckeditor5-build-classic/build/translations/ko';



const installedPlugins = [
    Alignment,
    Autoformat,
    Autosave,
    BlockQuote,
    Bold,
    CKFinder,
    CKFinderUploadAdapter,
    Essentials,
    // ExportToPDF,
    FontColor,
    FontFamily,
    FontSize,
    Heading,
    HorizontalLine,
    Image,
    ImageCaption,
    ImageResize,
    ImageStyle,
    ImageToolbar,
    ImageUpload,
    Indent,
    IndentBlock,
    Italic,
    Link,
    List,
    MediaEmbed,
    Paragraph,
    PasteFromOffice,
    SpecialCharacters,
    SpecialCharactersEssentials,
    Strikethrough,
    Table,
    TableToolbar,
    TextTransformation,
    Underline,
];

const OverrideEditorStyle = createGlobalStyle`
    .ck-editor__editable {
        min-height: ${({height}) => height ? height : '300'}px;
`;

class Editor extends React.Component<Props> {
    constructor(props) {
        super(props);
        this.state = {}
    }

    componentDidMount() {
    }

    componentWillUnmount() {
    }

    render() {
        return (
            <React.Fragment>
                <OverrideEditorStyle {...this.props}/>

                <CKEditor
                    editor={ClassicEditor}
                    config={{
                        ckfinder: {
                            uploadUrl: IMAGE_UPLOAD_URL
                        },
                        language: 'ko', // language for the korean
                        plugins: [...installedPlugins],
                        toolbar: [
                            // "exportPdf",
                            "|",
                            "heading",
                            "|",
                            "fontFamily",
                            "fontSize",
                            "fontColor",
                            "alignment",
                            "|",
                            "bold",
                            "italic",
                            "strikethrough",
                            "underline",
                            "specialCharacters",
                            "horizontalLine",
                            "|",
                            "bulletedList",
                            "numberedList",
                            "|",
                            "indent",
                            "outdent",
                            "|",
                            "link",
                            "blockQuote",
                            // "CKFinder",
                            "imageUpload",
                            "insertTable",
                            "mediaEmbed",
                            "|",
                            "undo",
                            "redo",
                        ],
                    }}
                    data={this.props.value || ''}
                    onReady={editor => {
                    }}
                    onChange={(event, editor) => {
                        const data = editor.getData();
                        this.props.handleChange({event, editor, data})
                    }}
                    onBlur={(event, editor) => {
                        // console.log('Blur.', editor);
                    }}
                    onFocus={(event, editor) => {
                    }}
                />
            </React.Fragment>
        )
    }
}

export default Editor;

Editor.jsx

Comments