Create a gist now

Instantly share code, notes, and snippets.

Embed
Theming Ant Design with Sass and Webpack

Theming Ant Design with Sass and Webpack

This is a solution on how to theme/customize Ant Design (which is written in Less) with Sass and webpack. Ant itself offers two solutions and a related article on theming, but these are only applicable if you use Less, the antd-init boilerplate or dva-cli.

What this solution offers:

  • use a single sass-file to customize (no duplicate variables for your project and Ant)
  • hot reload compatibility
  • no dependencies on outdated npm modules
  • easy integration with your existing webpack setup (webpack 3+ tested)

Any downsides?

  • all ant-styles are imported

According to our observations this does not have that much impact in practice, as using only a couple of Ant components will already result in most styles being loaded.

Procedure

The main procedure is as follows:

  1. Define your variables in variables.scss
  2. Write a ant.less file which imports the Ant less-styles and your sass-variables (yes)
  3. Tell webpack to load less files via less-loader
  4. Tell webpack to rewrite sass-files which are imported from less-files ($something -> @something)
  5. Import ant.less in your project.

How?

Apply the changes / create the files as shown below. The changes should be self-explanatory. Just keep in mind, that your exact webpack-setup may differ a bit from the one given below.

Authors: Kruemelkatze, mrukas

//Use .babelrc or add the options to the webpack loader
//Remove comments in .babelrc as they most likely will produce build errors
{
"presets": [
//...
],
"plugins": [
//...
["import", {
"libraryName": "antd",
"libraryDirectory": "es" //or "lib" for default
//No "style" setting
}]
]
}
@import "~antd/dist/antd.less";
@import "variables.scss"; // <-- SASS in a LESS file!
// Import the ant.less file in your project
import 'ant.less';
// This loader will simply replace all $something sass-variable with @something less-variables
module.exports = function (source) {
return source.replace(/\$/ig, '@');
};
// THIS FILE SHOULD ONLY CONTAIN VARIABLE DEFINITIONS
// Ant Colors & Styles can be overwritten here. Just use the variable names from
// https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
// Be sure to use $xyz, not @xyz!
$primary-color: crimson;
module: {
rules: [
{
loader: 'babel-loader',
test: /\.jsx?$/,
// Other settings, like include or exclude
options: {
presets: [
//...
],
plugins: [
// ...
// Importing Ant here is not needed if you are using a .babelrc file
['import', {
"libraryName": "antd",
"libraryDirectory": "es" // or "lib" for default
// No "style" setting
}],
]
},
},
// ...
// Include less-loader (exact settings may deviate depending on your building/bundling procedure)
{
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{
loader: "less-loader",
options: {
javascriptEnabled: true //This is important!
}
}
]
},
// Tell the DEFAULT sass-rule to ignore being used for sass imports in less files (sounds weird)
{
test: /\.scss$/,
issuer: {
exclude: /\.less$/,
},
// ... other settings
},
// Define a second rule for only being used from less files
// This rule will only be used for converting our sass-variables to less-variables
{
test: /\.scss$/,
issuer: /\.less$/,
use: {
loader: './sassVarsToLess.js' // Change path if necessary
}
},
// ...
]
}
@tim-soft

This comment has been minimized.

Show comment
Hide comment
@tim-soft

tim-soft Mar 28, 2018

Hey that's pretty clever! I integrated this into a boilerplate to test with and seems to work pretty well, have you ran into any stability issues/crashes during HMR?

Here's a demo for anyone interested
https://github.com/tim-soft/react-starter-kit-antd

git clone https://github.com/tim-soft/react-starter-kit-antd.git
cd react-starter-kit-antd
yarn install && yarn start

Hey that's pretty clever! I integrated this into a boilerplate to test with and seems to work pretty well, have you ran into any stability issues/crashes during HMR?

Here's a demo for anyone interested
https://github.com/tim-soft/react-starter-kit-antd

git clone https://github.com/tim-soft/react-starter-kit-antd.git
cd react-starter-kit-antd
yarn install && yarn start
@Kruemelkatze

This comment has been minimized.

Show comment
Hide comment
@Kruemelkatze

Kruemelkatze Mar 30, 2018

Hey, thanks! Glad that some people are using this! :)

We (8 devs in our company) did not encounter any issues with HMR yet. It may take a bit longer if the variables are changed because the Ant styles are recompiled. But changing branding colors isn't anything that you do on a regular basis :)

Owner

Kruemelkatze commented Mar 30, 2018

Hey, thanks! Glad that some people are using this! :)

We (8 devs in our company) did not encounter any issues with HMR yet. It may take a bit longer if the variables are changed because the Ant styles are recompiled. But changing branding colors isn't anything that you do on a regular basis :)

@Hazantip

This comment has been minimized.

Show comment
Hide comment
@Hazantip

Hazantip Apr 12, 2018

Thank's a lot, this magic works good!

Thank's a lot, this magic works good!

@TuxujPes

This comment has been minimized.

Show comment
Hide comment
@TuxujPes

TuxujPes Jun 11, 2018

This way, antd styles will be loaded after your component's styles, right?
If so, there will be no possibility to overwrite some pesky !importants :(

TuxujPes commented Jun 11, 2018

This way, antd styles will be loaded after your component's styles, right?
If so, there will be no possibility to overwrite some pesky !importants :(

@Kruemelkatze

This comment has been minimized.

Show comment
Hide comment
@Kruemelkatze

Kruemelkatze Jun 21, 2018

We included our styles in this order and do not have any issues with overriding:

// App.jsx
import 'ant.less';
import 'main.scss'; // our app styles

Before we switched to this solution, we loaded the Ant styles using Ant's import-loader. With this we had the exact same problem you describe, so we used a (really dirty!) hack and reversed the css chunks generated by HtmlWebpackPlugin.

// webpack.config.js
plugins: [
    new HtmlWebpackPlugin({
        // ...
        chunksSortMode: function (a, b) {
            // Reverse files in css chunk
        }
    }
]

I did not post the whole code as we strongly discourage this hack. ;)

Owner

Kruemelkatze commented Jun 21, 2018

We included our styles in this order and do not have any issues with overriding:

// App.jsx
import 'ant.less';
import 'main.scss'; // our app styles

Before we switched to this solution, we loaded the Ant styles using Ant's import-loader. With this we had the exact same problem you describe, so we used a (really dirty!) hack and reversed the css chunks generated by HtmlWebpackPlugin.

// webpack.config.js
plugins: [
    new HtmlWebpackPlugin({
        // ...
        chunksSortMode: function (a, b) {
            // Reverse files in css chunk
        }
    }
]

I did not post the whole code as we strongly discourage this hack. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment