ckeditor / ckeditor5-react

Official CKEditor 5 React component.
https://ckeditor.com/ckeditor-5
Other
426 stars 100 forks source link

How to add webpack configuration in nx config-override.js ? #196

Open Rajesh-Thiyagarajan opened 4 years ago

Rajesh-Thiyagarajan commented 4 years ago

Hi Team

Previously i am using craco config for ckeditor.

const path = require("path");
const webpack = require("webpack");
const { getLoader, loaderByName, addBeforeLoader } = require("@craco/craco");
const absolutePath = path.join(__dirname, "../components");
const { styles } = require("@ckeditor/ckeditor5-dev-utils");
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;

const enableCKEWebpackConfigPlugin = (webpackConfig, { env, paths }) => {
  // Extract the oneOf array from the relevant webpack.module.rules object
  let oneOf;
  let ix;
  ix = webpackConfig.module.rules.findIndex(item => {
    return item.hasOwnProperty("oneOf");
  });
  oneOf = webpackConfig.module.rules[ix].oneOf;

  // Add the SVG and CSS loaders to the oneOf array
  const additions = [

    {
      test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
      test: /\.svg$/,
      use: ["raw-loader"]
    },
    {
      test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
      use: [
        {
          loader: "style-loader",
          options: {
            injectType: "singletonStyleTag"
          },
        },
        {
          loader: "postcss-loader",
          options: styles.getPostCssConfig({
            themeImporter: {
              themePath: require.resolve("@ckeditor/ckeditor5-theme-lark")
            },
            minify: true
          })
        }
      ]
    },
  ];
  additions.forEach((item, index) => {
    oneOf.push(item);
  });

  // Modify cssRegex
  let loader;
  loader = oneOf.find(item => {
    if (item.test !== undefined)
      return item.test.toString() === cssRegex.toString();
  });
  loader.exclude = [cssModuleRegex, /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/];

  // Modify cssModuleRegex
  loader = oneOf.find(item => {
    if (item.test !== undefined)
      return item.test.toString() === cssModuleRegex.toString();
  });
  loader.exclude = [/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/];

  // Modify file-loader
  loader = oneOf.find(item => {
    if (item.loader !== undefined)
      return (
        item.loader.toString() === require.resolve("file-loader").toString()
      );
  });
  loader.exclude = [
    /\.(js|mjs|jsx|ts|tsx)$/,
    /\.html$/,
    /\.json$/,
    /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
    /\.svg$/,
  ];

  // Always return a config object.
  return webpackConfig;
};

module.exports = {
  webpack: {
    alias: {},
    plugins: [
      new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery",
        "window.moment": "moment",
        moment: "moment",
        Raphael: "raphael", // required by morris.js
      }),
    ],
    configure: (webpackConfig, { env, paths }) => {
      const { isFound, match } = getLoader(
        webpackConfig,
        loaderByName("babel-loader")
      );
      if (isFound) {
        const include = Array.isArray(match.loader.include)
          ? match.loader.include
          : [match.loader.include];
        match.loader.include = include.concat[absolutePath];
        const exclude = Array.isArray(match.loader.exclude)
          ? match.loader.exclude
          : [match.loader.exclude]
        match.loader.exclude = {
          test: match.loader.exlude || /node_modules/,
          not: [absolutePath]
        }
      }
      return enableCKEWebpackConfigPlugin(webpackConfig, { env, paths });
    },
  },
};

Now we are switching to **nx config**.
Could you please help me how to do that **nx config-override.js**

**nx config-overide.js**
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const TsConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');

const appName = "cadence";

module.exports = {
  webpack: (config) => {
    // Remove guard against importing modules outside of `src`.
    // Needed for workspace projects.
    config.resolve.plugins = config.resolve.plugins.filter(
      (plugin) => !(plugin instanceof ModuleScopePlugin)
    );

    // Add support for importing workspace projects.
    config.resolve.plugins.push(
      new TsConfigPathsPlugin({
        configFile: path.resolve(__dirname, 'tsconfig.json'),
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
        mainFields: ['module', 'main'],
      })
    );

    // Replace include option for babel loader with exclude
    // so babel will handle workspace projects as well.
    config.module.rules.forEach((r) => {
      if (r.oneOf) {
        const babelLoader = r.oneOf.find(
          (rr) => rr.loader.indexOf('babel-loader') !== -1
        );
        babelLoader.exclude = /node_modules/;
        delete babelLoader.include;
      }
    });

    return config;
  },
  paths: (paths) => {
    // Rewrite dist folder to where Nx expects it to be.
    paths.appBuild = path.resolve(__dirname, `../../dist/apps/${appName}`);
    return paths;
  },
  jest: (config) => {
    config.resolver = '@nrwl/jest/plugins/resolver';
    return config;
  },
};

Edit by @pomek: Formatting code style.

Rajesh-Thiyagarajan commented 4 years ago

Now I have done some modifications in some modifications in config-override.js

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const TsConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');

const appName = 'cadence';

const { styles } = require('@ckeditor/ckeditor5-dev-utils');
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;

module.exports = {
  webpack: (config) => {
    // Remove guard against importing modules outside of `src`.
    // Needed for workspace projects.
    config.resolve.plugins = config.resolve.plugins.filter(
      (plugin) => !(plugin instanceof ModuleScopePlugin)
    );

    // Add support for importing workspace projects.
    config.resolve.plugins.push(
      new TsConfigPathsPlugin({
        configFile: path.resolve(__dirname, 'tsconfig.json'),
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
        mainFields: ['module', 'main'],
      })
    );

    // Replace include option for babel loader with exclude
    // so babel will handle workspace projects as well.
    config.module.rules.forEach((r) => {
      if (r.oneOf) {
        const babelLoader = r.oneOf.find(
          (rr) => rr.loader.indexOf('babel-loader') !== -1
        );
        babelLoader.exclude = /node_modules/;
        delete babelLoader.include;
      }
    });

    // Extract the oneOf array from the relevant webpack.module.rules object
    let oneOf;
    let ix;
    ix = config.module.rules.findIndex((item) => {
      return item.hasOwnProperty('oneOf');
    });
    oneOf = config.module.rules[ix].oneOf;

    // Add the SVG and CSS loaders to the oneOf array
    const additions = [
      {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
        // test: /\.svg$/,
        use: ['raw-loader'],
      },
      {
        test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
        use: [
          {
            loader: 'style-loader',
            options: {
              injectType: 'singletonStyleTag',
            },
          },
          {
            loader: 'postcss-loader',
            options: styles.getPostCssConfig({
              themeImporter: {
                themePath: require.resolve('@ckeditor/ckeditor5-theme-lark'),
              },
              minify: true,
            }),
          },
        ],
      },
    ];
    additions.forEach((item, index) => {
      oneOf.push(item);
    });

    // Modify cssRegex
    let loader;
    loader = oneOf.find((item) => {
      if (item.test !== undefined)
        return item.test.toString() === cssRegex.toString();
    });
    loader.exclude = [
      cssModuleRegex,
      /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
    ];

    // Modify cssModuleRegex
    loader = oneOf.find((item) => {
      if (item.test !== undefined)
        return item.test.toString() === cssModuleRegex.toString();
    });
    loader.exclude = [/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/];

    // Modify file-loader
    loader = oneOf.find((item) => {
      if (item.loader !== undefined)
        return (
          item.loader.toString() === require.resolve('file-loader').toString()
        );
    });

    loader.exclude = [
      /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
      /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
      // /\.svg$/,
    ];

    return config;
  },
  paths: (paths) => {
    // Rewrite dist folder to where Nx expects it to be.
    paths.appBuild = path.resolve(__dirname, `../../dist/apps/${appName}`);
    return paths;
  },
  jest: (config) => {
    config.resolver = '@nrwl/jest/plugins/resolver';
    return config;
  },
};

if I comment below code the application get started. But ckeditor5 throwing error.

// Modify file-loader   
    loader.exclude = [
      /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
      /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
      // /\.svg$/,
    ];

Error image

If i uncomment the code i am getting undefined error in the vscode terminal image

Edit by @pomek: Formatting code style.

Rajesh-Thiyagarajan commented 4 years ago

Hi Team Any update ?

wtakayama-chwy commented 2 years ago

@Rajesh-Thiyagarajan I'm facing the same issue, what I discover is that if I downgrade the version from react-scripts to 4.0.3, the CKEditor 5 compiles correctly. Not sure why yet, but looks like react-scripts uses webpack 5 and the exclude doesn't work as expected for multiple loaders.