Skip to content

Commit 631808a

Browse files
authored
Merge pull request #4 from forge-42/custom_directives
Custom directives
2 parents 0803927 + 445f680 commit 631808a

File tree

15 files changed

+2526
-4680
lines changed

15 files changed

+2526
-4680
lines changed

.changeset/tired-paths-take.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-directives-plugin": minor
3+
---
4+
5+
Added support for custom directives like "use something"

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-directives-plugin",
33
"version": "1.0.0",
4-
"description": "Minimal open-source stack to help you ship an open-source package in TS",
4+
"description": "Vite plugin that allows you to add react directives to files behind the scenes",
55
"scripts": {
66
"build": "pnpm run --filter=\"./packages/**/*\" build",
77
"build:watch": "pnpm build && pnpm run --filter=\"./packages/**/*\" --parallel build --watch",
@@ -39,4 +39,4 @@
3939
"pnpm": ">=10.6.5",
4040
"node": ">=20.0.0"
4141
}
42-
}
42+
}
File renamed without changes.
File renamed without changes.

packages/react-directives/package.json renamed to packages/react-directives-plugin/package.json

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
22
"name": "react-directives-plugin",
33
"version": "1.0.0",
4-
"description": "Minimal open-source stack to help you ship an open-source package in TS",
5-
"main": "./dist/index.cjs",
4+
"description": "Vite plugin that allows you to add react directives to files behind the scenes",
65
"module": "./dist/index.js",
76
"types": "./dist/index.d.ts",
87
"type": "module",
@@ -13,11 +12,6 @@
1312
"types": "./dist/index.d.ts",
1413
"import": "./dist/index.js",
1514
"default": "./dist/index.js"
16-
},
17-
"require": {
18-
"types": "./dist/index.d.cts",
19-
"import": "./dist/index.cjs",
20-
"require": "./dist/index.cjs"
2115
}
2216
}
2317
},
@@ -40,9 +34,7 @@
4034
"bugs": {
4135
"url": "https://github.com/forge-42/react-directives-plugin/issues"
4236
},
43-
"files": [
44-
"dist"
45-
],
37+
"files": ["dist"],
4638
"homepage": "https://github.com/forge-42/react-directives-plugin#readme",
4739
"publishConfig": {
4840
"provenance": true
@@ -72,4 +64,4 @@
7264
"@babel/types": "^7.26.10",
7365
"picomatch": "^4.0.2"
7466
}
75-
}
67+
}

packages/react-directives/src/babel.ts renamed to packages/react-directives-plugin/src/babel.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import traverse from "@babel/traverse"
88
export const trav =
99
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
1010
typeof (traverse as any).default !== "undefined"
11-
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
12-
? ((traverse as any).default as typeof import("@babel/traverse").default)
11+
? // biome-ignore lint/suspicious/noExplicitAny: <explanation>
12+
((traverse as any).default as typeof import("@babel/traverse").default)
1313
: traverse
1414

1515
export const gen =
1616
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
1717
typeof (generate as any).default !== "undefined"
18-
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
19-
? ((generate as any).default as typeof import("@babel/generator").default)
18+
? // biome-ignore lint/suspicious/noExplicitAny: <explanation>
19+
((generate as any).default as typeof import("@babel/generator").default)
2020
: generate
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import type { Plugin } from "vite"
22
import { transformCode } from "./transformer"
33

4-
// This is your packages entry point, everything exported from here will be accessible to the end-user.
5-
export const reactDirectives = (props?: {
4+
export interface ReactDirectivesPluginOptions {
65
"use strict"?: string[]
76
"use server"?: string[]
87
"use client"?: string[]
8+
[key: `use ${string}`]: string[] | undefined
9+
}
10+
11+
// This is your packages entry point, everything exported from here will be accessible to the end-user.
12+
export const reactDirectives = (
13+
props?: ReactDirectivesPluginOptions
914
// biome-ignore lint/suspicious/noExplicitAny: Avoid issues with vite-plugin types
10-
}): any => {
11-
const { "use client": useClient = [], "use server": useServer = [], "use strict": useStrict = [] } = props || {}
15+
): any => {
1216
return {
1317
name: "react-directives-plugin",
1418
enforce: "pre",
1519
transform(code, id) {
16-
return transformCode(code, id, {
17-
useClient,
18-
useServer,
19-
useStrict,
20-
})
20+
return transformCode(code, id, props)
2121
},
2222
} satisfies Plugin
2323
}

packages/react-directives/src/transformer.test.ts renamed to packages/react-directives-plugin/src/transformer.test.ts

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ describe("transformCode", () => {
4949
const code = "const a = 1;"
5050
const id = "C://path/to/file/test.js"
5151
const result = transformCode(code, id, {
52-
useClient: ["**/*.js"],
53-
useServer: [],
54-
useStrict: [],
52+
"use client": ["**/*.js"],
53+
"use server": [],
54+
"use strict": [],
5555
})
5656
expect(removeWhitespace(result.code)).toMatch(
5757
removeWhitespace(`
@@ -64,9 +64,9 @@ describe("transformCode", () => {
6464
const code = "const a = 1;"
6565
const id = "C://path/to/file/test.js"
6666
const result = transformCode(code, id, {
67-
useClient: ["*/.ts", "**/*.js"],
68-
useServer: [],
69-
useStrict: [],
67+
"use client": ["*/.ts", "**/*.js"],
68+
"use server": [],
69+
"use strict": [],
7070
})
7171
expect(removeWhitespace(result.code)).toMatch(
7272
removeWhitespace(`
@@ -79,9 +79,9 @@ describe("transformCode", () => {
7979
const code = "const a = 1;"
8080
const id = "C://path/to/file/test.js"
8181
const result = transformCode(code, id, {
82-
useClient: [],
83-
useServer: ["*/.ts", "**/*.ts"],
84-
useStrict: [],
82+
"use client": [],
83+
"use server": ["*/.ts", "**/*.ts"],
84+
"use strict": [],
8585
})
8686
expect(removeWhitespace(result.code)).toMatch(
8787
removeWhitespace(`
@@ -94,9 +94,9 @@ describe("transformCode", () => {
9494
const code = "const a = 1;"
9595
const id = "C://path/to/file/test.js"
9696
const result = transformCode(code, id, {
97-
useClient: [],
98-
useServer: ["**/*.js"],
99-
useStrict: [],
97+
"use client": [],
98+
"use server": ["**/*.js"],
99+
"use strict": [],
100100
})
101101
expect(removeWhitespace(result.code)).toMatch(
102102
removeWhitespace(`
@@ -110,9 +110,9 @@ describe("transformCode", () => {
110110
const code = "const a = 1;"
111111
const id = "C://path/to/file/test.server.js"
112112
const result = transformCode(code, id, {
113-
useClient: [],
114-
useServer: ["**/*.server.js"],
115-
useStrict: [],
113+
"use client": [],
114+
"use server": ["**/*.server.js"],
115+
"use strict": [],
116116
})
117117
expect(removeWhitespace(result.code)).toMatch(
118118
removeWhitespace(`
@@ -125,9 +125,9 @@ describe("transformCode", () => {
125125
const code = "const a = 1;"
126126
const id = "C://path/to/file/test.js"
127127
const result = transformCode(code, id, {
128-
useClient: [],
129-
useServer: ["*/.ts", "**/*.js"],
130-
useStrict: [],
128+
"use client": [],
129+
"use server": ["*/.ts", "**/*.js"],
130+
"use strict": [],
131131
})
132132
expect(removeWhitespace(result.code)).toMatch(
133133
removeWhitespace(`
@@ -140,9 +140,9 @@ describe("transformCode", () => {
140140
const code = "const a = 1;"
141141
const id = "C://path/to/file/test.js"
142142
const result = transformCode(code, id, {
143-
useClient: [],
144-
useServer: ["*/.ts", "**/*.ts"],
145-
useStrict: [],
143+
"use client": [],
144+
"use server": ["*/.ts", "**/*.ts"],
145+
"use strict": [],
146146
})
147147
expect(removeWhitespace(result.code)).toMatch(
148148
removeWhitespace(`
@@ -156,9 +156,9 @@ describe("transformCode", () => {
156156
const code = "const a = 1;"
157157
const id = "C://path/to/file/test.js"
158158
const result = transformCode(code, id, {
159-
useClient: [],
160-
useServer: [],
161-
useStrict: ["*/.ts", "**/*.ts"],
159+
"use client": [],
160+
"use server": [],
161+
"use strict": ["*/.ts", "**/*.ts"],
162162
})
163163
expect(removeWhitespace(result.code)).toMatch(
164164
removeWhitespace(`
@@ -171,9 +171,9 @@ describe("transformCode", () => {
171171
const code = "const a = 1;"
172172
const id = "C://path/to/file/test.js"
173173
const result = transformCode(code, id, {
174-
useClient: [],
175-
useServer: [],
176-
useStrict: ["**/*.js"],
174+
"use client": [],
175+
"use server": [],
176+
"use strict": ["**/*.js"],
177177
})
178178
expect(removeWhitespace(result.code)).toMatch(
179179
removeWhitespace(`
@@ -186,9 +186,9 @@ describe("transformCode", () => {
186186
const code = "const a = 1;"
187187
const id = "C://path/to/file/test.js"
188188
const result = transformCode(code, id, {
189-
useClient: [],
190-
useServer: [],
191-
useStrict: ["*/.ts", "**/*.js"],
189+
"use client": [],
190+
"use server": [],
191+
"use strict": ["*/.ts", "**/*.js"],
192192
})
193193
expect(removeWhitespace(result.code)).toMatch(
194194
removeWhitespace(`
@@ -197,13 +197,31 @@ describe("transformCode", () => {
197197
`)
198198
)
199199
})
200+
201+
it("should add random directive with multiple matchers", () => {
202+
const code = "const a = 1;"
203+
const id = "C://path/to/file/test.js"
204+
const result = transformCode(code, id, {
205+
"use client": [],
206+
"use server": [],
207+
"use strict": ["*/.ts", "**/*.js"],
208+
"use potato": ["*/.ts", "**/*.js"],
209+
})
210+
expect(removeWhitespace(result.code)).toMatch(
211+
removeWhitespace(`
212+
"use potato";
213+
"use strict";
214+
const a = 1;
215+
`)
216+
)
217+
})
200218
it("should not add strict directive with multiple matchers if they don't match", () => {
201219
const code = "const a = 1;"
202220
const id = "C://path/to/file/test.js"
203221
const result = transformCode(code, id, {
204-
useClient: [],
205-
useServer: [],
206-
useStrict: ["*/.ts", "**/*.ts"],
222+
"use client": [],
223+
"use server": [],
224+
"use strict": ["*/.ts", "**/*.ts"],
207225
})
208226
expect(removeWhitespace(result.code)).toMatch(
209227
removeWhitespace(`

packages/react-directives/src/transformer.ts renamed to packages/react-directives-plugin/src/transformer.ts

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { types as Babel } from "@babel/core"
22
import type { ParseResult } from "@babel/parser"
33
import picomatch from "picomatch"
4+
import type { ReactDirectivesPluginOptions } from "."
45
import { gen, parse, t } from "./babel"
56

67
const transform = (ast: ParseResult<Babel.File>, directivesToAdd: string[]) => {
@@ -37,32 +38,18 @@ export function addReactDirectives(code: string, directivesToAdd: string[], id:
3738
}
3839
}
3940

40-
export const transformCode = (
41-
code: string,
42-
id: string,
43-
{
44-
useClient,
45-
useServer,
46-
useStrict,
47-
}: {
48-
useClient: string[]
49-
useServer: string[]
50-
useStrict: string[]
41+
export const transformCode = (code: string, id: string, directives?: ReactDirectivesPluginOptions) => {
42+
if (!directives) {
43+
return { code }
5144
}
52-
) => {
5345
const directivesToAdd = []
54-
const clientMatcher = picomatch(useClient)
55-
const serverMatcher = picomatch(useServer)
56-
const strictMatcher = picomatch(useStrict)
57-
if (clientMatcher(id)) {
58-
directivesToAdd.push("use client")
59-
}
60-
if (serverMatcher(id)) {
61-
directivesToAdd.push("use server")
62-
}
63-
if (strictMatcher(id)) {
64-
directivesToAdd.push("use strict")
46+
for (const [key, value] of Object.entries(directives)) {
47+
const matcher = picomatch(value)
48+
if (matcher(id)) {
49+
directivesToAdd.push(key)
50+
}
6551
}
52+
6653
if (!directivesToAdd.length) {
6754
return { code }
6855
}

0 commit comments

Comments
 (0)