next-with-less
next-with-less copied to clipboard
Doesn't work with NextJS 13
Versions
next-with-less: 2.0.5 less-loader: 11.1.0 less: 4.1.3 (dev dependency) next: 13.0.0 antd: 4.23.6
next.config.js
const withLess = require('next-with-less');
module.exports = withLess({
reactStrictMode: true,
swcMinify: true,
experimental: {
appDir: true,
}
});
Error Message
I'm importing the antd.less in my app/layout.tsx
file
Versions
next-with-less: 2.0.5 less-loader: 11.1.0 less: 4.1.3 (dev dependency) next: 13.0.0 antd: 4.23.6
next.config.js
const withLess = require('next-with-less'); module.exports = withLess({ reactStrictMode: true, swcMinify: true, experimental: { appDir: true, } });
Error Message
I'm importing the antd.less in my
app/layout.tsx
file
You can switch to this repo. Is working for me for /app dir :) https://github.com/SolidZORO/next-plugin-antd-less
You can switch to this repo. Is working for me for /app dir :) https://github.com/SolidZORO/next-plugin-antd-less
I kinda struggle on setting up the plugin with typescript:
Does anyone happen to have a working nextjs 13 (with app dir), typescript project on GitHub where I can take a look?
You can switch to this repo. Is working for me for /app dir :) https://github.com/SolidZORO/next-plugin-antd-less
Unfortunately this one doesn't work with SWC, so again not really working for me with Next 13...
I don't know which commit fixed the issue but next-with-less
is working in 13.1.1 now.
I don't know which commit fixed the issue but
next-with-less
is working in 13.1.1 now.
Although it is configured to use less
in 13.1.1, the configuration of nextjs
itself does not take effect.
Is there any recommended way to deal with it?
You can switch to this repo. Is working for me for /app dir :) https://github.com/SolidZORO/next-plugin-antd-less
Unfortunately this one doesn't work with SWC, so again not really working for me with Next 13...
Do you find the solution for nextjs 13 with app fold and SWC?
Not working with app folder
I had trouble getting this plugin to work with the app folder as well, and ended up extending the webpack config in next.config.js
to get LESS support:
webpack: (config) => {
config.module.rules.push({
test: /\.module\.less$/,
use: [
{
loader: require.resolve('style-loader'),
},
{
loader: require.resolve('css-loader'),
options: {
sourceMap: true,
modules: true,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
postcssOptions: {
sourceMap: true,
},
},
},
{
loader: require.resolve('less-loader'),
},
},
],
});
return config;
},
I edited the code to this and now it works for me. The code:
/**
* @function withLess
* @param {import('next').NextConfig} nextConfig
* @returns {import('next').NextConfig}
* */
function withLess(nextConfig) {
return Object.assign({}, nextConfig, {
/**
* @function webpack
* @type {import('next').NextConfig["webpack"]}
* @param {import('webpack').Configuration} config
* @returns {import('webpack').Configuration}
* */
webpack(config, opts) {
// there are 2 relevant sass rules in next.js - css modules and global css
let sassModuleRules = [];
// global sass rule (does not exist in server builds)
let sassGlobalRules = [];
const cssRule = config.module.rules.find(({ oneOf }) => !!oneOf).oneOf
const addLessToRuleTest = (test) => {
if (Array.isArray(test)) {
return test.map((rx) => addLessToRegExp(rx));
} else {
return addLessToRegExp(test);
}
};
cssRule.forEach((rule, i) => {
if (rule.use?.loader === 'error-loader') {
rule.test = addLessToRuleTest(rule.test);
} else if (rule.use?.loader?.includes('file-loader')) {
rule.issuer = addLessToRuleTest(rule.issuer);
} else if (rule.use?.includes?.('ignore-loader')) {
rule.test = addLessToRuleTest(rule.test);
} else if (rule.test?.source === '\\.module\\.(scss|sass)$') {
sassModuleRules.push(rule);
} else if (rule.test?.source === '(?<!\\.module)\\.(scss|sass)$') {
sassGlobalRules.push(rule);
} else if (rule.issuer?.source === "\\.(css|scss|sass)$" && rule.type === 'asset/resource') {
rule.issuer = addLessToRuleTest(rule.issuer);
} else if (rule.use?.loader?.includes('next-flight-css-loader')) {
rule.test = addLessToRuleTest(rule.test);
}
});
const lessLoader = {
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true,
},
},
};
let lessModuleRules = cloneDeep(sassModuleRules);
const configureLessRule = (rule) => {
rule.test = new RegExp(rule.test.source.replace('(scss|sass)', 'less'));
// replace sass-loader (last entry) with less-loader
rule.use.splice(-1, 1, lessLoader);
};
lessModuleRules.forEach((lessModuleRule, index) => {
configureLessRule(lessModuleRule);
cssRule.splice(cssRule.indexOf(sassModuleRules[index]) + 1, 0, lessModuleRule);
});
if (sassGlobalRules) {
let lessGlobalRules = cloneDeep(sassGlobalRules);
lessGlobalRules.forEach((lessGlobalRule, index) => {
configureLessRule(lessGlobalRule);
cssRule.splice(cssRule.indexOf(sassGlobalRules[index]) + 1, 0, lessGlobalRule);
});
}
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, opts);
}
return config;
},
});
}