-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(plugin-react): check for api.reactBabel
on other plugins
#5454
Conversation
b850459
to
c655ef1
Compare
Not sure why CI fails. I tested locally (with updated lockfile) and it builds fine. |
What about the api pattern instead? |
Maybe this is exactly the point. |
@bluwy I don't see Rollup ever adding a
I already tried that :\ |
This would be a new concept, and it wont work without the react plugin. I also think that we should use api if the dx is similar If not, this should go in vite config, and modified by plugins in the config hook |
Would that allow the end user to configure Babel through Probably want to avoid having two ways for the end user to configure Babel.
It's a clunkier solution, imo. Editable pluginsHere's an idea... We could add "editable plugins" 👇 export default function viteReact(options) {
const babelOptions = options.babel || {}
babelOptions.plugins ??= []
return {
name: 'vite:react-babel',
// Objects added to `editable` may be edited by other plugins.
editable: {
babel: babelOptions,
}
}
}
// Other plugins define an `editPlugins` hook…
editPlugins(edit) {
// This warns if `vite:react-babel` does not exist
edit('vite:react-babel', (state) => {
// Accessing `state.babel` will throw if never defined
// in `editable` of the targeted plugin.
state.babel.plugins.push(require.resolve('@foo/babel-plugin'))
// Or you can return an object to be merged recursively.
return { babel: { plugins: ['@foo/babel-plugin']} }
})
} |
I think Code 1export default function viteReact(options) {
const babelOptions = options.babel || {}
babelOptions.plugins ??= []
return {
name: 'vite:react-babel',
api: {
updateBabel(fn) {
fn(babelOptions)
}
}
}
}
function viteReactCss() {
return {
name: 'vite-react-css',
config(c) {
const viteReactApi = c.plugins.find(plugin => plugin.name === 'vite:react')?.api
viteReactApi?.updateBabel((babel) => {
babel.plugins.push(require.resolve('@foo/babel-plugin'))
})
}
}
} or we can invert the responsibility: Code 2export default function viteReact(options) {
const babelOptions = options.babel || {}
babelOptions.plugins ??= []
return {
name: 'vite:react-babel',
configResolved(c) {
c.plugins.forEach(plugin => {
plugin.api?.reactBabel?.(babelOptions)
}
}
}
}
function viteReactCss() {
return {
name: 'vite-react-css',
api: {
reactBabel(babel) {
babel.plugins.push(require.resolve('@foo/babel-plugin'))
}
}
}
} Windicss and svelte follows the latter pattern. windicss code, svelte code. |
The second one is a very interesting pattern, it looks a lot cleaner to me. If the ecosystem is going to start doing this, we should document that this is supported so Vite doesn't do things like freezing the ConfigResolved object in the future (if that is even possible). But it is still important to define that plugin can modify the config in From the current docs: https://vitejs.dev/guide/api-plugin.html#configresolved
|
The 2nd pattern is good, except that there's no warning if Another option: We could formalize the declaration of a cross-plugin dependency like so: // Dependent plugins would add @vitejs/plugin-react to devDependencies
// so the `api` object could be statically typed.
import type { ReactBabel } from '@vitejs/plugin-react'
// …within vite-react-css plugin
config({ getPlugin }) {
// `getPlugin` should probably return the plugin object (instead of only its `api` object)
// since its other hooks could be useful. For example, vite-plugin-mdx uses the `transform`
// hook of @vitejs/plugin-react-refresh to enable Fast Refresh in MDX files.
const reactBabel = getPlugin<ReactBabel>('vite:react-babel', true /* required */).api
reactBabel.mergeConfig({ plugins: […], presets: […] })
} The |
The dependent plugin can manually issue a warning if the babel plugin is a must, by checking for the plugin like in the 1st pattern using
This seems to be going back to the 1st pattern, and I'm not sure why we need a blessed way of searching for plugins instead of |
My vote is on the 2nd style by @bluwy. |
Something else we discussed in the meeting is that the worry in my comment here #5454 (comment) isn't really an issue. The ResolvedConfig object is not being modified in the 2nd style, what changes is the internal plugin config so it is totally fair to do so. There is no need to update the docs. |
93e6578
to
8978ddc
Compare
api.reactBabel
on other plugins
I've updated this PR. The |
8978ddc
to
dce43ac
Compare
5f55a13
to
0791318
Compare
6aa3bb2
to
8f6234b
Compare
8f6234b
to
53399ab
Compare
See the discussion below and this comment for more details.
Description
Allow Vite plugins to define their own Babel presets/plugins.
Additional context
This PR is needed for vite-react-css to work.
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).