diff --git a/src/TailwindCSSRspackPlugin.ts b/src/TailwindCSSRspackPlugin.ts index e49ec71..4dd17cd 100644 --- a/src/TailwindCSSRspackPlugin.ts +++ b/src/TailwindCSSRspackPlugin.ts @@ -116,6 +116,32 @@ interface TailwindRspackPluginOptions { */ include?: FilterPattern | undefined; + /** + * Setting Tailwind config path for different entries + * + * {@link multipleConfig} can be configured as an object where the key is the entryName and the value is the config path. + * If the key cannot be found, it will fallback to {@link config} , which is the default config path. + * + * @example + * + * ```js + * // rspack.config.js + * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss' + * + * export default { + * plugins: [ + * new TailwindRspackPlugin({ + * multipleConfig: { + * index: './config/tailwind.index.config.js', + * main: './config/tailwind.main.config.js' + * }, + * }), + * ], + * } + * ``` + */ + multipleConfig?: Record | undefined; + /** * The postcss options to be applied. * @@ -315,10 +341,14 @@ class TailwindRspackPluginImpl { entryName: string, entryModules: Array, ): Promise { - const userConfig = path.isAbsolute(this.options.config) - ? this.options.config + const multipleConfig = this.options.multipleConfig || {}; + + const userConfig = multipleConfig[entryName] || this.options.config; + + const resolvedConfig = path.isAbsolute(userConfig) + ? userConfig : // biome-ignore lint/style/noNonNullAssertion: should have context - path.resolve(this.compiler.options.context!, this.options.config); + path.resolve(this.compiler.options.context!, userConfig); const outputDir = DEBUG ? path.resolve( @@ -334,7 +364,7 @@ class TailwindRspackPluginImpl { } const [configName, configContent] = await this.#generateTailwindConfig( - userConfig, + resolvedConfig, entryModules, ); const configPath = path.resolve(outputDir, configName); diff --git a/src/index.ts b/src/index.ts index 57d9673..70c1892 100644 --- a/src/index.ts +++ b/src/index.ts @@ -112,6 +112,32 @@ export interface PluginTailwindCSSOptions { * ``` */ include?: FilterPattern | undefined; + + /** + * Setting Tailwind config path for different entries + * + * {@link multipleConfig} can be configured as an object where the key is the entryName and the value is the config path. + * If the key cannot be found, it will fallback to {@link config} , which is the default config path. + * + * @example + * + * ```js + * // rspack.config.js + * import { TailwindRspackPlugin } from 'rsbuild-plugin-tailwindcss' + * + * export default { + * plugins: [ + * new TailwindRspackPlugin({ + * multipleConfig: { + * index: './config/tailwind.index.config.js', + * main: './config/tailwind.main.config.js' + * }, + * }), + * ], + * } + * ``` + */ + multipleConfig?: Record | undefined; } export const pluginTailwindCSS = ( @@ -160,6 +186,7 @@ export const pluginTailwindCSS = ( config: options.config ?? 'tailwind.config.js', include: options.include, exclude: options.exclude, + multipleConfig: options.multipleConfig, postcssOptions, }, ]); diff --git a/test/multiple-config/config/tailwind.index.config.js b/test/multiple-config/config/tailwind.index.config.js new file mode 100644 index 0000000..f151588 --- /dev/null +++ b/test/multiple-config/config/tailwind.index.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{js,jsx,ts,tsx}'], + theme: { + extend: { + colors: { + index: '#0055ff', + }, + }, + }, +}; diff --git a/test/multiple-config/config/tailwind.main.config.js b/test/multiple-config/config/tailwind.main.config.js new file mode 100644 index 0000000..425d438 --- /dev/null +++ b/test/multiple-config/config/tailwind.main.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{js,jsx,ts,tsx}'], + theme: { + extend: { + colors: { + main: '#ff5500', + }, + }, + }, +}; diff --git a/test/multiple-config/index.test.ts b/test/multiple-config/index.test.ts new file mode 100644 index 0000000..1c5410d --- /dev/null +++ b/test/multiple-config/index.test.ts @@ -0,0 +1,68 @@ +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import test, { expect } from '@playwright/test'; +import { createRsbuild } from '@rsbuild/core'; + +import { pluginTailwindCSS } from '../../src'; +import { getRandomPort } from '../helper'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +test('should build with multiple configs for different entries', async ({ + page, +}) => { + const rsbuild = await createRsbuild({ + cwd: __dirname, + rsbuildConfig: { + source: { + entry: { + index: './src/index.js', + main: './src/main.js', + default: './src/default.js', + }, + }, + plugins: [ + pluginTailwindCSS({ + multipleConfig: { + index: './config/tailwind.index.config.js', + main: './config/tailwind.main.config.js', + }, + }), + ], + server: { + port: getRandomPort(), + }, + }, + }); + + await rsbuild.build(); + + const { server, urls } = await rsbuild.startDevServer(); + + await page.goto(`${urls[0]}/index`); + let style = await getStyle(); + expect(style.backgroundColor).toBe('rgb(0, 85, 255)'); + + await page.goto(`${urls[0]}/main`); + style = await getStyle(); + expect(style.backgroundColor).toBe('rgb(255, 85, 0)'); + + await page.goto(`${urls[0]}/default`); + style = await getStyle(); + expect(style.backgroundColor).toBe('rgb(85, 255, 0)'); + + await server.close(); + + async function getStyle() { + return await page.evaluate(() => { + const el = document.getElementById('test'); + + if (!el) { + throw new Error('#test not found'); + } + + return window.getComputedStyle(el); + }); + } +}); diff --git a/test/multiple-config/src/default.js b/test/multiple-config/src/default.js new file mode 100644 index 0000000..7ceeb48 --- /dev/null +++ b/test/multiple-config/src/default.js @@ -0,0 +1,12 @@ +import 'tailwindcss/utilities.css'; + +function className() { + return 'flex bg-default'; +} + +const root = document.getElementById('root'); +const element = document.createElement('div'); +element.id = 'test'; +element.className = className(); +element.textContent = 'Default Entry'; +root.appendChild(element); diff --git a/test/multiple-config/src/index.js b/test/multiple-config/src/index.js new file mode 100644 index 0000000..4369bd8 --- /dev/null +++ b/test/multiple-config/src/index.js @@ -0,0 +1,12 @@ +import 'tailwindcss/utilities.css'; + +function className() { + return 'flex bg-index'; +} + +const root = document.getElementById('root'); +const element = document.createElement('div'); +element.id = 'test'; +element.className = className(); +element.textContent = 'Index Entry'; +root.appendChild(element); diff --git a/test/multiple-config/src/main.js b/test/multiple-config/src/main.js new file mode 100644 index 0000000..5f12715 --- /dev/null +++ b/test/multiple-config/src/main.js @@ -0,0 +1,12 @@ +import 'tailwindcss/utilities.css'; + +function className() { + return 'flex bg-main'; +} + +const root = document.getElementById('root'); +const element = document.createElement('div'); +element.id = 'test'; +element.className = className(); +element.textContent = 'Main Entry'; +root.appendChild(element); diff --git a/test/multiple-config/tailwind.config.js b/test/multiple-config/tailwind.config.js new file mode 100644 index 0000000..2595b0f --- /dev/null +++ b/test/multiple-config/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{js,jsx,ts,tsx}'], + theme: { + extend: { + colors: { + default: '#55ff00', + }, + }, + }, +};