|
|
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 ) )}
|