From 8543352c0b850635c300575b77976cbada6e95e7 Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Sun, 25 Sep 2022 17:10:20 +0800 Subject: [PATCH 1/8] chore: add CliOptions type --- packages/core/src/types.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index f5cd2e8995..c836178066 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -512,6 +512,13 @@ export interface UserOnlyOptions { envMode?: 'dev' | 'build' } +/** + * For unocss-cli config + */ +export interface CliOptions { + cliOptions?: CliOptionItem[] +} + export interface UnocssPluginContext { ready: Promise> uno: UnoGenerator @@ -604,7 +611,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 +677,11 @@ export type PreparedRule = readonly [ noMerge: boolean, ] +export interface CliOptionItem { + patterns: string[] + outFile: string +} + export interface UtilObject { selector: string entries: CSSEntries From edc803b2368219f5b6fb068d9370632215df983c Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Sun, 25 Sep 2022 17:11:17 +0800 Subject: [PATCH 2/8] feat: support unocss config for cli --- packages/cli/src/cli-start.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/cli-start.ts b/packages/cli/src/cli-start.ts index b604dbefe2..cdd5cf78fb 100644 --- a/packages/cli/src/cli-start.ts +++ b/packages/cli/src/cli-start.ts @@ -1,4 +1,5 @@ import { cac } from 'cac' +import { loadConfig } from '@unocss/config' import { version } from '../package.json' import type { CliOptions } from './types' import { build } from './index' @@ -25,8 +26,17 @@ export async function startCli(cwd = process.cwd(), argv = process.argv, options if (patterns) options.patterns = patterns - - await build(options) + const { config } = await loadConfig(cwd, options.config) + if (config?.cliOptions && config.cliOptions.length !== 0) { + for (let i = 0; i < config.cliOptions.length; i++) { + options.patterns = config.cliOptions[i].patterns + options.outFile = config.cliOptions[i].outFile + await build(options) + } + } + else { + await build(options) + } }) cli.help() From 02fbcbd68662388c6182c459c2f0558efb576d0e Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Sun, 25 Sep 2022 17:11:43 +0800 Subject: [PATCH 3/8] feat: add unocss config for cli test --- test/cli.test.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/test/cli.test.ts b/test/cli.test.ts index c07be36a70..0db7adf7cd 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -90,6 +90,71 @@ export default defineConfig({ } } }) + + it('supports unocss.config.js cliOptions', async () => { + const testDir = getTestDir() + const fileName1 = 'views/index1.html' + const fileName2 = 'views/index2.html' + const Content1 = '
' + const Content2 = '
' + const absolutePathOfFile1 = resolve(testDir, fileName1) + const absolutePathOfFile2 = resolve(testDir, fileName2) + await fs.outputFile(absolutePathOfFile1, Content1) + await fs.outputFile(absolutePathOfFile2, Content2) + await fs.outputFile(resolve(testDir, 'unocss.config.js'), ` + import { defineConfig, transformerVariantGroup } from 'unocss' +export default defineConfig({ + cliOptions:[ + { + patterns:['views/index1.html'], + outFile:'./uno1.css', + }, + { + patterns:['views/index2.html'], + outFile:'./test/uno2.css', + }, + ], +}) + `) + 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 ----- From 2eadf5309c67799a72f76e19a07b854fa4438a47 Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Mon, 26 Sep 2022 11:20:01 +0800 Subject: [PATCH 4/8] chore: update api --- packages/cli/src/cli-start.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/cli-start.ts b/packages/cli/src/cli-start.ts index cdd5cf78fb..c500556df1 100644 --- a/packages/cli/src/cli-start.ts +++ b/packages/cli/src/cli-start.ts @@ -27,13 +27,20 @@ export async function startCli(cwd = process.cwd(), argv = process.argv, options if (patterns) options.patterns = patterns const { config } = await loadConfig(cwd, options.config) - if (config?.cliOptions && config.cliOptions.length !== 0) { - for (let i = 0; i < config.cliOptions.length; i++) { - options.patterns = config.cliOptions[i].patterns - options.outFile = config.cliOptions[i].outFile + if (config?.cli && Array.isArray(config.cli.entry) && config.cli.entry.length !== 0) { + const len = config.cli.entry.length + const cliEntryItems = config.cli.entry + for (let i = 0; i < len; i++) { + options.patterns = cliEntryItems[i].patterns + options.outFile = cliEntryItems[i].outFile await build(options) } } + else if (config?.cli && !Array.isArray(config.cli.entry) && typeof config.cli.entry === 'object' && Object.keys(config.cli.entry).length !== 0) { + options.patterns = config.cli.entry?.patterns + options.outFile = config.cli.entry?.outFile + await build(options) + } else { await build(options) } From 351ea09e99e03f6663b0f9f045100c449298985b Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Mon, 26 Sep 2022 11:20:46 +0800 Subject: [PATCH 5/8] chore: update types --- packages/core/src/types.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index c836178066..e99f719ae0 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -516,7 +516,9 @@ export interface UserOnlyOptions { * For unocss-cli config */ export interface CliOptions { - cliOptions?: CliOptionItem[] + cli?: { + entry?: CliEntryItem | CliEntryItem[] + } } export interface UnocssPluginContext { @@ -677,7 +679,7 @@ export type PreparedRule = readonly [ noMerge: boolean, ] -export interface CliOptionItem { +export interface CliEntryItem { patterns: string[] outFile: string } From 2e6b768f6951c42994ebfcd35b4635d9637e7afc Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Mon, 26 Sep 2022 11:21:02 +0800 Subject: [PATCH 6/8] chore: add test --- test/cli.test.ts | 145 +++++++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 54 deletions(-) diff --git a/test/cli.test.ts b/test/cli.test.ts index 0db7adf7cd..1c1ca5f7ed 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -16,7 +16,7 @@ afterAll(async () => { describe('cli', () => { it('builds uno.css', async () => { - const { output } = await runCli({ + const {output} = await runCli({ 'views/index.html': '
', }) @@ -24,7 +24,7 @@ describe('cli', () => { }) it('supports unocss.config.js', async () => { - const { output } = await runCli({ + const {output} = await runCli({ 'views/index.html': '
', 'unocss.config.js': ` import { defineConfig } from 'unocss' @@ -38,7 +38,7 @@ export default defineConfig({ }) it('supports variantGroup transformer', async () => { - const { output, transform } = await runCli({ + const {output, transform} = await runCli({ 'views/index.html': '
', 'unocss.config.js': ` import { defineConfig, transformerVariantGroup } from 'unocss' @@ -52,7 +52,7 @@ export default defineConfig({ }) it('supports directives transformer', async () => { - const { output, transform } = await runCli({ + const {output, transform} = await runCli({ 'views/index.css': '.btn-center{@apply text-center my-0 font-medium;}', 'unocss.config.js': ` import { defineConfig, transformerDirectives } from 'unocss' @@ -91,7 +91,7 @@ export default defineConfig({ } }) - it('supports unocss.config.js cliOptions', async () => { + it('supports unocss.config.js cliOptions CliEntryItem array', async () => { const testDir = getTestDir() const fileName1 = 'views/index1.html' const fileName2 = 'views/index2.html' @@ -102,20 +102,22 @@ export default defineConfig({ await fs.outputFile(absolutePathOfFile1, Content1) await fs.outputFile(absolutePathOfFile2, Content2) await fs.outputFile(resolve(testDir, 'unocss.config.js'), ` - import { defineConfig, transformerVariantGroup } from 'unocss' + import { defineConfig } from 'unocss' export default defineConfig({ - cliOptions:[ - { - patterns:['views/index1.html'], - outFile:'./uno1.css', - }, - { - patterns:['views/index2.html'], - outFile:'./test/uno2.css', - }, - ], + 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' @@ -155,54 +157,89 @@ export default defineConfig({ } } }) -}) -// ----- Utils ----- -function sleep(time = 300) { - return new Promise((resolve) => { - setTimeout(() => { - resolve() - }, time) + it('supports unocss.config.js cliOptions CliEntryItem Object', async () => { + const testDir = getTestDir() + const fileName1 = 'views/index1.html' + const Content1 = '
' + const absolutePathOfFile1 = resolve(testDir, fileName1) + await fs.outputFile(absolutePathOfFile1, Content1) + await fs.outputFile(resolve(testDir, 'unocss.config.js'), ` + import { defineConfig, transformerVariantGroup } from 'unocss' +export default defineConfig({ + cli:{ + entry:{ + patterns: ['views/index1.html'], + outFile: 'uno1.css', + } + }, +}) + `) + await runAsyncChildProcess(testDir, '', '') + const outputFile1 = './uno1.css' + const outputPath1 = resolve(testDir, outputFile1) + for (let i = 50; i >= 0; i--) { + await sleep(50) + if (fs.existsSync(outputPath1)) + break + } + // polling until update + for (let i = 100; i >= 0; i--) { + await sleep(100) + const output1 = await readFile(testDir, outputFile1) + if (i === 0 || output1.includes('.bg-blue')) { + expect(output1).toContain('.bg-blue') + break + } + } }) -} +}) +// ----- Utils ----- + function sleep(time = 300) { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, time) + }) + } -function getTestDir() { - return resolve(tempDir, Math.round(Math.random() * 100000).toString()) -} + function getTestDir() { + return resolve(tempDir, Math.round(Math.random() * 100000).toString()) + } -function initOutputFiles(testDir: string, files: Record) { - return Promise.all( - Object.entries(files).map(([path, content]) => - fs.outputFile(resolve(testDir, path), content, 'utf8'), - ), - ) -} + function initOutputFiles(testDir: string, files: Record) { + return Promise.all( + Object.entries(files).map(([path, content]) => + fs.outputFile(resolve(testDir, path), content, 'utf8'), + ), + ) + } -function runAsyncChildProcess(cwd: string, ...args: string[]) { - return startCli(cwd, ['', '', ...args, '--no-preflights']) -} + function runAsyncChildProcess(cwd: string, ...args: string[]) { + return startCli(cwd, ['', '', ...args, '--no-preflights']) + } -function readFile(testDir: string, targetFile?: string) { - return fs.readFile(resolve(testDir, targetFile ?? 'uno.css'), 'utf8') -} + function readFile(testDir: string, targetFile?: string) { + return fs.readFile(resolve(testDir, targetFile ?? 'uno.css'), 'utf8') + } -async function runCli(files: Record, transformFile?: string) { - const testDir = getTestDir() + async function runCli(files: Record, transformFile?: string) { + const testDir = getTestDir() - await initOutputFiles(testDir, files) - await runAsyncChildProcess(testDir, 'views/**/*') + await initOutputFiles(testDir, files) + await runAsyncChildProcess(testDir, 'views/**/*') - const output = await readFile(testDir) + const output = await readFile(testDir) + + if (transformFile) { + const transform = await readFile(testDir, transformFile) + return { + output, + transform, + } + } - if (transformFile) { - const transform = await readFile(testDir, transformFile) return { output, - transform, } } - - return { - output, - } -} From 6c06fc51807087b157400de1916651fa963fc3ed Mon Sep 17 00:00:00 2001 From: Frozen FIsh <976499226@qq.com> Date: Mon, 26 Sep 2022 11:21:43 +0800 Subject: [PATCH 7/8] chore: lint fix --- test/cli.test.ts | 80 ++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/test/cli.test.ts b/test/cli.test.ts index 1c1ca5f7ed..a2775968bb 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -16,7 +16,7 @@ afterAll(async () => { describe('cli', () => { it('builds uno.css', async () => { - const {output} = await runCli({ + const { output } = await runCli({ 'views/index.html': '
', }) @@ -24,7 +24,7 @@ describe('cli', () => { }) it('supports unocss.config.js', async () => { - const {output} = await runCli({ + const { output } = await runCli({ 'views/index.html': '
', 'unocss.config.js': ` import { defineConfig } from 'unocss' @@ -38,7 +38,7 @@ export default defineConfig({ }) it('supports variantGroup transformer', async () => { - const {output, transform} = await runCli({ + const { output, transform } = await runCli({ 'views/index.html': '
', 'unocss.config.js': ` import { defineConfig, transformerVariantGroup } from 'unocss' @@ -52,7 +52,7 @@ export default defineConfig({ }) it('supports directives transformer', async () => { - const {output, transform} = await runCli({ + const { output, transform } = await runCli({ 'views/index.css': '.btn-center{@apply text-center my-0 font-medium;}', 'unocss.config.js': ` import { defineConfig, transformerDirectives } from 'unocss' @@ -195,51 +195,51 @@ export default defineConfig({ }) }) // ----- Utils ----- - function sleep(time = 300) { - return new Promise((resolve) => { - setTimeout(() => { - resolve() - }, time) - }) - } +function sleep(time = 300) { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, time) + }) +} - function getTestDir() { - return resolve(tempDir, Math.round(Math.random() * 100000).toString()) - } +function getTestDir() { + return resolve(tempDir, Math.round(Math.random() * 100000).toString()) +} - function initOutputFiles(testDir: string, files: Record) { - return Promise.all( - Object.entries(files).map(([path, content]) => - fs.outputFile(resolve(testDir, path), content, 'utf8'), - ), - ) - } +function initOutputFiles(testDir: string, files: Record) { + return Promise.all( + Object.entries(files).map(([path, content]) => + fs.outputFile(resolve(testDir, path), content, 'utf8'), + ), + ) +} - function runAsyncChildProcess(cwd: string, ...args: string[]) { - return startCli(cwd, ['', '', ...args, '--no-preflights']) - } +function runAsyncChildProcess(cwd: string, ...args: string[]) { + return startCli(cwd, ['', '', ...args, '--no-preflights']) +} - function readFile(testDir: string, targetFile?: string) { - return fs.readFile(resolve(testDir, targetFile ?? 'uno.css'), 'utf8') - } +function readFile(testDir: string, targetFile?: string) { + return fs.readFile(resolve(testDir, targetFile ?? 'uno.css'), 'utf8') +} - async function runCli(files: Record, transformFile?: string) { - const testDir = getTestDir() - - await initOutputFiles(testDir, files) - await runAsyncChildProcess(testDir, 'views/**/*') +async function runCli(files: Record, transformFile?: string) { + const testDir = getTestDir() - const output = await readFile(testDir) + await initOutputFiles(testDir, files) + await runAsyncChildProcess(testDir, 'views/**/*') - if (transformFile) { - const transform = await readFile(testDir, transformFile) - return { - output, - transform, - } - } + const output = await readFile(testDir) + if (transformFile) { + const transform = await readFile(testDir, transformFile) return { output, + transform, } } + + return { + output, + } +} From 62bedd5c9227666f1c0cf0d83d94fac507630500 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 26 Sep 2022 11:46:49 +0800 Subject: [PATCH 8/8] chore: update --- packages/cli/src/cli-start.ts | 26 ++++++--------- test/cli.test.ts | 61 ++++++++--------------------------- 2 files changed, 22 insertions(+), 65 deletions(-) diff --git a/packages/cli/src/cli-start.ts b/packages/cli/src/cli-start.ts index c500556df1..558df0cb6f 100644 --- a/packages/cli/src/cli-start.ts +++ b/packages/cli/src/cli-start.ts @@ -1,5 +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' @@ -27,23 +28,14 @@ export async function startCli(cwd = process.cwd(), argv = process.argv, options if (patterns) options.patterns = patterns const { config } = await loadConfig(cwd, options.config) - if (config?.cli && Array.isArray(config.cli.entry) && config.cli.entry.length !== 0) { - const len = config.cli.entry.length - const cliEntryItems = config.cli.entry - for (let i = 0; i < len; i++) { - options.patterns = cliEntryItems[i].patterns - options.outFile = cliEntryItems[i].outFile - await build(options) - } - } - else if (config?.cli && !Array.isArray(config.cli.entry) && typeof config.cli.entry === 'object' && Object.keys(config.cli.entry).length !== 0) { - options.patterns = config.cli.entry?.patterns - options.outFile = config.cli.entry?.outFile - await build(options) - } - else { - await build(options) - } + + const entries = toArray(config.cli?.entry || options) + await Promise.all(entries.map(entry => + build({ + ...options, + ...entry, + }), + )) }) cli.help() diff --git a/test/cli.test.ts b/test/cli.test.ts index a2775968bb..00915f288e 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -91,33 +91,34 @@ export default defineConfig({ } }) - it('supports unocss.config.js cliOptions CliEntryItem array', async () => { + 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 = '
' - const absolutePathOfFile1 = resolve(testDir, fileName1) - const absolutePathOfFile2 = resolve(testDir, fileName2) - await fs.outputFile(absolutePathOfFile1, Content1) - await fs.outputFile(absolutePathOfFile2, 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' +import { defineConfig } from 'unocss' export default defineConfig({ - cli:{ - entry:[ + cli: { + entry: [ { - patterns:['views/index1.html'], - outFile:'./uno1.css', + patterns: ['views/index1.html'], + outFile: './uno1.css', }, { - patterns:['views/index2.html'], - outFile:'./test/uno2.css', + patterns: ['views/index2.html'], + outFile: './test/uno2.css', }, ], } }) `.trim()) + await runAsyncChildProcess(testDir, '', '') const outputFile1 = './uno1.css' const outputFile2 = './test/uno2.css' @@ -157,42 +158,6 @@ export default defineConfig({ } } }) - - it('supports unocss.config.js cliOptions CliEntryItem Object', async () => { - const testDir = getTestDir() - const fileName1 = 'views/index1.html' - const Content1 = '
' - const absolutePathOfFile1 = resolve(testDir, fileName1) - await fs.outputFile(absolutePathOfFile1, Content1) - await fs.outputFile(resolve(testDir, 'unocss.config.js'), ` - import { defineConfig, transformerVariantGroup } from 'unocss' -export default defineConfig({ - cli:{ - entry:{ - patterns: ['views/index1.html'], - outFile: 'uno1.css', - } - }, -}) - `) - await runAsyncChildProcess(testDir, '', '') - const outputFile1 = './uno1.css' - const outputPath1 = resolve(testDir, outputFile1) - for (let i = 50; i >= 0; i--) { - await sleep(50) - if (fs.existsSync(outputPath1)) - break - } - // polling until update - for (let i = 100; i >= 0; i--) { - await sleep(100) - const output1 = await readFile(testDir, outputFile1) - if (i === 0 || output1.includes('.bg-blue')) { - expect(output1).toContain('.bg-blue') - break - } - } - }) }) // ----- Utils ----- function sleep(time = 300) {