import merge from 'merge-source-map' ; import { RawSourceMap } from 'source-map' ; import { SFCStyleCompileOptions } from './compileStyle' ; import { isFunction } from '@vue/shared' ; export type StylePreprocessor = ( source : string , map : RawSourceMap | undefined , options : { [ key ] : any ; additionalData ? : string | ( ( source : string , filename : string ) => string ) ; filename : string ; } , customRequire : SFCStyleCompileOptions [ 'preprocessCustomRequire' ] ) => StylePreprocessorResults ; export interface StylePreprocessorResults { code : string ; map ? : object ; errors : Error [ ] ; dependencies : string [ ] ; } const scss = ( source , map , options , load = require ) => { const nodeSass = load ( 'sass' ) ; const finalOptions = { ... options , data : getSource ( source , options . filename , options . additionalData ) , file : options . filename , outFile : options . filename , sourceMap : ! ! map } ; try { const result = nodeSass . renderSync ( finalOptions ) ; const dependencies = result . stats . includedFiles ; if ( map ) { return { code : result . css . toString ( ) , map : merge ( map , JSON . parse ( result . map . toString ( ) ) ) , errors : [ ] , dependencies } ; } return { code : result . css . toString ( ) , errors : [ ] , dependencies } ; } catch ( e ) { return { code : '' , errors : [ e ] , dependencies : [ ] } ; } } ; const sass = ( source , map , options , load ) => scss ( source , map , { ... options , indentedSyntax : true } , load ) ; const less = ( source , map , options , load = require ) => { const nodeLess = load ( 'less' ) ; let result ; let error = null ; nodeLess . render ( getSource ( source , options . filename , options . additionalData ) , { ... options , syncImport : true } , ( err , output ) => { error = err ; result = output ; } ) ; if ( error ) return { code : '' , errors : [ error ] , dependencies : [ ] } ; const dependencies = result . imports ; if ( map ) { return { code : result . css . toString ( ) , map : merge ( map , result . map ) , errors : [ ] , dependencies : dependencies } ; } return { code : result . css . toString ( ) , errors : [ ] , dependencies : dependencies } ; } ; const styl = ( source , map , options , load = require ) => { const nodeStylus = load ( '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 ( ) ; const dependencies = ref . deps ( ) ; if ( map ) { return { code : result , map : merge ( map , ref . sourcemap ) , errors : [ ] , dependencies } ; } return { code : result , errors : [ ] , dependencies } ; } catch ( e ) { return { code : '' , errors : [ e ] , dependencies : [ ] } ; } } ; function getSource ( source , filename , additionalData ? ) { if ( ! additionalData ) return source ; if ( isFunction ( additionalData ) ) { return additionalData ( source , filename ) ; } return additionalData + source ; } export type PreprocessLang = 'less' | 'sass' | 'scss' | 'styl' | 'stylus' ; export const processors = { less , sass , scss , styl , stylus : styl } ;