Configure multiple next plugins: withMDX, withBundleAnalyzer - reactjs

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
}))

Related

Reacr Single SPA Micro frontend executes old scripts after a fresh deployment

We are migrating a standalone React.js application into micro frontend architecture using the library react-single-spa https://single-spa.js.org/docs/ecosystem-react/
We noticed a problem that after a new deployment to any micro-frontend app, the Single SPA was still loading the old code. I assume it is because, the browser caches the scrips . Is there's a way to make sure latest version of the code is being used ? Or is there a sample on how to implement this?
Below is my current webpack configs.
root-config
const { merge } = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = (webpackConfigEnv, argv) => {
const orgName = "my-org";
const defaultConfig = singleSpaDefaults({
orgName,
projectName: "root-config",
webpackConfigEnv,
argv,
disableHtmlGeneration: true,
});
return merge(defaultConfig, {
plugins: [
new HtmlWebpackPlugin({
inject: false,
template: "src/index.ejs",
templateParameters: {
isLocal: webpackConfigEnv && webpackConfigEnv.isLocal,
orgName,
},
}),
],
});
};
app-config
const { merge } = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa-react");
const path = require("path");
module.exports = (webpackConfigEnv, argv) => {
const defaultConfig = singleSpaDefaults({
orgName: "my-org",
projectName: "my-app",
webpackConfigEnv,
argv,
});
return merge(defaultConfig, {
resolve: {
fallback: {
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify")
},
extensions: ['.ts', '.js', 'mjs', '.tsx'],
alias: {
src: path.resolve(__dirname, 'src'),
}
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
{
test: /\.(woff|woff2|ttf|eot)$/,
use: 'file-loader?name=fonts/[name].[ext]!static'
}
]
}
});
};
Appreciate any help. Thank you !

Storybook can't process TS files outside of the project

I have noticed that Storybook can't process Typescript files if they are from another project (monorepo), but it is doing okay with TS files that are within its project.
How do I configure Storybook to handle TS files outside the project?
Structure of the monorepo:
package1
.storybook
main.ts
preview.ts
component.tsx (this component imports file.ts)
component.stories.tsx
package2
file.ts <- (Storybook can't process this file: ModuleParseError: Module parse failed: Unexpected token)
Here is the main.ts config file:
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const path = require('path');
const toPath = (filePath) => path.join(process.cwd(), filePath);
module.exports = {
"stories": [
"../src/**/*.stories.#(mdx|js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-interactions",
"#storybook/addon-knobs/register",
"#storybook/preset-create-react-app",
"#storybook/addon-a11y",
'storybook-addon-styled-component-theme/dist/preset',
'storybook-addon-themes',
"storybook-dark-mode",
],
"framework": "#storybook/react",
"core": {
"builder": "#storybook/builder-webpack5",
"disableTelemetry": true,
},
features: {
emotionAlias: false,
},
typescript: { reactDocgen: false },
webpackFinal: async (config, { configType }) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'#emotion/core': toPath('node_modules/#emotion/react'),
'emotion-theming': toPath('node_modules/#emotion/react'),
},
plugins: [new TsconfigPathsPlugin()]
},
}
}
}
Here is the error:
ModuleParseError: Module parse failed: Unexpected token (7:11)
File was processed with these loaders:
* ../../node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
You may need an additional loader to handle the result of these loaders.
| import { Palette as palette } from '../Palette';
|
> const Paper: any = [
| {
If I import the same TS file, but manually precompiled into regular JS - Storybook works.
I have no idea what to try to solve this :(
Add this to .storybook/main.js
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Storybook uses its own webpack config, so we need to merge our config with it
// See https://storybook.js.org/docs/configurations/custom-webpack-config/
// Add typescript loader to process TS-files from other packages
config.module.rules.push({
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve("ts-loader"),
options: {
reportFiles: [
"../**/src/**/*.{ts,tsx}"
]
}
},
]
});
config.resolve.extensions.push(".ts", ".tsx");
return config;
}

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.

Nextjs Error: Must use import to load ES Module

Hi i am creating a project using nextjs and reactjs ,i am facing an issue, when I am trying to import datetime from npm date-time package ,its throwing this error.I am using this npm package https://www.npmjs.com/package/date-time. The error in my code is shown in the picture attached
This is my next.config.js what i need to
const path = require("path");
const withCss = require("#zeit/next-css");
const withSass = require("#zeit/next-sass");
const withImages = require("next-images");
module.exports = withImages(
withSass(
withCss({
webpack: (config, { isServer }) => {
if (isServer) {
config.module.rules.push({
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: "url-loader",
options: {
limit: 100000,
name: "[name].[ext]",
},
},
});
}
return config;
},
cssLoaderOptions: {
url: false,
},
})
)
);

Updating nextjs from 8 to 9.3.3 broke styling

I just updated nextjs from 8 to 9.3.3, and some of my styling broke.
Previously I was importing .scss files and they were locally scoped to their respective components.
After updating to 9.3.3, it seems that components with classNames that are named the same are now sharing styles, so that leads me to believe that something with the sass-loader or css-loader in next.config.js seems off.
this is my next.config.js
const path = require('path');
const dotenv = require('dotenv');
const withSass = require('#zeit/next-sass');
const webpack = require('webpack');
const envConfig = dotenv.config();
const config = withSass({
cssModules : true,
cssLoaderOptions : {
modules : true,
sourceMap : true,
importLoaders : 1,
},
sassLoaderOptions: {
includePaths: [path.resolve(__dirname, './')], //eslint-disable-line
},
useFileSystemPublicRoutes: false,
webpack: (config, { buildId, dev, isServer, defaultLoaders }) => { // eslint-disable-line
const ENV = {};
for (let entry in envConfig.parsed) {
ENV[`process.env.${entry}`] = JSON.stringify(envConfig.parsed[entry]);
}
config.plugins.push(new webpack.DefinePlugin(ENV));
return config;
},
});
module.exports = config;
What I've tried
I've changing my config around like this:
const config = withSass({
cssModules : true,
cssLoaderOptions : {
modules : {
mode: 'local',
exportGlobals: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
context: path.resolve(__dirname, 'src'), //eslint-disable-line
hashPrefix: 'my-custom-hash',
},
sourceMap : true,
importLoaders : 1,
},
sassLoaderOptions: {
includePaths: [path.resolve(__dirname, './')], //eslint-disable-line
},
useFileSystemPublicRoutes: false,
webpack: (config, { buildId, dev, isServer, defaultLoaders }) => { // eslint-disable-line
const ENV = {};
for (let entry in envConfig.parsed) {
ENV[`process.env.${entry}`] = JSON.stringify(envConfig.parsed[entry]);
}
config.plugins.push(new webpack.DefinePlugin(ENV));
return config;
},
});
module.exports = config;
which didn't work.
My last resort which does work is manually going into each .scss file and changing them to x.module.scss, which would take a lot of time going into each file. Is there something wrong with my config?

Resources