【问题标题】:CKEditor5 with React: Adding a custom plugin fails (dublicated modules)CKEditor5 with React:添加自定义插件失败(重复模块)
【发布时间】:2022-10-24 19:59:49
【问题描述】:

我正在尝试在反应应用程序中为 CKEditor5 构建一个自定义插件。我主要遵循这两个教程:

这是我的代码到目前为止的样子:

import React from 'react';
import logo from './logo.svg';
import './App.css';

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';

class Timestamp extends Plugin {
  init() {
    console.log( 'Timestamp was initialized.' );
  }
}

function App() {
  return (
    <div className="App">
      <h2>Using CKEditor 5 build in React</h2>
      <CKEditor
        editor={ ClassicEditor }
        config={ {
          plugins: [ Timestamp ],
          toolbar: [ 'bold', 'italic' ]
        } }
        data="<p>Hello from CKEditor 5!</p>"
        onReady={ (editor: any) => {
          // You can store the "editor" and use when it is needed.
          console.log( 'Editor is ready to use!', editor );
        } }
        onChange={ ( event: any, editor: { getData: () => any; } ) => {
          const data = editor.getData();
          console.log( { event, editor, data } );
        } }
        onBlur={ ( event: any, editor: any ) => {
          console.log( 'Blur.', editor );
        } }
        onFocus={ ( event: any, editor: any ) => {
          console.log( 'Focus.', editor );
        } }
      />
    </div>
  );
}

export default App;

我不断收到白屏,但控制台中出现此错误:

Uncaught CKEditorError: ckeditor-duplicated-modules
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-ckeditor-duplicated-modules
    at ./node_modules/@ckeditor/ckeditor5-utils/src/version.js (version.js:144:1)
    at options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at ./node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.js (ckeditorerror.js:195:1)
    at options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at ./node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.js (mix.js:48:1)
    at options.factory (react refresh:6:1)

错误代码(重复模块)的文档没有说明自定义插件(仅导入的插件)。从我在这里看到的 (https://ckeditor.com/docs/ckeditor5/latest/framework/guides/tutorials/using-react-in-a-widget.html) 应该是可行的。

有谁知道我做错了什么?

【问题讨论】:

    标签: ckeditor ckeditor5 ckeditor5-react ckeditor5-plugin


    【解决方案1】:

    好的,我应该更仔细地阅读文档。本质上,如果您在从 create-react-app 生成的 repo 中工作,则必须更新您的 webpack 配置。这里有一个详尽的指南:https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/react.html#using-create-react-app3

    这是我的rules 块在我的./config/webpack.config.js 文件中的样子:

    rules: [
            // Handle node_modules packages that contain sourcemaps
            shouldUseSourceMap && {
              enforce: 'pre',
              exclude: /@babel(?:/|\{1,2})runtime/,
              test: /.(js|mjs|jsx|ts|tsx|css)$/,
              loader: require.resolve('source-map-loader'),
            },
            {
              // "oneOf" will traverse all following loaders until one will
              // match the requirements. When no loader matches it will fall
              // back to the "file" loader at the end of the loader list.
              oneOf: [
                // TODO: Merge this config once `image/avif` is in the mime-db
                // https://github.com/jshttp/mime-db
                {
                  test: [/.avif$/],
                  type: 'asset',
                  mimetype: 'image/avif',
                  parser: {
                    dataUrlCondition: {
                      maxSize: imageInlineSizeLimit,
                    },
                  },
                },
                // "url" loader works like "file" loader except that it embeds assets
                // smaller than specified limit in bytes as data URLs to avoid requests.
                // A missing `test` is equivalent to a match.
                {
                  test: [/.bmp$/, /.gif$/, /.jpe?g$/, /.png$/],
                  type: 'asset',
                  parser: {
                    dataUrlCondition: {
                      maxSize: imageInlineSizeLimit,
                    },
                  },
                },
                {
                  test: /.svg$/,
                  // Exclude `js` files to keep the "css" loader working as it injects
                  // its runtime that would otherwise be processed through the "file" loader.
                  // Also exclude `html` and `json` extensions so they get processed
                  // by webpack's internal loaders.
                  exclude: [
                    /.(js|mjs|jsx|ts|tsx)$/,
                    /.html$/,
                    /.json$/,
                    /ckeditor5-[^/\]+[/\]theme[/\]icons[/\][^/\]+.svg$/,
                    /ckeditor5-[^/\]+[/\]theme[/\].+.css$/
                  ],
                  use: [
                    {
                      loader: require.resolve('@svgr/webpack'),
                      options: {
                        prettier: false,
                        svgo: false,
                        svgoConfig: {
                          plugins: [{ removeViewBox: false }],
                        },
                        titleProp: true,
                        ref: true,
                      },
                    },
                    {
                      loader: require.resolve('file-loader'),
                      options: {
                        name: 'static/media/[name].[hash].[ext]',
                      },
                    },
                  ],
                  issuer: {
                    and: [/.(ts|tsx|js|jsx|md|mdx)$/],
                  },
                },
                // Process application JS with Babel.
                // The preset includes JSX, Flow, TypeScript, and some ESnext features.
                {
                  test: /.(js|mjs|jsx|ts|tsx)$/,
                  include: paths.appSrc,
                  loader: require.resolve('babel-loader'),
                  options: {
                    customize: require.resolve(
                      'babel-preset-react-app/webpack-overrides'
                    ),
                    presets: [
                      [
                        require.resolve('babel-preset-react-app'),
                        {
                          runtime: hasJsxRuntime ? 'automatic' : 'classic',
                        },
                      ],
                    ],
                    
                    plugins: [
                      isEnvDevelopment &&
                        shouldUseReactRefresh &&
                        require.resolve('react-refresh/babel'),
                    ].filter(Boolean),
                    // This is a feature of `babel-loader` for webpack (not Babel itself).
                    // It enables caching results in ./node_modules/.cache/babel-loader/
                    // directory for faster rebuilds.
                    cacheDirectory: true,
                    // See #6846 for context on why cacheCompression is disabled
                    cacheCompression: false,
                    compact: isEnvProduction,
                  },
                },
                // Process any JS outside of the app with Babel.
                // Unlike the application JS, we only compile the standard ES features.
                {
                  test: /.(js|mjs)$/,
                  exclude: /@babel(?:/|\{1,2})runtime/,
                  loader: require.resolve('babel-loader'),
                  options: {
                    babelrc: false,
                    configFile: false,
                    compact: false,
                    presets: [
                      [
                        require.resolve('babel-preset-react-app/dependencies'),
                        { helpers: true },
                      ],
                    ],
                    cacheDirectory: true,
                    // See #6846 for context on why cacheCompression is disabled
                    cacheCompression: false,
                    
                    // Babel sourcemaps are needed for debugging into node_modules
                    // code.  Without the options below, debuggers like VSCode
                    // show incorrect code and set breakpoints on the wrong lines.
                    sourceMaps: shouldUseSourceMap,
                    inputSourceMap: shouldUseSourceMap,
                  },
                },
                // "postcss" loader applies autoprefixer to our CSS.
                // "css" loader resolves paths in CSS and adds assets as dependencies.
                // "style" loader turns CSS into JS modules that inject <style> tags.
                // In production, we use MiniCSSExtractPlugin to extract that CSS
                // to a file, but in development "style" loader enables hot editing
                // of CSS.
                // By default we support CSS Modules with the extension .module.css
                {
                  test: cssRegex,
                  exclude: [
                    cssModuleRegex,
                    /ckeditor5-[^/\]+[/\]theme[/\].+.css$/,
                  ],
                  use: getStyleLoaders({
                    importLoaders: 1,
                    sourceMap: isEnvProduction
                      ? shouldUseSourceMap
                      : isEnvDevelopment,
                    modules: {
                      mode: 'icss',
                    },
                  }),
                  // Don't consider CSS imports dead code even if the
                  // containing package claims to have no side effects.
                  // Remove this when webpack adds a warning or an error for this.
                  // See https://github.com/webpack/webpack/issues/6571
                  sideEffects: true,
                },
                // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
                // using the extension .module.css
                {
                  test: cssModuleRegex,
                  exclude: [
                    /ckeditor5-[^/\]+[/\]theme[/\].+.css$/,
                  ],
                  use: getStyleLoaders({
                    importLoaders: 1,
                    sourceMap: isEnvProduction
                      ? shouldUseSourceMap
                      : isEnvDevelopment,
                    modules: {
                      mode: 'local',
                      getLocalIdent: getCSSModuleLocalIdent,
                    },
                  }),
                },
                // Opt-in support for SASS (using .scss or .sass extensions).
                // By default we support SASS Modules with the
                // extensions .module.scss or .module.sass
                {
                  test: sassRegex,
                  exclude: sassModuleRegex,
                  use: getStyleLoaders(
                    {
                      importLoaders: 3,
                      sourceMap: isEnvProduction
                        ? shouldUseSourceMap
                        : isEnvDevelopment,
                      modules: {
                        mode: 'icss',
                      },
                    },
                    'sass-loader'
                  ),
                  // Don't consider CSS imports dead code even if the
                  // containing package claims to have no side effects.
                  // Remove this when webpack adds a warning or an error for this.
                  // See https://github.com/webpack/webpack/issues/6571
                  sideEffects: true,
                },
                // Adds support for CSS Modules, but using SASS
                // using the extension .module.scss or .module.sass
                {
                  test: sassModuleRegex,
                  use: getStyleLoaders(
                    {
                      importLoaders: 3,
                      sourceMap: isEnvProduction
                        ? shouldUseSourceMap
                        : isEnvDevelopment,
                      modules: {
                        mode: 'local',
                        getLocalIdent: getCSSModuleLocalIdent,
                      },
                    },
                    'sass-loader'
                  ),
                },
                // Custom loaders for CKEditor5
                {
                  test: /ckeditor5-[^/\]+[/\]theme[/\]icons[/\][^/\]+.svg$/,
                  use: [ 'raw-loader' ]
                },
                {
                  test: /ckeditor5-[^/\]+[/\]theme[/\].+.css$/,
                  use: [
                      {
                          loader: 'style-loader',
                          options: {
                              injectType: 'singletonStyleTag',
                              attributes: {
                                  'data-cke': true
                              }
                          }
                      },
                      'css-loader',
                      {
                          loader: 'postcss-loader',
                          options: {
                              postcssOptions: styles.getPostCssConfig( {
                                  themeImporter: {
                                      themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
                                  },
                                  minify: true
                              } )
                          }
                      }
                  ]
                },
                // "file" loader makes sure those assets get served by WebpackDevServer.
                // When you `import` an asset, you get its (virtual) filename.
                // In production, they would get copied to the `build` folder.
                // This loader doesn't use a "test" so it will catch all modules
                // that fall through the other loaders.
                {
                  // Exclude `js` files to keep "css" loader working as it injects
                  // its runtime that would otherwise be processed through "file" loader.
                  // Also exclude `html` and `json` extensions so they get processed
                  // by webpacks internal loaders.
                  exclude: [/^$/, /.(js|mjs|jsx|ts|tsx)$/, /.html$/, /.json$/],
                  type: 'asset/resource',
                },
                // ** STOP ** Are you adding a new loader?
                // Make sure to add the new loader(s) before the "file" loader.
              ],
            }
          ].filter(Boolean),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-28
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2016-12-17
      相关资源
      最近更新 更多