如何在CommonJS规范的Webpack配置中导入rehype-autolink-headings插件
解决CommonJS Webpack配置中导入ES模块rehype-autolink-headings的问题
你遇到的错误是因为rehype-autolink-headings是纯ES模块(ESM),而你的Webpack配置文件遵循CommonJS规范(用require导入),Node.js不允许在CommonJS文件中用require直接导入ES模块,因此触发ERR_REQUIRE_ESM报错。以下是三种可行的解决方法:
方法1:使用动态导入(import())
Webpack允许配置文件导出异步函数,因此可以在函数内部用动态加载ES模块:
- 删除配置文件顶部的
const rehype=require("rehype-autolink-headings")语句 - 修改导出的配置函数为异步函数,在内部导入插件并更新MDX loader配置:
module.exports = async () => { // 动态导入ES模块,取default导出 const rehypeAutolinkHeadings = (await import('rehype-autolink-headings')).default; const isProduction = process.env.NODE_ENV == "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; const config = { entry: "./src/index.tsx", output: { path: path.resolve(__dirname, "build"), publicPath: '/' }, devServer: { open: true, host: "localhost", historyApiFallback: true }, plugins: [ new HtmlWebpackPlugin({ template: "index.html", }), new CopyPlugin({ patterns: [ { from: "public", to: "./" }, ], }), ], module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"], }, { test: /\.(ts|tsx)$/, loader: "ts-loader", }, { test: /\.mdx?$/, use: [ { loader: '@mdx-js/loader', options: { rehypePlugins: [rehypeAutolinkHeadings], } } ] }, { test: /\.css$/i, use: [stylesHandler, "css-loader"], }, { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, ], }, resolve: { extensions: [".tsx", ".ts", ".jsx", ".js", "..."], }, }; if (isProduction) { config.mode = "production"; config.plugins.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } return config; };
方法2:将Webpack配置文件改为ES模块
把配置文件后缀改为.mjs(即webpack.config.mjs),改用import语句导入所有依赖:
import path from "path"; import HtmlWebpackPlugin from "html-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; import CopyPlugin from "copy-webpack-plugin"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; const isProduction = process.env.NODE_ENV == "production"; const stylesHandler = isProduction ? MiniCssExtractPlugin.loader : "style-loader"; const config = { // 原配置内容完全不变,仅导入方式改为ES模块语法 entry: "./src/index.tsx", output: { path: path.resolve(__dirname, "build"), publicPath: '/' }, devServer: { open: true, host: "localhost", historyApiFallback: true }, plugins: [ new HtmlWebpackPlugin({ template: "index.html", }), new CopyPlugin({ patterns: [ { from: "public", to: "./" }, ], }), ], module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"], }, { test: /\.(ts|tsx)$/, loader: "ts-loader", }, { test: /\.mdx?$/, use: [ { loader: '@mdx-js/loader', options: { rehypePlugins: [rehypeAutolinkHeadings], } } ] }, { test: /\.css$/i, use: [stylesHandler, "css-loader"], }, { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", }, ], }, resolve: { extensions: [".tsx", ".ts", ".jsx", ".js", "..."], }, }; export default () => { if (isProduction) { config.mode = "production"; config.plugins.push(new MiniCssExtractPlugin()); } else { config.mode = "development"; } return config; };
若Webpack未自动识别.mjs配置文件,可手动指定:
webpack --config webpack.config.mjs
方法3:降级插件到支持CommonJS的版本
rehype-autolink-headings v5及以上版本改为纯ES模块,v4版本仍支持CommonJS,可降级安装:
npm install rehype-autolink-headings@4 --save-dev
安装完成后,即可继续用原有的require语句导入插件:
const rehype = require("rehype-autolink-headings");
方案对比
- 动态导入:无需修改文件格式,侵入性低,适合快速解决问题
- 改为ES模块:符合现代JS规范,是长期趋势,但需要调整所有导入语法
- 降级版本:操作最简单,但会错过插件后续的功能更新和bug修复
内容的提问来源于stack exchange,提问作者captain-yossarian from Ukraine
相关产品推荐
相关产品推荐

