Reputation: 869
I want to use Next.js with Sass and CSS modules but also want to use Ant Design and wanted to use the Less styles for smaller building size.
I'm able to enable either CSS modules or Less loader but not both at the same time. The examples from Next.js were not helping me complete that problem.
Upvotes: 36
Views: 44232
Reputation: 31
To add Less to the Next.js is easy way.
Need to add 'next-with-less' library (also install less and less-loader) and 'next-compose-plugin'.
To your next.config.js add:
/** @type {import('next').NextConfig} */
const withPlugins = require('next-compose-plugins');
const withLess = require('next-with-less');
const plugins = [
[
withLess,
{
lessLoaderOptions: {},
},
],
];
module.exports = withPlugins(plugins, {
reactStrictMode: true,
swcMinify: true,
});
Upvotes: 3
Reputation: 7
For anyone who is still having trouble, you don't need any extra package other than our lovely mini-css-extract-plugin. Here is how you solve the issue.
PS: I also added sass to my webpack config. You can use both less and sass/scss files in your project.
next.config.js
:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
webpack(config) {
config.module.rules.push(
{
// this part is for css
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, { loader: 'css-loader' }],
},
{
// this part is for sass
test: /\.module\.(scss|sass)$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},
{
// this part is for less
test: /\.less$/i,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
},
{
loader: 'less-loader',
options: {
sourceMap: true,
lessOptions: {
javascriptEnabled: true,
},
},
},
],
}
);
config.plugins.push(
new MiniCssExtractPlugin({
filename: 'static/css/[name].css',
chunkFilename: 'static/css/[contenthash].css',
})
);
return config;
},
};
package.json
:
"dependencies": {
"@next/font": "13.1.1",
"css-loader": "^6.7.3",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"mini-css-extract-plugin": "^2.7.2",
"next": "13.1.1",
"next-transpile-modules": "^10.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"sass": "^1.57.1",
"sass-loader": "^13.2.0",
}
Upvotes: 0
Reputation: 869
Edit: This answer is definitely outdated for current versions of next.js, check the other answers below.
After multiple hours of research I found now finally the right solution and wanted to share it:
.babelrc
(no magic here)
{
"presets": ["next/babel"],
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": true
}
]
]
}
next.config.js
:
/* eslint-disable */
const withLess = require('@zeit/next-less');
const withSass = require('@zeit/next-sass');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './assets/antd-custom.less'), 'utf8')
);
module.exports = withSass({
cssModules: true,
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
importLoaders: 0
},
cssLoaderOptions: {
importLoaders: 3,
localIdentName: '[local]___[hash:base64:5]'
},
webpack: (config, { isServer }) => {
//Make Ant styles work with less
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === 'function') {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === 'function' ? [] : origExternals)
];
config.module.rules.unshift({
test: antStyles,
use: 'null-loader'
});
}
return config;
}
})
});
The final hint how to write the withSass
withLess
use and to put the cssModules: true
in the outer object came from this comment here.
While I was already trying different combinations derived from the examples before: next+ant+less next+sass
For completion here the dependencies in my package.json
:
...
"dependencies": {
"@zeit/next-less": "^1.0.1",
"@zeit/next-sass": "^1.0.1",
"antd": "^4.1.3",
"babel-plugin-import": "^1.13.0",
"less": "^3.11.1",
"less-vars-to-js": "^1.3.0",
"next": "^9.3.4",
"node-sass": "^4.13.1",
"null-loader": "^3.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"sass": "^1.26.3"
}
...
I hope this helps other people to find this solution faster. :)
Upvotes: 40
Reputation: 21
In our project, there were old scss and css files. They were not using the Next js guidline for CSS modules. So I had to override webpack.config.js. So that works fine. But when we moved the file to the monorepo shared package, babel was not transpiling them. I used the below things, but those did not work for SCSS modules without a .module extension.
{ externalDir: true, }
in next Js config with root babel.cofig.jsonFinally symlink hack worked for external shared files
Use symlinks for shared folder by updating next.config.js
module.exports = {
//...
resolve: {
symlinks: false,
},
};
Upvotes: 0
Reputation: 23
I am using elado's package which is - https://github.com/elado/next-with-less
you will need less
and less-loader
as dependencies.
after that create a global.less
file on styles
folder. so it's like ,root> style > global.less
and paste this code
@import '~antd/lib/style/themes/default.less';
@import '~antd/dist/antd.less';
@primary-color: #ff9b18;
@border-radius-base: 20px;
and add below code in your next.config.js
file which you will create on your root folder.
// next.config.js
const withLess = require("next-with-less");
module.exports = withLess({
lessLoaderOptions: {
/* ... */
},
});
Upvotes: 1
Reputation: 7489
While the above answers may work for versions of NextJS lower than 11, they do not work for 11+. I've found excellent success with the following plugin...
https://github.com/SolidZORO/next-plugin-antd-less
Upvotes: 9
Reputation: 8760
@zeit/next-less
is deprecated and disables Next's built in CSS support. It also uses a very old version of less
and less-loader
.
I created a package that injects Less support to Next.js by duplicating the SASS rules and setting them for Less files and less-loader
. It works with webpack5
flag.
https://github.com/elado/next-with-less
https://www.npmjs.com/package/next-with-less
Upvotes: 19