前言:
项目中如果使用了ts和ts-loader,那么这个loader会影响webpack的HMR功能,导致代码改动后浏览器每次都刷新,给日常的react项目开发工作带来不少麻烦!下面是解决方案
准备工作:
- 最低支持 react 16.9 版本
- npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
- 如果要支持ts 需要安装 npm install -D type-fest
用babel-loader编译ts 实现HMR
babel 需要安装 @babel/preset-typescript 来支持ts
webpack的相关配置如下:
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
mode: isDevelopment ? 'development' : 'production',
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('babel-loader'),
options: {
plugins: [isDevelopment && require.resolve('react-refresh/babel')].filter(Boolean),
},
},
],
},
],
},
plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
};
babel配置文件参考
module.exports = (api) => {
// This caches the Babel config
api.cache.using(() => process.env.NODE_ENV);
return {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
// 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'] }),
};
};
用ts-loader编译ts 实现 HMR
需要安装包 npm install -D react-refresh-typescript
const ReactRefreshTypeScript = require('react-refresh-typescript');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('ts-loader'),
options: {
getCustomTransformers: () => ({
before: [isDevelopment && ReactRefreshTypeScript()].filter(Boolean),
}),
transpileOnly: isDevelopment,
},
},
],
},
],
},
};
ts-loader不能和HMR一起工作,除非transpileOnly设置为true。如果你需要在开发过程中进行类型检查,你应该使用ForkTsCheckerWebpackPlugin。
以上就分别实现了react项目中编译ts 和HMR 热替换 之间的冲突问题!