Spaces:
Sleeping
Sleeping
const postcss = require('postcss') | |
import { ProcessOptions, LazyResult } from 'postcss' | |
import trimPlugin from './stylePlugins/trim' | |
import scopedPlugin from './stylePlugins/scoped' | |
import { | |
processors, | |
StylePreprocessor, | |
StylePreprocessorResults | |
} from './styleProcessors' | |
export interface StyleCompileOptions { | |
source: string | |
filename: string | |
id: string | |
map?: any | |
scoped?: boolean | |
trim?: boolean | |
preprocessLang?: string | |
preprocessOptions?: any | |
postcssOptions?: any | |
postcssPlugins?: any[] | |
} | |
export interface AsyncStyleCompileOptions extends StyleCompileOptions { | |
isAsync?: boolean | |
} | |
export interface StyleCompileResults { | |
code: string | |
map: any | void | |
rawResult: LazyResult | void | |
errors: string[] | |
} | |
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, | |
id, | |
scoped = true, | |
trim = true, | |
preprocessLang, | |
postcssOptions, | |
postcssPlugins | |
} = options | |
const preprocessor = preprocessLang && processors[preprocessLang] | |
const preProcessedSource = preprocessor && preprocess(options, preprocessor) | |
const map = preProcessedSource ? preProcessedSource.map : options.map | |
const source = preProcessedSource ? preProcessedSource.code : options.source | |
const plugins = (postcssPlugins || []).slice() | |
if (trim) { | |
plugins.push(trimPlugin()) | |
} | |
if (scoped) { | |
plugins.push(scopedPlugin(id)) | |
} | |
const postCSSOptions: ProcessOptions = { | |
...postcssOptions, | |
to: filename, | |
from: filename | |
} | |
if (map) { | |
postCSSOptions.map = { | |
inline: false, | |
annotation: false, | |
prev: map | |
} | |
} | |
let result, code, outMap | |
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 | |
} catch (e) { | |
errors.push(e) | |
} | |
return { | |
code: code || ``, | |
map: outMap && outMap.toJSON(), | |
errors, | |
rawResult: result | |
} | |
} | |
function preprocess( | |
options: StyleCompileOptions, | |
preprocessor: StylePreprocessor | |
): StylePreprocessorResults { | |
return preprocessor.render( | |
options.source, | |
options.map, | |
Object.assign( | |
{ | |
filename: options.filename | |
}, | |
options.preprocessOptions | |
) | |
) | |
} | |