Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use absoultePath as fileCache key #1045

Merged
merged 3 commits into from Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 8 additions & 4 deletions packages/cli/src/index.ts
Expand Up @@ -17,8 +17,10 @@ let uno: UnoGenerator

const fileCache = new Map<string, string>()

const getAbsolutePath = (file: string) => resolve(process.cwd(), file)

export async function generate(options: ResolvedCliOptions) {
const outFile = options.outFile ?? resolve(process.cwd(), 'uno.css')
const outFile = options.outFile ?? getAbsolutePath('uno.css')
const { css, matched } = await uno.generate([...fileCache].join('\n'))

const dir = dirname(outFile)
Expand Down Expand Up @@ -57,7 +59,8 @@ export async function build(_options: CliOptions) {
const files = await fg(options.patterns)
await Promise.all(
files.map(async (file) => {
fileCache.set(file, await fs.readFile(file, 'utf8'))
const absolutePath = getAbsolutePath(file)
fileCache.set(absolutePath, await fs.readFile(absolutePath, 'utf8'))
}),
)

Expand Down Expand Up @@ -103,10 +106,11 @@ export async function build(_options: CliOptions) {
else {
consola.log(`${green(type)} ${dim(file)}`)

const absolutePath = getAbsolutePath(file)
if (type.startsWith('unlink'))
fileCache.delete(file)
fileCache.delete(absolutePath)
else
fileCache.set(file, await fs.readFile(file, 'utf8'))
fileCache.set(absolutePath, await fs.readFile(absolutePath, 'utf8'))
}

debouncedBuild()
Expand Down
7 changes: 7 additions & 0 deletions test/__snapshots__/cli.test.ts.snap
Expand Up @@ -14,3 +14,10 @@ exports[`cli > supports unocss.config.js 1`] = `
/* layer: shortcuts */
.box{margin-left:auto;margin-right:auto;max-width:80rem;border-radius:0.375rem;--un-bg-opacity:1;background-color:rgba(243,244,246,var(--un-bg-opacity));padding:1rem;--un-shadow:var(--un-shadow-inset) 0 1px 2px 0 var(--un-shadow-color, rgba(0,0,0,0.05));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}"
`;

exports[`cli > uno.css exclude initialized class after changing file 1`] = `
"/* layer: preflights */
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z));--un-pan-x:var(--un-empty,/*!*/ /*!*/);--un-pan-y:var(--un-empty,/*!*/ /*!*/);--un-pinch-zoom:var(--un-empty,/*!*/ /*!*/);--un-touch-action:var(--un-pan-x) var(--un-pan-y) var(--un-pinch-zoom);--un-scroll-snap-strictness:proximity;--un-ordinal:var(--un-empty,/*!*/ /*!*/);--un-slashed-zero:var(--un-empty,/*!*/ /*!*/);--un-numeric-figure:var(--un-empty,/*!*/ /*!*/);--un-numeric-spacing:var(--un-empty,/*!*/ /*!*/);--un-numeric-fraction:var(--un-empty,/*!*/ /*!*/);--un-font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction);--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:var(--un-empty,/*!*/ /*!*/);--un-shadow:0 0 #0000;--un-ring-inset:var(--un-empty,/*!*/ /*!*/);--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur:var(--un-empty,/*!*/ /*!*/);--un-brightness:var(--un-empty,/*!*/ /*!*/);--un-contrast:var(--un-empty,/*!*/ /*!*/);--un-drop-shadow:var(--un-empty,/*!*/ /*!*/);--un-grayscale:var(--un-empty,/*!*/ /*!*/);--un-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-invert:var(--un-empty,/*!*/ /*!*/);--un-saturate:var(--un-empty,/*!*/ /*!*/);--un-sepia:var(--un-empty,/*!*/ /*!*/);--un-filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);--un-backdrop-blur:var(--un-empty,/*!*/ /*!*/);--un-backdrop-brightness:var(--un-empty,/*!*/ /*!*/);--un-backdrop-contrast:var(--un-empty,/*!*/ /*!*/);--un-backdrop-grayscale:var(--un-empty,/*!*/ /*!*/);--un-backdrop-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-invert:var(--un-empty,/*!*/ /*!*/);--un-backdrop-opacity:var(--un-empty,/*!*/ /*!*/);--un-backdrop-saturate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-sepia:var(--un-empty,/*!*/ /*!*/);--un-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}
/* layer: default */
.bg-blue{--un-bg-opacity:1;background-color:rgba(96,165,250,var(--un-bg-opacity));}"
TrickyPi marked this conversation as resolved.
Show resolved Hide resolved
`;
73 changes: 67 additions & 6 deletions test/cli.test.ts
Expand Up @@ -6,6 +6,29 @@ import { execa } from 'execa'
export const tempDir = resolve('.temp')
export const cli = resolve(__dirname, '../packages/cli/src/cli.ts')

function createWaiting() {
const loop = () => { }
let $resolve = loop
let $reject = loop
const waiting = new Promise<void>((resolve, reject) => {
$resolve = resolve
$reject = reject
})
return {
waiting,
$resolve,
$reject,
}
}

function sleep(time = 300) {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve()
}, time)
})
}

beforeAll(async () => {
await fs.remove(tempDir)
})
Expand All @@ -23,6 +46,28 @@ describe('cli', () => {
expect(output).toMatchSnapshot()
})

it('uno.css exclude initialized class after changing file', async () => {
const fileName = 'views/index.html'
const initializedContent = '<div class="bg-blue"></div>'
const changedContent = '<div class="bg-red"></div>'
const testDir = getTestDir()
const absolutePathOfFile = resolve(testDir, fileName)
await fs.outputFile(absolutePathOfFile, initializedContent)
const subProcess = runAsyncChildProcess(testDir, './views/**/*', '-w')
const { stdout } = subProcess
const { waiting, $resolve } = createWaiting()
stdout!.on('data', (data) => {
if (data.toString().includes('[info] Watching for changes'))
$resolve()
})
await waiting
await fs.writeFile(absolutePathOfFile, changedContent)
await sleep(2022)
subProcess.cancel()
const output = await readUnocssFile(testDir)
expect(output).toMatchSnapshot()
})

it('supports unocss.config.js', async () => {
const { output } = await runCli({
'views/index.html': '<div class="box"></div>',
Expand All @@ -38,25 +83,41 @@ export default defineConfig({
})
})

async function runCli(files: Record<string, string>) {
const testDir = resolve(tempDir, Math.round(Math.random() * 100000).toString())
function getTestDir() {
return resolve(tempDir, Math.round(Math.random() * 100000).toString())
}

await Promise.all(
function initalOutputFiles(testDir: string, files: Record<string, string>) {
return Promise.all(
Object.entries(files).map(([path, content]) =>
fs.outputFile(resolve(testDir, path), content, 'utf8'),
),
)
}

const { exitCode, stdout, stderr } = await execa('npx', ['esno', cli, 'views/**/*'], {
cwd: testDir,
function runAsyncChildProcess(cwd: string, ...args: string[]) {
return execa('npx', ['esno', cli, ...args], {
cwd,
// stdio: 'inherit',
})
}

function readUnocssFile(testDir: string) {
return fs.readFile(resolve(testDir, 'uno.css'), 'utf8')
}

async function runCli(files: Record<string, string>) {
const testDir = getTestDir()

await initalOutputFiles(testDir, files)

const { exitCode, stdout, stderr } = await runAsyncChildProcess(testDir, 'views/**/*')

const logs = stdout + stderr
if (exitCode !== 0)
throw new Error(logs)

const output = await fs.readFile(resolve(testDir, 'uno.css'), 'utf8')
const output = await readUnocssFile(testDir)

return {
output,
Expand Down