How to configure nextjs 9 and ant design less compatibility? - reactjs

After upgrading react,react-dom and nextjs this error happens :
Build error occurred
/home/lenovo/.../node_modules/antd/lib/style/index.css:7
body {
^
SyntaxError: Unexpected token {
at Module._compile (internal/modules/cjs/loader.js:720:22)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:788:10)
at Module.load (internal/modules/cjs/loader.js:643:32) {
type: 'SyntaxError',
'$error': '$error'
}
events.js:180
throw er; // Unhandled 'error' event
^
Error: write EPIPE
...
at processTicksAndRejections (internal/process/task_queues.js:77:11)
Emitted 'error' event at:
at internal/child_process.js:810:39
at processTicksAndRejections (internal/process/task_queues.js:75:11) {
errno: 'EPIPE',
code: 'EPIPE',
syscall: 'write'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
This is my next.config.js:
const nextConfig = {
distDir: '_next',
onDemandEntries: {
maxInactiveAge: 1000 * 60 * 60,
pagesBufferLength: 5,
},
webpack: (config, { dev }) => {
!dev &&
config.plugins.push(
new BrotliPlugin({
asset: '[path].br[query]',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.7,
}),
);
!dev &&
config.plugins.push(
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.7,
}),
);
return config;
},
};
module.exports = withPlugins(
[
[withImages],
[withCss],
[
withSass,
{
cssModules: true,
cssLoaderOptions: {
localIdentName: '[path]___[local]___[hash:base64:5]',
},
},
],
[withBundleAnalyzer],
],
nextConfig,
);
Do you know what is wrong with this?
Edit
It seems there is a compatibility problem with ant design and I found some sources but not get it though!

Based on this example in the Next.js repository
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design
To resolve this problem, add these lines to your next.config.js:
const nextConfig = {
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style\/css.*?/;
const origExternals = [...config.externals];
config.externals = [ // eslint-disable-line
(context, request, callback) => { // eslint-disable-line
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;
},
};
An example of what the next.config.js file would look like:
const withPlugins = require('next-compose-plugins');
const withCss = require('#zeit/next-css');
const withSass = require('#zeit/next-sass');
if (typeof require !== 'undefined') {
require.extensions['.css'] = file => {};
}
const nextConfig = {
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style\/css.*?/;
const origExternals = [...config.externals];
config.externals = [ // eslint-disable-line
(context, request, callback) => { // eslint-disable-line
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;
},
};
module.exports = withPlugins(
[
[withCss],
[
withSass,
{
cssModules: true,
cssLoaderOptions: {
localIdentName: '[path]___[local]___[hash:base64:5]',
},
},
],
],
nextConfig,
);

Related

Tailwind `#apply` utility not working in storybook

#apply utility is being compiled to normal CSS and is flagged as invalid syntax in storybook
Here's my main.js
// .storybook/main.js
const path = require("path");
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.#(js|jsx|ts|tsx)"],
staticDirs: ["../public"],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/preset-scss",
{
name: "#storybook/addon-postcss",
options: {
postcssLoaderOptions: {
implementation: require("postcss"),
},
},
},
],
webpackFinal: async (config) => {
const rules = config.module.rules;
const fileLoaderRule = rules.find((rule) => {
return rule.test && rule.test.test(".svg");
});
fileLoaderRule.exclude = /\.svg$/;
rules.push({
test: /\.svg$/,
use: ["#svgr/webpack"],
});
return config;
},
core: {
builder: "#storybook/builder-webpack5",
},
framework: "#storybook/react",
};
Here's my preview.js
import * as NextImage from "next/image";
import "../src/styles/globals.scss";
const OriginalNextImage = NextImage.default;
Object.defineProperty(NextImage, "default", {
configurable: true,
value: (props) => <OriginalNextImage {...props} unoptimized />,
});
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
previewTabs: {
"storybook/docs/panel": { index: -1 },
},
};
Here's my postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

Antd and webpack5 configuration problem in nextjs

I have problem with configuring antd in nextjs version 12.0.8. I know i can fix this with downgrading webpack to version 4 but its necessary for me to use webpack 5.
antd version: 4.18.3
Webpack version: 5.65.0
nextjs version: 12.0.8
Here is my next config:
module.exports = withImages({...withFonts({
...withCss({
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
importLoaders: 0
},
cssLoaderOptions: {
importLoaders: 3,
localIdentName: '[local]___[hash:base64:5]'
},
// webpack5: false,
webpack: (config, {isServer}) => {
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'
});
}
// config.module.rules.push({
// test: /\.(png|jpe?g|gif)$/i,
// loader: 'file-loader'
// })
return config;
}
})
})
})
});
But i got this error:
TypeError: Cannot set property 'styles' of undefined
at module.exports (/home/sajjad/Project/pishrun-frontend/node_modules/#zeit/next-css/css-loader-config.js:25:56)
at Object.webpack (/home/sajjad/Project/pishrun-frontend/node_modules/#zeit/next-css/index.js:15:36)
at Object.webpack (/home/sajjad/Project/pishrun-frontend/node_modules/next-fonts/index.js:42:27)
at Object.webpack (/home/sajjad/Project/pishrun-frontend/node_modules/next-images/index.js:63:27)
at Object.getBaseWebpackConfig [as default] (/home/sajjad/Project/pishrun-frontend/node_modules/next/dist/build/webpack-config.js:1390:32)
at async Promise.all (index 0)
at async Span.traceAsyncFn (/home/sajjad/Project/pishrun-frontend/node_modules/next/dist/trace/trace.js:75:20)
at async Span.traceAsyncFn (/home/sajjad/Project/pishrun-frontend/node_modules/next/dist/trace/trace.js:75:20)
at async HotReloader.start (/home/sajjad/Project/pishrun-frontend/node_modules/next/dist/server/dev/hot-reloader.js:329:25)
at async DevServer.prepare (/home/sajjad/Project/pishrun-frontend/node_modules/next/dist/server/dev/next-dev-server.js:295:9)
Thanks for your help.

Configure multiple next plugins: withMDX, withBundleAnalyzer

I started a nextjs site with a tailwind blog starter that already comes with withBundleAnalyzer in next.config.js.
I am now trying to get .mdx files to work from the pages directly. Documentation says I need withMDX in my nextjs.config file. How do I get the two to play together? Should I only keep one or the other? I have installed next-compose-plugins but not sure how to set it all up.
Update
This is my next config file; it's still failing. Error:
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
TypeError: undefined is not a function
at _withPlugins (/home/xxx/xxx/nodeapps/my-web/node_modules/next-compose-plugins/lib/index.js:17:22)
at Object.<anonymous> (/home/xxx/xxx/nodeapps/my-web/next.config.js:11:18)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at loadConfig (/home/xxx/xxx/nodeapps/my-web/node_modules/next/dist/next-server/server/config.js:8:94)
at async NextServer.loadConfig (/home/xxx/xxx/nodeapps/my-web/node_modules/next/dist/server/next.js:1:2962)
const withPlugins = require('next-compose-plugins')
const withMDX = require('#next/mdx')({
extension: /\.mdx$/,
})
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withPlugins(
withMDX(
withBundleAnalyzer({
pageExtensions: ['js', 'jsx', 'md', 'mdx'],
future: {
webpack5: true,
},
webpack: (config, { dev, isServer }) => {
config.module.rules.push({
test: /\.(png|jpe?g|gif|mp4)$/i,
use: [
{
loader: 'file-loader',
options: {
publicPath: '/_next',
name: 'static/media/[name].[hash].[ext]',
},
},
],
})
config.module.rules.push({
test: /\.svg$/,
use: ['#svgr/webpack'],
})
if (!dev && !isServer) {
// Replace React with Preact only in client production build
Object.assign(config.resolve.alias, {
react: 'preact/compat',
'react-dom/test-utils': 'preact/test-utils',
'react-dom': 'preact/compat',
})
}
return config
},
})
)
)
As you mentioned you can use next-compose-plugins like this
const withPlugins = require('next-compose-plugins');
const withMDX = require('#next/mdx');
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withPlugins([
// add a plugin with specific configuration
[withMDX, {
// MDX plugin specific options
}],
// add it like this if no plugin configuration is needed
[withBundleAnalyzer],
]);
EDIT:
Here is your complete config file:
const withPlugins = require("next-compose-plugins");
const withMDX = require("#next/mdx")({
extension: /\.mdx?$/,
});
const withBundleAnalyzer = require("#next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
module.exports = withPlugins([[withBundleAnalyzer], [withMDX]], {
pageExtensions: ["js", "jsx", "md", "mdx"],
future: {
webpack5: true,
},
webpack: (config, { dev, isServer }) => {
config.module.rules.push({
test: /\.(png|jpe?g|gif|mp4)$/i,
use: [
{
loader: "file-loader",
options: {
publicPath: "/_next",
name: "static/media/[name].[hash].[ext]",
},
},
],
});
config.module.rules.push({
test: /\.svg$/,
use: ["#svgr/webpack"],
});
if (!dev && !isServer) {
// Replace React with Preact only in client production build
Object.assign(config.resolve.alias, {
react: "preact/compat",
"react-dom/test-utils": "preact/test-utils",
"react-dom": "preact/compat",
});
}
return config;
},
});
You can setup the config without using next-compose-plugins as well.
const withMDX = require('#next/mdx')({
extension: /\.mdx$/,
})
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withMDX(withBundleAnalyzer({
// Your Next.js configs, including withMDX-specific options
}))

Webpack build failing on upgrading Nextjs to v10 from v9

I'm quite new to frontend technologies. I tried Next.js v9.x.x and anyhow configured next.config.js to support less as well as .css files as AntDesign needed it which I'm using in the project. Here is thenext.config.js file which perfectly worked with Next.js-v9.x.x:
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './assets/theme.less'), 'utf8'),
);
const plugins = [
[withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
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',
});
}
const builtInLoader = config.module.rules.find((rule) => {
if (rule.oneOf) {
return (
rule.oneOf.find((deepRule) => deepRule.test && deepRule.test.toString().includes('/a^/')) !== undefined
);
}
return false;
});
if (typeof builtInLoader !== 'undefined') {
config.module.rules.push({
oneOf: [
...builtInLoader.oneOf.filter((rule) => (rule.test && rule.test.toString().includes('/a^/')) !== true),
],
});
}
config.resolve.alias['#'] = path.resolve(__dirname);
// SVGs loading
config.module.rules.push({
test: /\.svg$/,
issuer: {
test: /\.(js|ts)x?$/,
},
use: ['#svgr/webpack'],
});
return config;
},
})],
];
module.exports = withPlugins(plugins, nextConfig);
I just found that a major version (10.x.x) released by Next.js. I upgraded the project and the build started failing with:
Failed to compile.
Error: No module factory available for dependency type: CssDependency
> Build error occurred
Error: > Build failed because of webpack errors
at build (/Users/ss/Projects/Test/Frontend/node_modules/next/dist/build/index.js:15:918)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
Tried finding solutions online and found here that a missing mini-css-extract-plugin configuration might raise this error. I was confused as the same was working earlier so thought that they removed this dependency in the latest release but couldn't find any issue raised for this in their Github repo.
On debugging the project, I also found that mini-css-extract-plugin was missing in package-lock.json > "next" > "requires" section in v10.x.x while it was there in v9.x.x
Now I'm confused about how to re-configure the next.config.js for my case as I couldn't find any solutions online.
Can anyone please check? Any help would be appreciated. Thanks in advance.
I had the same issue, I fixed it by splitting the plugin to look like this:
module.exports = withPlugins([[
withLess, {
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
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',
});
}
const builtInLoader = config.module.rules.find((rule) => {
if (rule.oneOf) {
return (
rule.oneOf.find((deepRule) => deepRule.test && deepRule.test.toString().includes('/a^/')) !== undefined
);
}
return false;
});
if (typeof builtInLoader !== 'undefined') {
config.module.rules.push({
oneOf: [
...builtInLoader.oneOf.filter((rule) => (rule.test && rule.test.toString().includes('/a^/')) !== true),
],
});
}
config.resolve.alias['#'] = path.resolve(__dirname);
// SVGs loading
config.module.rules.push({
test: /\.svg$/,
issuer: {
test: /\.(js|ts)x?$/,
},
use: ['#svgr/webpack'],
});
return config;
},
}]], nextConfig);
If this doesn't help, you can use this package next-plugin-antd-less
Using it with next-compose-plugins you'll have to follow the same structure as the above.
module.exports = withPlugins([
[
withAntdLess,
{
lessVarsFilePath: "./assets/theme.less",
},
],
])

How to config Ant Design in Next.js with custom theme & support CSS Module feature

I'm building a ReactJs project base on SSR ( using Next.js ) with Ant Design. But after I customize next.config.js config for support Ant Design, I can't use CSS Module feature.
Next.js supports CSS Modules using the [name].module.css file naming
convention
Here are my configure files:
next.config.js
require('dotenv').config();
const lessToJS = require('less-vars-to-js')
const fs = require('fs')
const path = require('path');
const withSass = require('#zeit/next-sass');
const withLess = require('#zeit/next-less');
const withCSS = require('#zeit/next-css');
const withPlugins = require('next-compose-plugins');
// Where your antd-custom.less file lives
const themeVariables = lessToJS(fs.readFileSync(path.resolve(__dirname, './css/antd.less'), 'utf8'));
const nextConfig = {
env: {
spaceID: process.env.spaceID,
accessTokenDelivery: process.env.accessTokenDelivery,
},
distDir: '.next',
};
const plugins = [
withCSS,
withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables,
},
webpack: (config, { isServer }) => {
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;
},
}),
withSass,
];
module.exports = withPlugins(plugins, nextConfig);
pages/index.tsx:
import headerStyled from '../components/Header.module.css'
export default () => {
return (
<>
<div className={headerStyled.appc}>
Hello World
</div>
</>
)
}
Here is my test project on github ( you can clone & see these configs )
https://github.com/thobn24h/nextjs-with-ant.git
When I run yarn dev to build project --> I got error:
./components/Header.module.css 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> .appc {
| color: #fff;
| background: #16191e;
Here are my dependencies:
"dependencies": {
"#zeit/next-css": "^1.0.1",
"#zeit/next-less": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^4.4.0",
"dotenv": "^8.2.0",
"less": "^3.11.3",
"less-vars-to-js": "^1.3.0",
"next": "^9.4.4",
"next-compose-plugins": "^2.2.0",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"#types/node": "^14.0.14",
"#types/react": "^16.9.41",
"typescript": "^3.9.6"
},
Please show me how to correct this configurations to run Next.js project with Ant Design support & still support CSS Modules
Thank you!
Thank you Sumit Sarkar (#sumitsarkar01) was helped me config the next.config.js,
And now, It work correctly!
const withLess = require('#zeit/next-less')
const lessToJS = require('less-vars-to-js')
const withPlugins = require('next-compose-plugins')
const fs = require('fs')
const path = require('path')
const dotenv = require('dotenv')
dotenv.config()
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, './css/antd.less'), 'utf8')
)
const plugins = [
[withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
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',
})
}
const builtInLoader = config.module.rules.find((rule) => {
if (rule.oneOf) {
return (
rule.oneOf.find((deepRule) => {
return deepRule.test && deepRule.test.toString().includes('/a^/');
}) !== undefined
);
}
return false;
});
if (typeof builtInLoader !== 'undefined') {
config.module.rules.push({
oneOf: [
...builtInLoader.oneOf.filter((rule) => {
return (rule.test && rule.test.toString().includes('/a^/')) !== true;
}),
],
});
}
config.resolve.alias['#'] = path.resolve(__dirname);
return config;
}
})]
]
const nextConfig = {
env: {
}
}
module.exports = withPlugins(plugins, nextConfig)
I was updated this config to my test project, you can check it out
[https://github.com/thobn24h/nextjs-with-ant][1]

Resources