Skip to content

Commit

Permalink
feat: Add async style compilation support (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
znck authored and yyx990803 committed Jun 1, 2018
1 parent a3bb34e commit 54464d6
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ interface StyleCompileOptions {
map?: any
scoped?: boolean
trim?: boolean
preprocessLang?: string
preprocessOptions?: any
postcssOptions?: any
postcssPlugins?: any[]
}

interface StyleCompileResults {
Expand All @@ -125,3 +129,7 @@ interface StyleCompileResults {
errors: string[]
}
```

### compileStyleAsync(StyleCompileOptions)

Same as `compileStyle(StyleCompileOptions)` but it returns a Promise resolving to `StyleCompileResults`. It can be used with async postcss plugins.
36 changes: 35 additions & 1 deletion lib/compileStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export interface StyleCompileOptions {
postcssPlugins?: any[]
}

export interface AsyncStyleCompileOptions extends StyleCompileOptions {
isAsync?: boolean
}

export interface StyleCompileResults {
code: string
map: any | void
Expand All @@ -26,6 +30,18 @@ export interface StyleCompileResults {

export function compileStyle (
options: StyleCompileOptions
): StyleCompileResults {
return doCompileStyle({ ...options, isAsync: false })
}

export function compileStyleAsync (
options: StyleCompileOptions
): Promise<StyleCompileResults> {
return Promise.resolve(doCompileStyle({ ...options, isAsync: true }))
}

export function doCompileStyle (
options: AsyncStyleCompileOptions
): StyleCompileResults {
const {
filename,
Expand Down Expand Up @@ -63,12 +79,30 @@ export function compileStyle (
}

let result, code, outMap
const errors = []
const errors: any[] = []
if (preProcessedSource && preProcessedSource.errors.length) {
errors.push(...preProcessedSource.errors)
}
try {
result = postcss(plugins).process(source, postCSSOptions)

// In async mode, return a promise.
if (options.isAsync) {
return result
.then((result: LazyResult): StyleCompileResults => ({
code: result.css || '',
map: result.map && result.map.toJSON(),
errors,
rawResult: result
}))
.catch((error: Error): StyleCompileResults => ({
code: '',
map: undefined,
errors: [...errors, error.message],
rawResult: undefined
}))
}

// force synchronous transform (we know we only have sync plugins)
code = result.css
outMap = result.map
Expand Down
4 changes: 3 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {

import {
compileStyle,
compileStyleAsync,
StyleCompileOptions,
StyleCompileResults
} from './compileStyle'
Expand All @@ -21,7 +22,8 @@ import {
export {
parse,
compileTemplate,
compileStyle
compileStyle,
compileStyleAsync
}

// types
Expand Down
33 changes: 31 additions & 2 deletions test/compileStyle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { parse } from '../lib/parse'
import { compileStyle } from '../lib/compileStyle'
import { compileStyle, compileStyleAsync } from '../lib/compileStyle'

test('preprocess less', () => {
const style = parse({
Expand Down Expand Up @@ -122,5 +122,34 @@ test('custom postcss options', () => {
postcssOptions: { random: 'foo' }
})

expect((<any>result.rawResult).opts.random).toBe('foo')
expect((result.rawResult).opts.random).toBe('foo')
})

test('async postcss plugin in sync mode', () => {
const result = compileStyle({
id: 'v-scope-xxx',
filename: 'example.vue',
source: '.foo { color: red }',
scoped: false,
postcssPlugins: [require('postcss').plugin('test-plugin', () => async (result) => result)]
})

expect(result.errors).toHaveLength(1)
})


test('async postcss plugin', async () => {
const promise = compileStyleAsync({
id: 'v-scope-xxx',
filename: 'example.vue',
source: '.foo { color: red }',
scoped: false,
postcssPlugins: [require('postcss').plugin('test-plugin', () => async (result) => result)]
})

expect(promise instanceof Promise).toBe(true)

const result = await promise
expect(result.errors).toHaveLength(0)
expect(result.code).toEqual(expect.stringContaining('color: red'))
})

0 comments on commit 54464d6

Please sign in to comment.