ptm*_*mva 12 javascript reactjs webpack
我将 React 更新到 v18,每当热模块替换触发并注入新的 javascript 代码时,我的 Webpack 开发服务器都会出现控制台错误:
Warning: You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root. render() on the existing root instead if you want to update it.
index.js文件
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<App />);
if (module.hot) module.hot.accept(function (err) {
console.log('An error occurred while accepting new version');
});
Run Code Online (Sandbox Code Playgroud)
webpack.config.js
const path = require('path');
const HtmlWEbpackPlugin = require('html-webpack-plugin');
module.exports = (env) => {
let cfg = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.[contenthash:6].js',
publicPath: '/',
clean: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
]
},
plugins: [new HtmlWEbpackPlugin({ template: './src/index.html' })
],
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 3000,
hot: true,
open: true,
},
performance: {
hints: false
}
}
return cfg;
};
Run Code Online (Sandbox Code Playgroud)
sxk*_*xkx 19
React 18 原生支持热重载,这称为快速刷新。反应刷新自述文件的摘录:
快速刷新是一项功能,可让您在运行的应用程序中编辑 React 组件而不会丢失其状态。它类似于称为“热重载”的旧功能,但快速刷新更可靠并且受到 React 官方支持。
要在 Webpack 5 中使用它,您将需要一个名为react-refresh-webpack-plugin 的插件。为了让它工作,我建议查看 git 存储库中包含的示例,尤其是webpack-dev-server示例。
注意:在撰写此答案时,它react-refresh-webpack-plugin处于实验状态,但create-react-app已经在使用它,因此它可能足够稳定,可以使用。
以下内容直接取自react-refresh-webpack-plugin的示例webpack-dev-server:
src/index.js
import { createRoot } from 'react-dom/client';
import App from './App';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App />);
Run Code Online (Sandbox Code Playgroud)
webpack.config.js
const path = require('path');
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
mode: isDevelopment ? 'development' : 'production',
devServer: {
client: { overlay: false },
},
entry: {
main: './src/index.js',
},
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
use: 'babel-loader',
},
],
},
plugins: [
isDevelopment && new ReactRefreshPlugin(),
new HtmlWebpackPlugin({
filename: './index.html',
template: './public/index.html',
}),
].filter(Boolean),
resolve: {
extensions: ['.js', '.jsx'],
},
};
Run Code Online (Sandbox Code Playgroud)
babel.config.js
module.exports = (api) => {
// This caches the Babel config
api.cache.using(() => process.env.NODE_ENV);
return {
presets: [
'@babel/preset-env',
// Enable development transform of React with new automatic runtime
['@babel/preset-react', { development: !api.env('production'), runtime: 'automatic' }],
],
// Applies the react-refresh Babel plugin on non-production modes only
...(!api.env('production') && { plugins: ['react-refresh/babel'] }),
};
};
Run Code Online (Sandbox Code Playgroud)
您可以从 Webpack 入口点删除以下内容:
src/index.js
// ...
if (module.hot) {
module.hot.accept()
}
Run Code Online (Sandbox Code Playgroud)
这有一个小缺点,即每当您修改入口点 ( src/index.js) 时,都需要完全重新加载。Webpack 非常明确地告诉您需要完全重新加载,并向您显示以下日志消息。
这真的让我很恼火。在查看create-react-app如何解决此问题时,我发现他们禁用了 的客户端日志记录webpack-dev-server,或者至少将日志级别设置为warn或error。client.logging您可以通过在配置中设置属性来设置日志级别devServer:
webpack.config.js
// ...
devServer: {
client: {
overlay: false,
logging: 'warn' // Want to set this to 'warn' or 'error'
}
}
// ...
Run Code Online (Sandbox Code Playgroud)
关于“警告”的奇怪之处在于,它根本不是警告,它只是一条伪装成警告的信息消息。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
15107 次 |
| 最近记录: |