React集成xterm.js生产环境报错,疑与Webpack配置相关
问题
React项目集成xterm.js后,开发环境正常运行,但生产环境代码崩溃,报错提示无法正确导入xterm,排查后确定问题出在生产环境Webpack配置,但未找到根因。
组件代码
import React, {useEffect} from 'react'; import {Terminal} from 'xterm'; import {FitAddon} from 'xterm-addon-fit'; const UITerminal = () => { const term = new Terminal(); const fitAddon = new FitAddon(); term.loadAddon(fitAddon); useEffect(() => { let termDocument = document.getElementById('terminal') if (termDocument) { term.open(termDocument) fitaddon.fit(); } window.addEventListener('resize', () => { fitaddon.fit(); }) }, []) return (<div id="terminal"></div>) }
生产环境报错信息
react_devtools_backend.js:4012 ReferenceError: Cannot access 'r' before initialization at new m (96209.72626fc1cc862aea477a.bundle.js:1:165467) at new b (96209.72626fc1cc862aea477a.bundle.js:1:159758) at new M (96209.72626fc1cc862aea477a.bundle.js:1:57572) at new r.exports.i.Terminal (96209.72626fc1cc862aea477a.bundle.js:1:294972) at w (96209.72626fc1cc862aea477a.bundle.js:1:15994) at zo (main.71e827eabc798023c129.bundle.js:1:1260000) at Ws (main.71e827eabc798023c129.bundle.js:1:1333492) at Wi (main.71e827eabc798023c129.bundle.js:1:1294411) at Ui (main.71e827eabc798023c129.bundle.js:1:1294336) at Pi (main.71e827eabc798023c129.bundle.js:1:1291367)
Webpack配置文件
webpack.dev.js
const fqdn = "some.fqdn.com" const path = require("path"); const webpack = require("webpack") const common = require("./webpack.common"); const { merge } = require("webpack-merge"); const fs = require('fs'); const jsonFormat = require('json-format'); var HtmlWebpackPlugin = require("html-webpack-plugin"); const jsonFromatConfig = { type: 'space', size: 4 } module.exports = merge(common, { mode: "development", devtool: "source-map", output: { filename: "bundle.js", publicPath: '/', }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html" }), new webpack.HotModuleReplacementPlugin() ], module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] } ] }, target: "web", devServer: { open: true, static: { directory: path.join(__dirname, '../public'), }, historyApiFallback: true, }, });
webpack.prod.js
const path = require("path"); const common = require("./webpack.common"); const { merge } = require("webpack-merge"); var MinifyPlugin = require('babel-minify-webpack-plugin') var CompressionPlugin = require('compression-webpack-plugin'); const CleanWebpackPlugin = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const TerserPlugin = require("terser-webpack-plugin"); var HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = merge(common, { mode: "production", output: { filename: "naming.[name].contenthash.[contenthash].bundle.js", path: path.resolve(__dirname, "../build") }, optimization: { minimizer: [ new TerserPlugin(), new HtmlWebpackPlugin( { template: "./public/index.html", minify: { removeAttributeQuotes: true, collapseWhitespace: true, removeComments: true } } ), new MinifyPlugin({}, { comments: false }) ], splitChunks: { chunks: 'all', minChunks: 3 } }, plugins: [ new CompressionPlugin({ test: /\.js$|\.css$|\.html$/ }), new MiniCssExtractPlugin({ filename: "naming.[name].contenthash.[contenthash].css" }), new CleanWebpackPlugin() ], module: { rules: [ { test: /\.css/i, use: [ MiniCssExtractPlugin.loader, "css-loader" ] }, ] } });
解决方案
1. 移除重复压缩插件
生产环境配置中同时启用TerserPlugin和babel-minify-webpack-plugin,两个JS压缩工具同时工作会导致代码混淆冲突,引发变量初始化顺序错误。保留TerserPlugin(Webpack5默认压缩工具,兼容性更好),移除babel-minify-webpack-plugin:
// 修改webpack.prod.js的optimization.minimizer optimization: { minimizer: [ new TerserPlugin(), new HtmlWebpackPlugin( { template: "./public/index.html", minify: { removeAttributeQuotes: true, collapseWhitespace: true, removeComments: true } } ) ], // 其他配置不变 }
2. 修复组件变量大小写错误
组件中fitAddon定义为驼峰命名,但useEffect内写成了小写fitaddon,生产环境压缩后会直接抛出错误,修正为:
useEffect(() => { let termDocument = document.getElementById('terminal') if (termDocument) { term.open(termDocument) fitAddon.fit(); // 修正为驼峰 } window.addEventListener('resize', () => { fitAddon.fit(); // 修正为驼峰 }) }, [])
3. 调整splitChunks配置
生产环境splitChunks.minChunks设为3,可能导致xterm相关代码被拆分到多个chunk,加载顺序出错。降低阈值或单独配置xterm拆分规则:
splitChunks: { chunks: 'all', minChunks: 1, cacheGroups: { xterm: { test: /[\\/]node_modules[\\/](xterm|xterm-addon-fit)[\\/]/, name: 'xterm-vendors', chunks: 'all' } } }
4. 导入xterm样式文件
xterm需要自身CSS支持,组件中缺少导入,添加:
import 'xterm/css/xterm.css';
内容的提问来源于stack exchange,提问作者Himanshu Arora
相关产品推荐
相关产品推荐

