refactor(compiler-sfc): simplify style preprocessors

This commit is contained in:
Evan You 2020-07-16 13:38:46 -04:00
parent 9cb29eea3a
commit d5055cd8dd
2 changed files with 92 additions and 103 deletions

View File

@ -213,7 +213,7 @@ function preprocess(
) )
} }
return preprocessor.render( return preprocessor(
options.source, options.source,
options.map, options.map,
{ {

View File

@ -3,17 +3,15 @@ import path from 'path'
import { RawSourceMap } from 'source-map' import { RawSourceMap } from 'source-map'
import { SFCStyleCompileOptions } from './compileStyle' import { SFCStyleCompileOptions } from './compileStyle'
export interface StylePreprocessor { export type StylePreprocessor = (
render( source: string,
source: string, map: RawSourceMap | undefined,
map: RawSourceMap | undefined, options: {
options: { [key: string]: any
[key: string]: any filename: string
filename: string },
}, customRequire: SFCStyleCompileOptions['preprocessCustomRequire']
customRequire: SFCStyleCompileOptions['preprocessCustomRequire'] ) => StylePreprocessorResults
): StylePreprocessorResults
}
export interface StylePreprocessorResults { export interface StylePreprocessorResults {
code: string code: string
@ -23,118 +21,109 @@ export interface StylePreprocessorResults {
} }
// .scss/.sass processor // .scss/.sass processor
const scss: StylePreprocessor = { const scss: StylePreprocessor = (source, map, options, load = require) => {
render(source, map, options, load = require) { const nodeSass = load('sass')
const nodeSass = load('sass') const finalOptions = {
const finalOptions = { ...options,
...options, data: source,
data: source, file: options.filename,
file: options.filename, outFile: options.filename,
outFile: options.filename, sourceMap: !!map
sourceMap: !!map
}
try {
const result = nodeSass.renderSync(finalOptions)
// sass output path is position path
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: StylePreprocessor = { try {
render(source, map, options, load) { const result = nodeSass.renderSync(finalOptions)
return scss.render( // sass output path is position path
source, const dependencies = result.stats.includedFiles
map,
{
...options,
indentedSyntax: true
},
load
)
}
}
// .less
const less: StylePreprocessor = {
render(source, map, options, load = require) {
const nodeLess = load('less')
let result: any
let error: Error | null = null
nodeLess.render(
source,
{ ...options, syncImport: true },
(err: Error | null, output: any) => {
error = err
result = output
}
)
if (error) return { code: '', errors: [error], dependencies: [] }
// less output path is relative path
const dependencies = getAbsolutePaths(
result.imports,
path.dirname(options.filename)
)
if (map) { if (map) {
return { return {
code: result.css.toString(), code: result.css.toString(),
map: merge(map, result.map), map: merge(map, JSON.parse(result.map.toString())),
errors: [], errors: [],
dependencies: dependencies dependencies
} }
} }
return { code: result.css.toString(), errors: [], dependencies }
} catch (e) {
return { code: '', errors: [e], dependencies: [] }
}
}
const sass: StylePreprocessor = (source, map, options, load) =>
scss(
source,
map,
{
...options,
indentedSyntax: true
},
load
)
// .less
const less: StylePreprocessor = (source, map, options, load = require) => {
const nodeLess = load('less')
let result: any
let error: Error | null = null
nodeLess.render(
source,
{ ...options, syncImport: true },
(err: Error | null, output: any) => {
error = err
result = output
}
)
if (error) return { code: '', errors: [error], dependencies: [] }
// less output path is relative path
const dependencies = getAbsolutePaths(
result.imports,
path.dirname(options.filename)
)
if (map) {
return { return {
code: result.css.toString(), code: result.css.toString(),
map: merge(map, result.map),
errors: [], errors: [],
dependencies: dependencies dependencies: dependencies
} }
} }
return {
code: result.css.toString(),
errors: [],
dependencies: dependencies
}
} }
// .styl // .styl
const styl: StylePreprocessor = { const styl: StylePreprocessor = (source, map, options, load = require) => {
render(source, map, options, load = require) { const nodeStylus = load('stylus')
const nodeStylus = load('stylus') try {
try { const ref = nodeStylus(source)
const ref = nodeStylus(source) Object.keys(options).forEach(key => ref.set(key, options[key]))
Object.keys(options).forEach(key => ref.set(key, options[key])) if (map) ref.set('sourcemap', { inline: false, comment: false })
if (map) ref.set('sourcemap', { inline: false, comment: false })
const result = ref.render() const result = ref.render()
// stylus output path is relative path // stylus output path is relative path
const dependencies = getAbsolutePaths( const dependencies = getAbsolutePaths(
ref.deps(), ref.deps(),
path.dirname(options.fileName) path.dirname(options.fileName)
) )
if (map) { if (map) {
return { return {
code: result, code: result,
map: merge(map, ref.sourcemap), map: merge(map, ref.sourcemap),
errors: [], errors: [],
dependencies dependencies
}
} }
return { code: result, errors: [], dependencies }
} catch (e) {
return { code: '', errors: [e], dependencies: [] }
} }
return { code: result, errors: [], dependencies }
} catch (e) {
return { code: '', errors: [e], dependencies: [] }
} }
} }