Skip to content
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

Plugin-React: Allow user provided babel plugins to be applied to non-project files #16

Closed
4 tasks done
leebeydoun opened this issue Nov 18, 2021 · 3 comments · Fixed by #122
Closed
4 tasks done
Labels
enhancement New feature or request

Comments

@leebeydoun
Copy link

leebeydoun commented Nov 18, 2021

Clear and concise description of the problem

At present we can provide extra babel plugins to the @vitejs/plugin-react via its babel option, e.g:

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: ["@compiled/babel-plugin"],
      },
    }),
  ],
})

For the most part this works fine. The plugins provided are applied to project files, where a project file is not a node_module and starts with the projectRoot (project root being the current working directory). This is defined here

This is where I encounter an issue. I am using pnpm workspaces in my project and have a directory structure like:

root
|
|__vite-demo-app
|          vite.config.ts
|
|__packages/
|         |
|         |__ui-package/
|                    some-files.ts

During development my workspace packages use src/index.ts for their main entry-point in their package.json. This means when a file is loaded it needs to be transpiled (by vite in this case). In my case I am using @compiled/react which requires its babel
plugin to be applied before using the component. Since my packages will be outside the project-root the react-plugin will not apply the user provided plugins to it.

Suggested solution

Allow users to specify an include (or something similar) option which can be used to ensure that user provided plugins are still applied. For example, logic defined in the vite react plugin, could become:

const plugins = isProjectFile || options.include.some(match) ? [...userPlugins] : []

Then I could do something like:

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: ["@compiled/babel-plugin"],
        include: [function(filename) { return filename.includes('<my-project-name>/packages/<my-dep>'} ]
      },
    }),
  ],
})

The usage I'd ideally like to have seen is similar to how babel handles situations like this

Alternative

In my case I could pre-build my dependencies but this is not a great developer experience. Not aware of any other alternatives - but definitely open to suggestions.

My main goal in suggesting this change is so that I can make changes to workspace packages and see live reloads without needing to build the workspace package.

Additional context

Happy to pick this up myself and raise a PR for it.

Validations

@kalda341
Copy link

kalda341 commented Dec 16, 2021

I work with a monorepo, where I use a bit of Vite alias trickery to remap workspace packages to reference the uncompiled typescript files. This allows changes to be seen without recompiling, without any babel plugins defined.

I spent a long time figuring out why my project wasn't working after upgrading plugin-react, but eventually stumbled upon the same issue you have. I think the change is an improvement, however I, like you, want to be able to continue to apply babel transforms to these files.

@aleclarson
Copy link
Member

If anyone wants to write tests for vitejs/vite#6202, we can get it merged!

@justinbhopper
Copy link

For anyone using a monorepo and the @vitejs/plugin-react plugin, there was a discussion in vitejs/vite#6202 that explains how to setup a babel config across all projects.

Currently, @vitejs/plugin-react only applies babel to files within the project root, which ends up being the main entrypoint that vite is building. In a monorepo, this does not include any of the other projects/workspaces.

To fix this, you can setup the plugin to use your own babel config on top of theirs by using configFile: true.

.vite.config.js:

reactPlugin({
  babel: {
    configFile: true, // Tells @vitejs/plugin-react that there is a babel.config.js or babel.config.json to search for
    rootMode: "upward", // Use this if you want a shared babel.config.json at the root of your monorepo
  }
}),

babel.config.json (example):

{
  "only": ["**/packages/**/src"],
  "ignore": ["**/node_modules/**"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "@quickbaseoss/babel-plugin-styled-components-css-namespace",
    ["babel-plugin-styled-components", { "displayName": true, "fileName": false }]
  ]
}

You can add babel.config.js files within each project, as well.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.