134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| const merge = require('merge-source-map')
 | |
| 
 | |
| export interface StylePreprocessor {
 | |
|   render(
 | |
|     source: string,
 | |
|     map: any | null,
 | |
|     options: any
 | |
|   ): StylePreprocessorResults
 | |
| }
 | |
| 
 | |
| export interface StylePreprocessorResults {
 | |
|   code: string
 | |
|   map?: any
 | |
|   errors: Array<Error>
 | |
| }
 | |
| 
 | |
| // .scss/.sass processor
 | |
| const scss: StylePreprocessor = {
 | |
|   render(
 | |
|     source: string,
 | |
|     map: any | null,
 | |
|     options: any
 | |
|   ): StylePreprocessorResults {
 | |
|     const nodeSass = require('sass')
 | |
|     const finalOptions = Object.assign({}, options, {
 | |
|       data: source,
 | |
|       file: options.filename,
 | |
|       outFile: options.filename,
 | |
|       sourceMap: !!map
 | |
|     })
 | |
| 
 | |
|     try {
 | |
|       const result = nodeSass.renderSync(finalOptions)
 | |
| 
 | |
|       if (map) {
 | |
|         return {
 | |
|           code: result.css.toString(),
 | |
|           map: merge(map, JSON.parse(result.map.toString())),
 | |
|           errors: []
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return { code: result.css.toString(), errors: [] }
 | |
|     } catch (e) {
 | |
|       return { code: '', errors: [e] }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| const sass = {
 | |
|   render(
 | |
|     source: string,
 | |
|     map: any | null,
 | |
|     options: any
 | |
|   ): StylePreprocessorResults {
 | |
|     return scss.render(
 | |
|       source,
 | |
|       map,
 | |
|       Object.assign({}, options, { indentedSyntax: true })
 | |
|     )
 | |
|   }
 | |
| }
 | |
| 
 | |
| // .less
 | |
| const less = {
 | |
|   render(
 | |
|     source: string,
 | |
|     map: any | null,
 | |
|     options: any
 | |
|   ): StylePreprocessorResults {
 | |
|     const nodeLess = require('less')
 | |
| 
 | |
|     let result: any
 | |
|     let error: Error | null = null
 | |
|     nodeLess.render(
 | |
|       source,
 | |
|       Object.assign({}, options, { syncImport: true }),
 | |
|       (err: Error | null, output: any) => {
 | |
|         error = err
 | |
|         result = output
 | |
|       }
 | |
|     )
 | |
| 
 | |
|     if (error) return { code: '', errors: [error] }
 | |
| 
 | |
|     if (map) {
 | |
|       return {
 | |
|         code: result.css.toString(),
 | |
|         map: merge(map, result.map),
 | |
|         errors: []
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return { code: result.css.toString(), errors: [] }
 | |
|   }
 | |
| }
 | |
| 
 | |
| // .styl
 | |
| const styl = {
 | |
|   render(
 | |
|     source: string,
 | |
|     map: any | null,
 | |
|     options: any
 | |
|   ): StylePreprocessorResults {
 | |
|     const nodeStylus = require('stylus')
 | |
|     try {
 | |
|       const ref = nodeStylus(source)
 | |
|       Object.keys(options).forEach(key => ref.set(key, options[key]))
 | |
|       if (map) ref.set('sourcemap', { inline: false, comment: false })
 | |
| 
 | |
|       const result = ref.render()
 | |
|       if (map) {
 | |
|         return {
 | |
|           code: result,
 | |
|           map: merge(map, ref.sourcemap),
 | |
|           errors: []
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return { code: result, errors: [] }
 | |
|     } catch (e) {
 | |
|       return { code: '', errors: [e] }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| export const processors: { [key: string]: StylePreprocessor } = {
 | |
|   less,
 | |
|   sass,
 | |
|   scss,
 | |
|   styl,
 | |
|   stylus: styl
 | |
| }
 |