From 066d514d757fb7e8844104210d7d04cc11598fef Mon Sep 17 00:00:00 2001 From: underfin Date: Wed, 16 Sep 2020 21:28:31 +0800 Subject: [PATCH] feat(compiler-sfc): `additionalData` support for css preprocessors (#2126) close https://github.com/vitejs/vite/issues/520 --- .../__tests__/compileStyle.spec.ts | 30 ++++++++++++++++++- .../compiler-sfc/src/stylePreprocessors.ts | 18 +++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index 46a34463..ce837470 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -337,7 +337,7 @@ describe('SFC style preprocessors', () => { ]) }) - test('scss respect user-defined options.additionalData', () => { + test('scss respect user-defined string options.additionalData', () => { const res = compileStyle({ preprocessOptions: { additionalData: ` @@ -358,4 +358,32 @@ describe('SFC style preprocessors', () => { expect(res.errors.length).toBe(0) }) + + test('scss respect user-defined function options.additionalData', () => { + const source = ` + .square { + @include square(100px); + } + ` + const filename = path.resolve(__dirname, './fixture/test.scss') + const res = compileStyle({ + preprocessOptions: { + additionalData: (s: string, f: string) => { + expect(s).toBe(source) + expect(f).toBe(filename) + return ` + @mixin square($size) { + width: $size; + height: $size; + }` + } + }, + source, + filename, + id: '', + preprocessLang: 'scss' + }) + + expect(res.errors.length).toBe(0) + }) }) diff --git a/packages/compiler-sfc/src/stylePreprocessors.ts b/packages/compiler-sfc/src/stylePreprocessors.ts index a6287dfc..1a4e7b7c 100644 --- a/packages/compiler-sfc/src/stylePreprocessors.ts +++ b/packages/compiler-sfc/src/stylePreprocessors.ts @@ -1,12 +1,14 @@ 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: string]: any + additionalData?: string | ((source: string, filename: string) => string) filename: string }, customRequire: SFCStyleCompileOptions['preprocessCustomRequire'] @@ -24,7 +26,7 @@ const scss: StylePreprocessor = (source, map, options, load = require) => { const nodeSass = load('sass') const finalOptions = { ...options, - data: (options.additionalData || '') + source, + data: getSource(source, options.filename, options.additionalData), file: options.filename, outFile: options.filename, sourceMap: !!map @@ -66,7 +68,7 @@ const less: StylePreprocessor = (source, map, options, load = require) => { let result: any let error: Error | null = null nodeLess.render( - source, + getSource(source, options.filename, options.additionalData), { ...options, syncImport: true }, (err: Error | null, output: any) => { error = err @@ -117,6 +119,18 @@ const styl: StylePreprocessor = (source, map, options, load = require) => { } } +function getSource( + source: string, + filename: string, + additionalData?: string | ((source: string, filename: string) => string) +) { + 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: Record = {