Skip to content

Commit f02a9f1

Browse files
authored
feat: implement include and exclude option (#19)
1 parent 0f1cc6c commit f02a9f1

18 files changed

+536
-21
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"devDependencies": {
3131
"@biomejs/biome": "^1.9.4",
3232
"@playwright/test": "^1.48.2",
33+
"@rollup/pluginutils": "^5.1.3",
3334
"@rsbuild/core": "^1.1.0",
3435
"@rslib/core": "^0.0.16",
3536
"@types/node": "^22.9.0",

pnpm-lock.yaml

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/TailwindCSSRspackPlugin.ts

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
44
import path from 'node:path';
55
import { pathToFileURL } from 'node:url';
66

7+
import { createFilter } from '@rollup/pluginutils';
78
import type { PostCSSLoaderOptions, Rspack } from '@rsbuild/core';
89

910
/**
@@ -56,6 +57,61 @@ interface TailwindRspackPluginOptions {
5657
*/
5758
config: string;
5859

60+
/**
61+
* The modules to be excluded.
62+
*
63+
* If {@link include} is omitted or empty,
64+
* all modules that do not match any of the {@link exclude} patterns will be included.
65+
* Otherwise, only modules that match one or more of the {@link include} patterns
66+
* and do not match any of the {@link exclude} patterns will be included.
67+
*
68+
* @example
69+
*
70+
* ```js
71+
* // rspack.config.js
72+
* import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
73+
*
74+
* export default {
75+
* plugins: [
76+
* new TailwindRspackPlugin({
77+
* exclude: [
78+
* './src/store/**',
79+
* /[\\/]node_modules[\\/]/,
80+
* ],
81+
* }),
82+
* ],
83+
* }
84+
* ```
85+
*/
86+
exclude?: FilterPattern | undefined;
87+
88+
/**
89+
* The modules to be included using `picomatch` patterns.
90+
*
91+
* If {@link include} is omitted or empty,
92+
* all modules that do not match any of the {@link exclude} patterns will be included.
93+
* Otherwise, only modules that match one or more of the {@link include} patterns
94+
* and do not match any of the {@link exclude} patterns will be included.
95+
*
96+
* @example
97+
*
98+
* ```js
99+
* // rspack.config.js
100+
* import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss'
101+
*
102+
* export default {
103+
* plugins: [
104+
* new TailwindRspackPlugin({
105+
* include: [
106+
* /\.[jt]sx?/,
107+
* ],
108+
* }),
109+
* ],
110+
* }
111+
* ```
112+
*/
113+
include?: FilterPattern | undefined;
114+
59115
/**
60116
* The postcss options to be applied.
61117
*
@@ -86,6 +142,16 @@ interface TailwindRspackPluginOptions {
86142
>;
87143
}
88144

145+
// From `@rollup/pluginutils`
146+
/**
147+
* A valid `picomatch` glob pattern, or array of patterns.
148+
*/
149+
export type FilterPattern =
150+
| ReadonlyArray<string | RegExp>
151+
| string
152+
| RegExp
153+
| null;
154+
89155
/**
90156
* The Rspack plugin for Tailwind integration.
91157
*
@@ -94,17 +160,6 @@ interface TailwindRspackPluginOptions {
94160
class TailwindRspackPlugin {
95161
constructor(private readonly options: TailwindRspackPluginOptions) {}
96162

97-
/**
98-
* `defaultOptions` is the default options that the {@link TailwindRspackPlugin} uses.
99-
*
100-
* @public
101-
*/
102-
static defaultOptions: Readonly<Required<TailwindRspackPluginOptions>> =
103-
Object.freeze<Required<TailwindRspackPluginOptions>>({
104-
config: 'tailwind.config.js',
105-
postcssOptions: {},
106-
});
107-
108163
/**
109164
* The entry point of a Rspack plugin.
110165
* @param compiler - the Rspack compiler
@@ -124,6 +179,11 @@ class TailwindRspackPluginImpl {
124179
private compiler: Rspack.Compiler,
125180
private options: TailwindRspackPluginOptions,
126181
) {
182+
const filter = createFilter(options.include, options.exclude, {
183+
// biome-ignore lint/style/noNonNullAssertion: context should exist
184+
resolve: compiler.options.context!,
185+
});
186+
127187
const { RawSource } = compiler.webpack.sources;
128188
compiler.hooks.thisCompilation.tap(this.name, (compilation) => {
129189
compilation.hooks.processAssets.tapPromise(this.name, async () => {
@@ -159,7 +219,10 @@ class TailwindRspackPluginImpl {
159219
] = await Promise.all([
160220
import('postcss'),
161221
import('tailwindcss'),
162-
this.#prepareTailwindConfig(entryName, entryModules),
222+
this.#prepareTailwindConfig(
223+
entryName,
224+
Array.from(entryModules).filter(filter),
225+
),
163226
]);
164227

165228
const postcssTransform = postcss([
@@ -203,7 +266,7 @@ class TailwindRspackPluginImpl {
203266

204267
async #prepareTailwindConfig(
205268
entryName: string,
206-
entryModules: Set<string>,
269+
entryModules: Array<string>,
207270
): Promise<string> {
208271
const userConfig = path.isAbsolute(this.options.config)
209272
? this.options.config
@@ -225,7 +288,7 @@ class TailwindRspackPluginImpl {
225288

226289
const configPath = path.resolve(outputDir, 'tailwind.config.mjs');
227290

228-
const content = JSON.stringify(Array.from(entryModules));
291+
const content = JSON.stringify(entryModules);
229292

230293
await writeFile(
231294
configPath,

src/index.ts

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import type {
55
} from '@rsbuild/core';
66

77
import { TailwindRspackPlugin } from './TailwindCSSRspackPlugin.js';
8+
import type { FilterPattern } from './TailwindCSSRspackPlugin.js';
89

9-
export type PluginTailwindCSSOptions = {
10+
export type { FilterPattern };
11+
12+
export interface PluginTailwindCSSOptions {
1013
/**
1114
* The path to the configuration of Tailwind CSS.
1215
*
@@ -54,7 +57,62 @@ export type PluginTailwindCSSOptions = {
5457
* ```
5558
*/
5659
config?: string;
57-
};
60+
61+
/**
62+
* The modules to be excluded using `picomatch` patterns.
63+
*
64+
* If {@link include} is omitted or empty,
65+
* all modules that do not match any of the {@link exclude} patterns will be included.
66+
* Otherwise, only modules that match one or more of the {@link include} patterns
67+
* and do not match any of the {@link exclude} patterns will be included.
68+
*
69+
* @example
70+
*
71+
* ```js
72+
* // rsbuild.config.ts
73+
* import { pluginTailwindCSS } from '@byted-lynx/plugin-tailwindcss'
74+
*
75+
* export default {
76+
* plugins: [
77+
* pluginTailwindCSS({
78+
* exclude: [
79+
* './src/store/**',
80+
* /[\\/]node_modules[\\/]/,
81+
* ],
82+
* }),
83+
* ],
84+
* }
85+
* ```
86+
*/
87+
exclude?: FilterPattern | undefined;
88+
89+
/**
90+
* The modules to be included using `picomatch` patterns.
91+
*
92+
* If {@link include} is omitted or empty,
93+
* all modules that do not match any of the {@link exclude} patterns will be included.
94+
* Otherwise, only modules that match one or more of the {@link include} patterns
95+
* and do not match any of the {@link exclude} patterns will be included.
96+
*
97+
* @example
98+
*
99+
* ```js
100+
* // rsbuild.config.ts
101+
* import { pluginTailwindCSS } from '@byted-lynx/plugin-tailwindcss'
102+
*
103+
* export default {
104+
* plugins: [
105+
* pluginTailwindCSS({
106+
* include: [
107+
* /\.[jt]sx?/,
108+
* ],
109+
* }),
110+
* ],
111+
* }
112+
* ```
113+
*/
114+
include?: FilterPattern | undefined;
115+
}
58116

59117
export const pluginTailwindCSS = (
60118
options: PluginTailwindCSSOptions = {},
@@ -97,11 +155,14 @@ export const pluginTailwindCSS = (
97155
api.modifyBundlerChain({
98156
order: 'post',
99157
handler(chain) {
100-
chain
101-
.plugin('tailwindcss')
102-
.use(TailwindRspackPlugin, [
103-
{ config: options.config ?? 'tailwind.config.js', postcssOptions },
104-
]);
158+
chain.plugin('tailwindcss').use(TailwindRspackPlugin, [
159+
{
160+
config: options.config ?? 'tailwind.config.js',
161+
include: options.include,
162+
exclude: options.exclude,
163+
postcssOptions,
164+
},
165+
]);
105166
},
106167
});
107168
},

0 commit comments

Comments
 (0)