diff --git a/.changeset/many-hotels-make.md b/.changeset/many-hotels-make.md new file mode 100644 index 00000000..59dc2904 --- /dev/null +++ b/.changeset/many-hotels-make.md @@ -0,0 +1,7 @@ +--- +'@prefresh/vite': major +--- + +Make Babel an optional peer dependency + +`@babel/core` and `@prefresh/babel-plugin` are no longer hard dependencies of `@prefresh/vite`. Projects using modern versions of Vite no longer require Babel in their dependency tree. diff --git a/packages/vite/package.json b/packages/vite/package.json index 63270cea..ddb790a4 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -36,22 +36,32 @@ }, "homepage": "https://github.com/preactjs/prefresh#readme", "dependencies": { - "@babel/core": "^7.22.1", "@prefresh/core": "^1.5.0", - "@prefresh/babel-plugin": "^0.5.2", "@prefresh/rolldown": "workspace:*", "@prefresh/utils": "^1.2.0", "@rollup/pluginutils": "^4.2.1", "rolldown": "^1.0.0-rc.12" }, "devDependencies": { + "@babel/core": "^7.22.1", + "@prefresh/babel-plugin": "^0.5.2", "preact": "^10.26.10", "vite": "^8.0.0" }, "peerDependencies": { + "@babel/core": "^7.22.1", + "@prefresh/babel-plugin": "^0.5.2", "preact": "^10.4.0 || ^11.0.0-0", "vite": ">=2.0.0" }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@prefresh/babel-plugin": { + "optional": true + } + }, "publishConfig": { "provenance": true } diff --git a/packages/vite/src/index.js b/packages/vite/src/index.js index 10089ffd..5bf0680f 100644 --- a/packages/vite/src/index.js +++ b/packages/vite/src/index.js @@ -2,18 +2,38 @@ const { createFilter } = require('@rollup/pluginutils'); const SCRIPT_LANG_RE = /\.(c|m)?(t|j)sx?$/; let babel; +let babelLoadAttempted = false; let prefreshRolldownPromise; let viteSupportsHookFilters; let viteVersionParts; -function loadBabel() { - babel ||= { +function tryLoadBabel() { + if (babelLoadAttempted) return babel; + babelLoadAttempted = true; + try { + require.resolve('@babel/core'); + require.resolve('@prefresh/babel-plugin'); + } catch (err) { + if (err && err.code === 'MODULE_NOT_FOUND') return babel; + throw err; + } + babel = { transformSync: require('@babel/core').transformSync, prefreshBabelPlugin: require('@prefresh/babel-plugin'), }; return babel; } +function loadBabel() { + const loaded = tryLoadBabel(); + if (loaded) return loaded; + throw new Error( + '@prefresh/vite needs @babel/core and @prefresh/babel-plugin to use the Babel transform path ' + + '(triggered by `parserPlugins` or by Vite < 8 without rolldown support). ' + + 'Install them as dev dependencies, or upgrade to a Vite version with rolldown so the Oxc path is used instead.' + ); +} + function loadPrefreshRolldown() { prefreshRolldownPromise ||= import('@prefresh/rolldown').then( ({ default: prefreshRolldown }) => prefreshRolldown @@ -213,6 +233,10 @@ function prefreshBabelTransformPlugin(options = {}, forceBabel) { const hasSig = /\$RefreshSig\$\(/.test(code); if (hasReg || hasSig) return; + + // Babel is an optional fallback on the Oxc path; if it's not + // installed we silently skip rather than failing the request. + if (!tryLoadBabel()) return; } const result = transform(code, id, parserPlugins); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00dc1a2c..4bbdd8b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,12 +103,6 @@ importers: packages/vite: dependencies: - '@babel/core': - specifier: ^7.22.1 - version: 7.27.7 - '@prefresh/babel-plugin': - specifier: ^0.5.2 - version: 0.5.2 '@prefresh/core': specifier: ^1.5.0 version: 1.5.4(preact@10.26.10) @@ -125,6 +119,12 @@ importers: specifier: ^1.0.0-rc.12 version: 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) devDependencies: + '@babel/core': + specifier: ^7.22.1 + version: 7.27.7 + '@prefresh/babel-plugin': + specifier: ^0.5.2 + version: 0.5.2 preact: specifier: ^10.26.10 version: 10.26.10