144 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
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
 | 
						|
    )
 | 
						|
  )
 | 
						|
}
 |