'NextJs build fail for webpack | Monaco editor
Description of the bug
1.Monaco editor running properly in dev server, but I have to import it dynamicly to turn ssr off; but Its emmiting a warning, But its running in dev despite of that error.
error - unhandledRejection: SyntaxError: Cannot use import statement outside a module
2.Second when I run npm run build its showing conflict webpack error.
Failed to compile.
Conflict: Multiple assets emit different content to the same filename ../main.js.nft.json
Conflict: Multiple assets emit different content to the same filename ../main.js.nft.json
Conflict: Multiple assets emit different content to the same filename ../main.js.nft.json
Conflict: Multiple assets emit different content to the same filename ../main.js.nft.json
> Build failed because of webpack errors
My next.config.js file:
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
const withTM = require("next-transpile-modules")([
// `monaco-editor` isn't published to npm correctly: it includes both CSS
// imports and non-Node friendly syntax, so it needs to be compiled.
"monaco-editor",
]);
module.exports = withTM({
webpack: (config) => {
const rule = config.module.rules
.find((rule) => rule.oneOf)
.oneOf.find(
(r) =>
// Find the global CSS loader
r.issuer && r.issuer.include && r.issuer.include.includes("_app")
);
if (rule) {
rule.issuer.include = [
rule.issuer.include,
// Allow `monaco-editor` to import global CSS:
/[\\/]node_modules[\\/]monaco-editor[\\/]/,
];
}
config.plugins.push(
new MonacoWebpackPlugin({
languages: [
"json",
"markdown",
"css",
"typescript",
"javascript",
"html",
"graphql",
"python",
"scss",
"yaml",
],
filename: "static/[name].worker.js",
})
);
return config;
},
});
This is my editor.js page in nextjs
import React, { useEffect } from "react";
import dynamic from "next/dynamic";
const MonacoEditor = dynamic(import("react-monaco-editor"), { ssr: false });
import DrawerWrapper from "../components/wrapperRoutes/DrawerWrapper";
import RestrictedForMobile from "../components/restricted/forMobile";
const App = () => {
const [iframeSrc, setIframeSrc] = React.useState("");
const [html, setHtml] = React.useState('');
const [css, setCss] = React.useState('');
const [js, setJs] = React.useState('');
//useEffect to render iframe output in every 600ms
useEffect(() => {
const timeout = setTimeout(() => {
setIframeSrc(`
<head><link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>${html}</body>
<style>${css}</style>
<script>${js}</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.24.0/axios.min.js"></script>
`);
}, 600);
return () => clearTimeout(timeout);
}, [html, css, js]);
return (
<>
<DrawerWrapper>
<div className="block lg:hidden">
<RestrictedForMobile />
</div>
<div className="hidden lg:block">
<div className=" w-full bg-coolGray-900 flex justify-between align-center items-center overflow-visible ">
<div className="ml-3">
<p className="bg-secondary mt-1 text-center text-gray-50 rounded-t-lg">
HTML
</p>
<MonacoEditor
width="32vw"
height="400"
language="html"
theme="hc-black"
value={html}
options={{
minimap: {
enabled: false,
},
}}
onChange={setHtml}
/>
</div>
<div className=" flex-shrink-0">
<p className="bg-secondary mt-1 text-center text-gray-50 rounded-t-lg">
CSS
</p>
<MonacoEditor
width="32vw"
height="400"
className="shadow-md"
language="css"
theme="hc-black"
value={css}
options={{
minimap: {
enabled: false,
},
}}
onChange={setCss}
/>
</div>
<div className="mr-3 flex-shrink-0">
<p className="bg-secondary mt-1 text-center text-gray-50 rounded-t-lg">
JS
</p>
<MonacoEditor
width="32vw"
height="400"
language="javascript"
theme="hc-black"
value={js}
options={{
minimap: {
enabled: false,
},
}}
onChange={setJs}
/>
</div>
</div>
{/* <div className="text-gray-400 divider">Output [screen : 100vh]</div> */}
<iframe
srcDoc={iframeSrc}
frameBorder="0"
sandbox="allow-scripts allow-forms"
className="overflow-scroll h-screen border-t-4 border-b-4 -mb-6 border-secondary"
width="100%"
height="100%"
/>
</div>
</DrawerWrapper>
</>
);
};
export default App;
Environment:
- OS: Apple Macbook Air M1, Monterey
- Browser: Chrome
Please Help . Thank You ❤️
Solution 1:[1]
In addition to excluding the server from the dynamic import (which you've done with { ssr: false }), you'll also need to exclude it when the MonacoWebpackPlugin is created. The webpack function in next.config.js will get called twice -- once for server-side compilation, once more for client-side compilation. When running next build, the error you're seeing happens during server-side compilation, so limit the MonacoWebpackPlugin to the client side:
// next.config.js
// ...
module.exports = withTM({
webpack: (config, options) => { // add `options` parameter
// ...
if (!options.isServer) { // run only for client side
config.plugins.push(
new MonacoWebpackPlugin({
// ...
})
);
}
return config;
},
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
