Skip to content

Commit 26326b3

Browse files
Jinjianghi-ogawasapphi-red
authored
feat!: support including files in node_modules (#306)
Co-authored-by: Hiroshi Ogawa <[email protected]> Co-authored-by: sapphi-red <[email protected]>
1 parent 2a81b90 commit 26326b3

File tree

16 files changed

+152
-85
lines changed

16 files changed

+152
-85
lines changed

packages/plugin-react-oxc/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Allow processing files in `node_modules`
6+
7+
The default value of `exclude` options is now `[/\/node_modules\//]` to allow processing files in `node_modules` directory. It was previously `[]` and files in `node_modules` was always excluded regardless of the value of `exclude` option.
8+
59
### Require Node 20.19+, 22.12+
610

711
This plugin now requires Node 20.19+ or 22.12+.

packages/plugin-react-oxc/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default defineConfig({
2525

2626
### include/exclude
2727

28-
Includes `.js`, `.jsx`, `.ts` & `.tsx` by default. This option can be used to add fast refresh to `.mdx` files:
28+
Includes `.js`, `.jsx`, `.ts` & `.tsx` and excludes `/node_modules/` by default. This option can be used to add fast refresh to `.mdx` files:
2929

3030
```js
3131
import { defineConfig } from 'vite'
@@ -40,8 +40,6 @@ export default defineConfig({
4040
})
4141
```
4242

43-
> `node_modules` are never processed by this plugin (but Oxc will)
44-
4543
### jsxImportSource
4644

4745
Control where the JSX factory is imported from. Default to `'react'`

packages/plugin-react-oxc/src/index.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,11 @@ export interface Options {
2525
}
2626

2727
const defaultIncludeRE = /\.[tj]sx?(?:$|\?)/
28+
const defaultExcludeRE = /\/node_modules\//
2829

2930
export default function viteReact(opts: Options = {}): Plugin[] {
3031
const include = opts.include ?? defaultIncludeRE
31-
const exclude = [
32-
...(Array.isArray(opts.exclude)
33-
? opts.exclude
34-
: opts.exclude
35-
? [opts.exclude]
36-
: []),
37-
/\/node_modules\//,
38-
]
32+
const exclude = opts.exclude ?? defaultExcludeRE
3933

4034
const jsxImportSource = opts.jsxImportSource ?? 'react'
4135
const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`

packages/plugin-react/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Allow processing files in `node_modules`
6+
7+
The default value of `exclude` options is now `[/\/node_modules\//]` to allow processing files in `node_modules` directory. It was previously `[]` and files in `node_modules` was always excluded regardless of the value of `exclude` option.
8+
59
### `react` and `react-dom` is no longer added to [`resolve.dedupe`](https://vite.dev/config/#resolve-dedupe) automatically
610

711
Adding values to `resolve.dedupe` forces Vite to resolve them differently from how Node.js does, which can be confusing and may not be expected. This plugin no longer adds `react` and `react-dom` to `resolve.dedupe` automatically.

packages/plugin-react/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default defineConfig({
2121

2222
### include/exclude
2323

24-
Includes `.js`, `.jsx`, `.ts` & `.tsx` by default. This option can be used to add fast refresh to `.mdx` files:
24+
Includes `.js`, `.jsx`, `.ts` & `.tsx` and excludes `/node_modules/` by default. This option can be used to add fast refresh to `.mdx` files:
2525

2626
```js
2727
import { defineConfig } from 'vite'
@@ -36,8 +36,6 @@ export default defineConfig({
3636
})
3737
```
3838

39-
> `node_modules` are never processed by this plugin (but esbuild will)
40-
4139
### jsxImportSource
4240

4341
Control where the JSX factory is imported from. Default to `'react'`

packages/plugin-react/src/index.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,12 @@ export type ViteReactPluginApi = {
104104
}
105105

106106
const defaultIncludeRE = /\.[tj]sx?$/
107+
const defaultExcludeRE = /\/node_modules\//
107108
const tsRE = /\.tsx?$/
108109

109110
export default function viteReact(opts: Options = {}): Plugin[] {
110111
const include = opts.include ?? defaultIncludeRE
111-
const exclude = opts.exclude
112+
const exclude = opts.exclude ?? defaultExcludeRE
112113
const filter = createFilter(include, exclude)
113114

114115
const jsxImportSource = opts.jsxImportSource ?? 'react'
@@ -222,17 +223,10 @@ export default function viteReact(opts: Options = {}): Plugin[] {
222223
filter: {
223224
id: {
224225
include: makeIdFiltersToMatchWithQuery(include),
225-
exclude: [
226-
...(exclude
227-
? makeIdFiltersToMatchWithQuery(ensureArray(exclude))
228-
: []),
229-
/\/node_modules\//,
230-
],
226+
exclude: makeIdFiltersToMatchWithQuery(exclude),
231227
},
232228
},
233229
async handler(code, id, options) {
234-
if (id.includes('/node_modules/')) return
235-
236230
const [filepath] = id.split('?')
237231
if (!filter(filepath)) return
238232

@@ -472,7 +466,3 @@ function getReactCompilerRuntimeModule(
472466
}
473467
return moduleName
474468
}
475-
476-
function ensureArray<T>(value: T | T[]): T[] {
477-
return Array.isArray(value) ? value : [value]
478-
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import test from '@vitejs/test-package'
2+
3+
function App() {
4+
return (
5+
<div>
6+
<h1>Node Modules Include Test</h1>
7+
<p>
8+
This playground tests that files in node_modules are processed
9+
correctly.
10+
</p>
11+
12+
<p className="result">Result: {'' + test}</p>
13+
</div>
14+
)
15+
}
16+
17+
export default App
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { expect, test } from 'vitest'
2+
import { page } from '~utils'
3+
4+
test('should render', async () => {
5+
expect(await page.textContent('h1')).toMatch('Node Modules Include Test')
6+
})
7+
8+
test('babel should run on files in node_modules', async () => {
9+
expect(await page.textContent('.result')).toMatch('Result: true')
10+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div id="app"></div>
2+
<script type="module">
3+
import React from 'react'
4+
import ReactDOM from 'react-dom/client'
5+
import App from './App.jsx'
6+
7+
ReactDOM.createRoot(document.getElementById('app')).render(
8+
React.createElement(App),
9+
)
10+
</script>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@vitejs/test-node-modules-include",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"preview": "vite preview"
9+
},
10+
"dependencies": {
11+
"react": "^19.1.0",
12+
"react-dom": "^19.1.0"
13+
},
14+
"devDependencies": {
15+
"@types/babel__core": "^7.20.5",
16+
"@types/react": "^19.1.8",
17+
"@types/react-dom": "^19.1.6",
18+
"@vitejs/plugin-react": "workspace:*",
19+
"@vitejs/test-package": "file:./test-package"
20+
}
21+
}

0 commit comments

Comments
 (0)