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