babel-plugin-vue-jsx-hmr
raw JSON → 1.0.0 verified Sat Apr 25 auth: no javascript
A Babel plugin that enables hot module replacement (HMR) for Vue 3 JSX and TSX components when using build tools like webpack and Rspack. Version 1.0.0 is latest. It works alongside @vue/babel-plugin-jsx and requires babel-loader. The plugin injects HMR code for components that are exported and declared via defineComponent, supporting named exports, re-exports, and default exports. It does not work with Vite (use @vitejs/plugin-vue-jsx instead). Provides HMR detection similar to Vite's plugin but for webpack/Rspack ecosystems.
Common errors
error Cannot find module '@vue/babel-plugin-jsx' ↓
cause Missing peer dependency.
fix
Install @vue/babel-plugin-jsx: npm install @vue/babel-plugin-jsx --save-dev
error HMR not working: components not updating on save ↓
cause Component not exported or not using defineComponent, or plugin order wrong.
fix
Ensure component is exported and declared with defineComponent, and plugins order is correct: ['@vue/babel-plugin-jsx', 'babel-plugin-vue-jsx-hmr'].
error Hot Module Replacement is disabled in production mode. ↓
cause HMR only works in development mode.
fix
Set mode: 'development' in webpack config, or use NODE_ENV=development.
error Uncaught TypeError: Cannot read properties of undefined (reading 'setup') ↓
cause Component not properly transformed; likely missing @vue/babel-plugin-jsx.
fix
Add @vue/babel-plugin-jsx to Babel plugins before babel-plugin-vue-jsx-hmr.
Warnings
gotcha HMR only works for components exported and declared via defineComponent at root level. ↓
fix Ensure each component is a root-level statement: export const Foo = defineComponent({...}) or export default defineComponent({...}). Anonymous default exports work.
gotcha Plugin order matters: @vue/babel-plugin-jsx must come before babel-plugin-vue-jsx-hmr. ↓
fix Specify plugins in order: ['@vue/babel-plugin-jsx', 'babel-plugin-vue-jsx-hmr'].
gotcha Does not work with Vite; use @vitejs/plugin-vue-jsx instead. ↓
fix If using Vite, remove babel-plugin-vue-jsx-hmr and add @vitejs/plugin-vue-jsx to vite.config.js.
gotcha Requires liveReload: false and hot: true in webpack devServer config. ↓
fix Set devServer: { liveReload: false, hot: true } in webpack.config.js.
gotcha Components not using defineComponent (e.g., plain object) will not get HMR. ↓
fix Wrap component options with defineComponent: const Comp = defineComponent({...}).
Install
npm install babel-plugin-vue-jsx-hmr yarn add babel-plugin-vue-jsx-hmr pnpm add babel-plugin-vue-jsx-hmr Imports
- babel-plugin-vue-jsx-hmr wrong
import babelPluginVueJsxHmr from 'babel-plugin-vue-jsx-hmr'correctIn babel.config.js or webpack babel options: plugins: ['babel-plugin-vue-jsx-hmr'] - Plugin usage with string wrong
plugins: ['babel-plugin-vue-jsx-hmr', '@vue/babel-plugin-jsx']correctplugins: ['@vue/babel-plugin-jsx', 'babel-plugin-vue-jsx-hmr'] - defineComponent wrong
import { defineComponent } from '@vue/composition-api'correctimport { defineComponent } from 'vue'
Quickstart
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(jsx|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@vue/babel-plugin-jsx', 'babel-plugin-vue-jsx-hmr']
}
}
}
]
},
devServer: {
liveReload: false,
hot: true
}
};
// component.jsx
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
const count = ref(0);
return () => <button onClick={() => count.value++}>{count.value}</button>;
}
});