Webpack 5 で node: プレフィックスの付いた import を解決する
#Next.js #Webpack
Webpack 5 以降では Node.js のコアモジュールはデフォルトで polyfill されなくなりました
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.
このため、対応する polyfill を自分で解決する、あるいは node-polyfill-webpack-plugin - npm などを利用する必要があります
code:next.config.ts
const nextConfig: NextConfig = {
webpack: (config, {isServer}) => {
if (!isServer) {
config.resolve.fallback'events' = require.resolve('events')
// 別途 events などを依存関係に追加する必要がある
}
return config
}
}
export default nextConfig
code:next.config.ts
const nextConfig: NextConfig = {
webpack: (config, {isServer}) => {
if (!isServer) {
config.plugins.push(new NodePolyfillWebpackPlugin())
}
return config
}
}
export default nextConfig
ところが、import { EventEmitter } from 'node:events' のように node: プレフィックスの付いたモジュール名で import している場合、上記の方法ではモジュールを解決することはできません
code:error
Failed to compile.
node:events
Module build failed: UnhandledSchemeError: Reading from "node:events" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.
解決方法
NormalModuleReplacementPlugin | webpack を利用することで解決できます
このプラグインはモジュールを解決する前に import 文を書き換えることができます
これを利用してまず node: プレフィックスを取り除きます
code:next.config.ts
import { NormalModuleReplacementPlugin } from 'webpack'
const nextConfig: NextConfig = {
webpack: (config, {isServer}) => {
if (!isServer) {
config.plugins.push(
new NormalModuleReplacementPlugin(/^node:/, (resource) => {
switch (resource.request) {
case 'node:events':
resource.request = 'events'
// import { EventEmitter } from 'events' に書き換えられる
break
default:
throw new Error(unknown module: ${module})
}
})
)
}
return config
}
}
export default nextConfig