DocSpring / craco-antd

A craco plugin to use Ant Design with create-react-app
MIT License
234 stars 49 forks source link

Add example of working with AntdScssThemePlugin #25

Open nirvdrum opened 4 years ago

nirvdrum commented 4 years ago

craco-antd is a great way to provide a custom theme for Ant with a project created by create-react-app. I think the next logical step for many projects is being able to consume the Ant less styles from within an SCSS-enabled CRA-based app. AntdScssThemePlugin is a project that enables doing such, by hooking into the less and sass loaders.

Since craco-antd also pulls in craco-less, it has all the key components to support AntdScssThemePlugin. I think it'd be helpful if the documentation showed how to do so.

I realize docs like this may not be an exact fit because it includes an external project. However, I think it's in keeping with the goals of this project and that documentation should live somewhere semi-official, instead of someone's blog.

nirvdrum commented 4 years ago

It took a while to work it all out, but this craco.config.js file will do it:

const AntdScssThemePlugin = require('antd-scss-theme-plugin')
const CracoAntDesignPlugin = require('craco-antd')
const path = require('path')

const ReplaceSassLoaderPlugin = {
  overrideWebpackConfig: ({ webpackConfig }) => {
    const oneOfRule = webpackConfig.module.rules.find(rule => rule.oneOf)

    oneOfRule.oneOf.forEach(rule => {
      if (rule.test && rule.test.toString().includes('scss|sass')) {
        rule.use = rule.use.map(rule => {
          if (rule.loader && rule.loader.includes('sass-loader')) {
            return AntdScssThemePlugin.themify({ loader: 'sass-loader', options: rule.options })
          } else {
            return rule
          }
        })
      }
    })

    return webpackConfig
  },
}

module.exports = {
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeThemeLessPath: path.join(__dirname, '../src/styles/ant/customTheme.less'),
        modifyLessRule: (lessRule, _context) => {
          const use = lessRule.use.map(rule => {
            if (rule.loader.includes('less-loader')) {
              return AntdScssThemePlugin.themify({ loader: 'less-loader', options: rule.options })
            } else {
              return rule
            }
          })

          return { ...lessRule, use: use }
        },
      },
    },
    {
      plugin: ReplaceSassLoaderPlugin,
    },
  ],
  webpack: {
    plugins: [new AntdScssThemePlugin(path.join(__dirname, '../src/styles/ant/customTheme.scss'))],
  },
  /*
  devServer: {
    quiet: false,
  },
  */
}

Note that one odd consequence of this is that there are now two ways to override Ant's variables: through a custom less file or a custom sass file. The less version is still the more powerful of the two because it can make use of Ant's variables. The custom sass file, in contrast, can only override Ant variables -- it can't reference them. But, other sass files can reference Ant's variables now, so that's really nice.

MildTomato commented 4 years ago

@nirvdrum I'm getting a sass export error with this.

./node_modules/antd/es/icon/style/index.less (./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--6-oneOf-8-3!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--6-oneOf-8-4!./node_modules/antd/es/icon/style/index.less)
Could not compile the SCSS theme file "/Users/jonathan/Sites/plover/src/styles/ant/customTheme.scss" for the purpose of variable extraction. This is likely because it contains a Sass error.

Did you get anything similar?

I have a theme file in ./src/styles/ant/customTheme.scss

Jsisas commented 3 years ago

Did you ever resolve this issue?

imVinayPandya commented 2 years ago

@nirvdrum I'm getting a sass export error with this.

./node_modules/antd/es/icon/style/index.less (./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--6-oneOf-8-3!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--6-oneOf-8-4!./node_modules/antd/es/icon/style/index.less)
Could not compile the SCSS theme file "/Users/jonathan/Sites/plover/src/styles/ant/customTheme.scss" for the purpose of variable extraction. This is likely because it contains a Sass error.

Did you get anything similar?

I have a theme file in ./src/styles/ant/customTheme.scss

getting same error, any solution?

floatrx commented 2 years ago
./node_modules/antd/es/icon/style/index.less (./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--6-oneOf-8-3!./node_modules/antd-scss-theme-plugin/build/dist/lib/antdLessLoader.js??ref--6-oneOf-8-4!./node_modules/antd/es/icon/style/index.less)
Could not compile the SCSS theme file "/Users/jonathan/Sites/plover/src/styles/ant/customTheme.scss" for the purpose of variable extraction. This is likely because it contains a Sass error.

++++ 1 same error...

I like antd & scss! I want define my variables from single file variables.antd.scss and use them for antd & for my other styles || modules...

this is my current craco.config.js

const CracoAntDesignPlugin = require("craco-antd");
const path = require("path");

const pathResolve = (pathUrl) => path.join(__dirname, pathUrl);

module.exports = {
  reactScriptsVersion: "react-scripts",
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        customizeThemeLessPath: pathResolve("src/styles/variables.antd.less"),
      },
    },
  ],
};