diff --git a/packages/cli/src/cli-start.ts b/packages/cli/src/cli-start.ts index b604dbefe2..558df0cb6f 100644 --- a/packages/cli/src/cli-start.ts +++ b/packages/cli/src/cli-start.ts @@ -1,4 +1,6 @@ import { cac } from 'cac' +import { loadConfig } from '@unocss/config' +import { toArray } from '@unocss/core' import { version } from '../package.json' import type { CliOptions } from './types' import { build } from './index' @@ -25,8 +27,15 @@ export async function startCli(cwd = process.cwd(), argv = process.argv, options if (patterns) options.patterns = patterns + const { config } = await loadConfig(cwd, options.config) - await build(options) + const entries = toArray(config.cli?.entry || options) + await Promise.all(entries.map(entry => + build({ + ...options, + ...entry, + }), + )) }) cli.help() diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index f5cd2e8995..e99f719ae0 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -512,6 +512,15 @@ export interface UserOnlyOptions { envMode?: 'dev' | 'build' } +/** + * For unocss-cli config + */ +export interface CliOptions { + cli?: { + entry?: CliEntryItem | CliEntryItem[] + } +} + export interface UnocssPluginContext { ready: Promise> uno: UnoGenerator @@ -604,7 +613,7 @@ export interface PluginOptions { transformers?: SourceCodeTransformer[] } -export interface UserConfig extends ConfigBase, UserOnlyOptions, GeneratorOptions, PluginOptions {} +export interface UserConfig extends ConfigBase, UserOnlyOptions, GeneratorOptions, PluginOptions, CliOptions {} export interface UserConfigDefaults extends ConfigBase, UserOnlyOptions {} export interface ResolvedConfig extends Omit< @@ -670,6 +679,11 @@ export type PreparedRule = readonly [ noMerge: boolean, ] +export interface CliEntryItem { + patterns: string[] + outFile: string +} + export interface UtilObject { selector: string entries: CSSEntries diff --git a/test/cli.test.ts b/test/cli.test.ts index c07be36a70..00915f288e 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -90,8 +90,75 @@ export default defineConfig({ } } }) + + it('supports unocss.config.js cli options', async () => { + const testDir = getTestDir() + + const fileName1 = 'views/index1.html' + const fileName2 = 'views/index2.html' + const Content1 = '
' + const Content2 = '
' + + await fs.outputFile(resolve(testDir, fileName1), Content1) + await fs.outputFile(resolve(testDir, fileName2), Content2) + await fs.outputFile(resolve(testDir, 'unocss.config.js'), ` +import { defineConfig } from 'unocss' +export default defineConfig({ + cli: { + entry: [ + { + patterns: ['views/index1.html'], + outFile: './uno1.css', + }, + { + patterns: ['views/index2.html'], + outFile: './test/uno2.css', + }, + ], + } }) + `.trim()) + await runAsyncChildProcess(testDir, '', '') + const outputFile1 = './uno1.css' + const outputFile2 = './test/uno2.css' + const outputPath1 = resolve(testDir, outputFile1) + const outputPath2 = resolve(testDir, outputFile2) + for (let i = 50; i >= 0; i--) { + await sleep(50) + if (fs.existsSync(outputPath1)) + break + } + for (let i = 50; i >= 0; i--) { + await sleep(50) + if (fs.existsSync(outputPath2)) + break + } + // polling until update + for (let i = 100; i >= 0; i--) { + await sleep(100) + const output1 = await readFile(testDir, outputFile1) + const output2 = await readFile(testDir, outputFile2) + if (i === 0 || output1.includes('.bg-blue')) { + expect(output1).toContain('.bg-blue') + break + } + if (i === 0 || output2.includes('.bg-red')) { + expect(output2).toContain('.bg-red') + break + } + } + + for (let i = 100; i >= 0; i--) { + await sleep(100) + const output2 = await readFile(testDir, outputFile2) + if (i === 0 || output2.includes('.bg-red')) { + expect(output2).toContain('.bg-red') + break + } + } + }) +}) // ----- Utils ----- function sleep(time = 300) { return new Promise((resolve) => {