Skip to content

Commit

Permalink
feat: new touchMode options (#7)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
deleonio and antfu authored Apr 9, 2021
1 parent 78576da commit f94d1d7
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 20 deletions.
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ Install `postcss-windicss` from NPM
npm i -D postcss-windicss
```

Create `postcss.config.js` under your project root
Create `postcss.config.js` under your project root.

```js
// postcss.config.js
module.exports = {
plugins: {
'postcss-windicss': { /* ... */ },
'postcss-windicss': {
/* Options */
},
},
}
```
Expand Down Expand Up @@ -57,9 +59,9 @@ You can pass options to the plugin by
module.exports = {
plugins: {
'postcss-windicss': {
config: 'path/to/windi.config.js' // by default it will try to find it in your project root
},
},
config: 'path/to/windi.config.js', // by default it will try to find it in your project root
}
}
}
```

Expand All @@ -76,6 +78,23 @@ cross-env NODE_ENV=production npm run build # production mode
cross-env NODE_ENV=development npm run build # development mode
```

## Touch Mode

By default, this plugin "touches" your css entry by updating the file's "updated time" (utime) to trigger the hot reload without changing its content.

It should work most of the time. But for some tools, they might also compare the file's content to avoid unnecessary hot reloads. In that cases, you will need to specify `touchMode` to `insert-comment` to get proper style updates with those tools.

```js
// postcss.config.js
module.exports = {
plugins: {
'postcss-windicss': {
touchMode: 'insert-comment' // <--
}
}
}
```

## Progress

### Features
Expand Down
4 changes: 3 additions & 1 deletion examples/vite/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
plugins: {
'postcss-windicss': {},
'postcss-windicss': {
// touchMode: 'insert-comment',
},
},
}
21 changes: 17 additions & 4 deletions src/context.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { WindiPluginUtils } from '@windicss/plugin-utils'
import { WindiPluginUtils, WindiPluginUtilsOptions } from '@windicss/plugin-utils'
import _debug from 'debug'

export interface WindiPostCSSPluginOptions extends WindiPluginUtilsOptions {
/**
* By default, this plugin "touches" your css entry by updating the file's
* "updated time" (utime) to trigger the hot reload without changing its content.
*
* It should work most of the time. But for some tools, they might also compare
* the file's content to avoid unnecessary hot reloads. In that cases, you will
* need to specify this option to "insert-comment" to get proper style updates with
* those tools.
*
* @default 'utime'
*/
touchMode?: 'utime' | 'insert-comment'
}

export interface Context {
entry?: string
utils?: WindiPluginUtils
}

export const context: Context = {

}
export const context: Context = {}

export const isDev = process.env.NODE_ENV === 'development'
export const debug = _debug('postcss-windicss')
12 changes: 8 additions & 4 deletions src/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { promises as fs } from 'fs'
import chokidar, { FSWatcher } from 'chokidar'
import exitHook from 'exit-hook'
import { touch } from './utils'
import { context, debug } from './context'
import { context, debug, WindiPostCSSPluginOptions } from './context'

let watcher: FSWatcher | undefined

Expand All @@ -15,13 +15,17 @@ export function shutdownWatcher() {
}
exitHook(shutdownWatcher)

export async function startDevWatcher() {
export async function startDevWatcher(options: WindiPostCSSPluginOptions) {
shutdownWatcher()

debug('starting dev watcher')
const utils = context.utils!
await utils.ensureInit()

const {
touchMode = 'utime',
} = options

watcher = chokidar
.watch(utils.options.scanOptions.include, {
ignored: utils.options.scanOptions.exclude,
Expand All @@ -42,9 +46,9 @@ export async function startDevWatcher() {
debug('update from', path)
await utils!.extractFile(await fs.readFile(path, 'utf-8'))
if (context.entry)
touch(context.entry)
await touch(context.entry, touchMode)
})

if (context.entry)
touch(context.entry)
await touch(context.entry, touchMode)
}
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { Plugin } from 'postcss'
import { parse } from 'postcss'
import { createUtils, WindiPluginUtilsOptions } from '@windicss/plugin-utils'
import { createUtils } from '@windicss/plugin-utils'
import { startDevWatcher } from './dev'
import { context, debug, isDev } from './context'
import { context, debug, isDev, WindiPostCSSPluginOptions } from './context'

const plugin = (options: WindiPluginUtilsOptions = {}): Plugin => {
const plugin = (options: WindiPostCSSPluginOptions): Plugin => {
if (!context.utils) {
context.utils = createUtils({
...options,
onOptionsResolved() {
if (isDev)
setTimeout(() => startDevWatcher())
setTimeout(() => startDevWatcher(options))
},
}, {
name: 'postcss-windicss',
Expand Down
26 changes: 24 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
import { close, open, utimes } from 'fs'
import { promises as fs, utimes, open, close } from 'fs'

export function touch(path: string) {
export async function touch(path: string, mode: 'utime' | 'insert-comment' = 'utime') {
if (mode === 'utime')
return await touchUtime(path)
else
return await touchInsert(path)
}

const TOUCH_REG = /\/\*\s*windicss-touch:.*\*\//

export async function touchInsert(path: string) {
let css = await fs.readFile(path, 'utf-8')
const banner = `/* windicss-touch: ${Date.now()} */`
let replaced = false
css = css.replace(TOUCH_REG, () => {
replaced = true
return banner
})
if (!replaced)
css = `${banner}\n${css}`
await fs.writeFile(path, css, 'utf-8')
}

export async function touchUtime(path: string) {
return new Promise((resolve, reject) => {
const time = new Date()
utimes(path, time, time, (err) => {
Expand Down

0 comments on commit f94d1d7

Please sign in to comment.