Closed dukesx closed 3 years ago
Hi @dukesx,
The react-ace
is going to be deprecated soon: https://elastic.github.io/eui/#/editors-syntax/code-editor. I guess once we deprecate it will make it easier to update our starter to Next JS 11.
But recently, in a different project, I was also struggling to make EUI work in Next JS 11. This was my solution to exclude react-ace (next.config.js
):
const path = require('path');
module.exports = {
reactStrictMode: true,
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
config.resolve.alias = {
...config.resolve.alias,
// we don't want to load react-ace because it gives the error `window is not defined`
[path.resolve(__dirname, './node_modules/react-ace')]: false,
};
config.resolve.mainFields = ['module', 'main'];
return config;
},
};
Let me know if that worked! 🙂
Hi @dukesx,
The
react-ace
is going to be deprecated soon: https://elastic.github.io/eui/#/editors-syntax/code-editor. I guess once we deprecate it will make it easier to update our starter to Next JS 11.But recently, in a different project, I was also struggling to make EUI work in Next JS 11. This was my solution to exclude react-ace (
next.config.js
):const path = require('path'); module.exports = { reactStrictMode: true, webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => { config.resolve.alias = { ...config.resolve.alias, // we don't want to load react-ace because it gives the error `window is not defined` [path.resolve(__dirname, './node_modules/react-ace')]: false, }; config.resolve.mainFields = ['module', 'main']; return config; }, };
Let me know if that worked! 🙂
Thank you, this resolves the React Ace issue, but now, another issue has popped up, please check the code below:
ReferenceError: HTMLElement is not defined at EuiPopover.render (C:\Users\Username\Desktop\my-eui-starter\.next\server\pages\_app.js:58710:30) at processChild (C:\Users\Username\Desktop\my-eui-starter\node_modules\react-dom\cjs\react-dom-server.node.development.js:3450:18) at resolve (C:\Users\Username\Desktop\my-eui-starter\node_modules\react-dom\cjs\react-dom-server.node.development.js:3270:5)
From what i have seen in debugging, the error is coming from "Chrome" named custom component, included in starter. It does not seem to inhabit "popover" element as stated in the log but the issue is gone if i remove the "Chrome" component. I suppose there is a EUI component in it that is causing this.
Update After Few Mins: My bad, Chrome houses a Theme Switcher that uses POPOVER as Select box to switch between themes. The error is coming from there.
Problem file: eui.d.ts it mentions HTMLELEMENT as ref type
Help anyone??
EUI is meant to be used on client side and NextJS is used for server side rendering. So the HTMLElement
doesn't exist on server side. That's the issue you're running. 🙂
I suggest you look into our next.config.js
and try to translate what is done there into Webpack 5.
This part of the config might help you: https://github.com/elastic/next-eui-starter/blob/5e4414e2b46cac1277fe697e0c57cf9d71e2aeff/next.config.js#L87-L96
Or you can also turn off the Webpack 5 (in NextJS 11): https://nextjs.org/docs/messages/webpack5
I'm closing this issue because we're our starter doesn't support Webpack 5 and NextJS 11, so we can't give proper support for these types of questions.
I haven't run next-eui-starter
itself, but I took parts of webpack config. It was working with webpack 4 and not working with webpack 5 until I've found out that externals
have different definitions.
Just fixing externals made it work with version 5 and nextjs 11.
if (isServer) {
config.externals = config.externals.map((fn) => (ctx, callback) => {
if (typeof fn !== 'function') {
return fn;
}
if (
ctx.request.includes('@elastic/eui') ||
ctx.request.includes('react-ace')
) {
return callback();
}
return fn(ctx, callback);
});
// Mock react-ace server-side
config.module.rules.push({
test: /react-ace/,
use: 'null-loader',
});
// Mock HTMLElement and window server-side
const definePluginId = config.plugins.findIndex(
(p) => p.constructor.name === 'DefinePlugin',
);
config.plugins[definePluginId].definitions = {
...config.plugins[definePluginId].definitions,
// eslint-disable-next-line object-shorthand
HTMLElement: function () {}, // I've no idea why but using shorthand leads to webpack error
// eslint-disable-next-line object-shorthand
window: function () {},
};
}
Or externals handler might look like this if you want to switch between v4 and v5 easily:
config.externals = config.externals.map((fn) => (...args) => {
if (typeof fn !== 'function') {
return fn;
}
if (args.length === 2) {
// webpack 5
const [ctx, callback] = args;
if (
ctx.request.includes('@elastic/eui') ||
ctx.request.includes('react-ace')
) {
return callback();
}
return fn(ctx, callback);
} else {
// webpack 4
const [context, request, callback] = args;
if (
request.includes('@elastic/eui') ||
request.includes('react-ace')
) {
return callback();
}
return fn(context, request, callback);
}
});
I am struggling here to make it work with the latest from Next js. I just don't get how i can migrate next.config.js to webpack 5. Nothing works. tried all the syntax and functions to exclude React Ace but it just doesn't works. Any help would be greatly appreciated.