diff --git a/packages/playground/css-sourcemap/vite.config.js b/packages/playground/css-sourcemap/vite.config.js index 2e70a4a0894406..335ed5627d8a5c 100644 --- a/packages/playground/css-sourcemap/vite.config.js +++ b/packages/playground/css-sourcemap/vite.config.js @@ -10,6 +10,7 @@ module.exports = { } }, css: { + devSourcemap: true, preprocessorOptions: { less: { additionalData: '@color: red;' diff --git a/packages/playground/vue-sourcemap/vite.config.js b/packages/playground/vue-sourcemap/vite.config.js index 045410259fe590..2a48cad3cb00d4 100644 --- a/packages/playground/vue-sourcemap/vite.config.js +++ b/packages/playground/vue-sourcemap/vite.config.js @@ -5,6 +5,7 @@ const vuePlugin = require('@vitejs/plugin-vue') */ module.exports = { css: { + devSourcemap: true, preprocessorOptions: { less: { additionalData: '@color: red;' diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index 28280ed79188b8..7bdf63b700fa15 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -63,6 +63,7 @@ export interface ResolvedOptions extends Options { compiler: typeof _compiler root: string sourceMap: boolean + cssDevSourcemap: boolean devServer?: ViteDevServer devToolsEnabled?: boolean } @@ -99,6 +100,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { reactivityTransform, root: process.cwd(), sourceMap: true, + cssDevSourcemap: false, devToolsEnabled: process.env.NODE_ENV !== 'production' } @@ -137,6 +139,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { ...options, root: config.root, sourceMap: config.command === 'build' ? !!config.build.sourcemap : true, + cssDevSourcemap: config.css?.devSourcemap ?? false, isProduction: config.isProduction, devToolsEnabled: !!config.define!.__VUE_PROD_DEVTOOLS__ || !config.isProduction diff --git a/packages/plugin-vue/src/style.ts b/packages/plugin-vue/src/style.ts index c124f3ec744e4f..cab75791bd54ec 100644 --- a/packages/plugin-vue/src/style.ts +++ b/packages/plugin-vue/src/style.ts @@ -23,13 +23,17 @@ export async function transformStyle( isProd: options.isProduction, source: code, scoped: block.scoped, - postcssOptions: { - map: { - from: filename, - inline: false, - annotation: false - } - } + ...(options.cssDevSourcemap + ? { + postcssOptions: { + map: { + from: filename, + inline: false, + annotation: false + } + } + } + : {}) }) if (result.errors.length) { diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index f45a1ac01fb6f8..59b850ede49332 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -62,6 +62,12 @@ export interface CSSOptions { | (Postcss.ProcessOptions & { plugins?: Postcss.Plugin[] }) + /** + * Enables css sourcemaps during dev + * @default false + * @experimental + */ + devSourcemap?: boolean } export interface CSSModulesOptions { @@ -301,9 +307,12 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { return `export default ${JSON.stringify(css)}` } - const sourcemap = this.getCombinedSourcemap() - await injectSourcesContent(sourcemap, cleanUrl(id), config.logger) - const cssContent = getCodeWithSourcemap('css', css, sourcemap) + let cssContent = css + if (config.css?.devSourcemap) { + const sourcemap = this.getCombinedSourcemap() + await injectSourcesContent(sourcemap, cleanUrl(id), config.logger) + cssContent = getCodeWithSourcemap('css', css, sourcemap) + } return [ `import { updateStyle as __vite__updateStyle, removeStyle as __vite__removeStyle } from ${JSON.stringify( @@ -604,7 +613,11 @@ async function compileCSS( modules?: Record deps?: Set }> { - const { modules: modulesOptions, preprocessorOptions } = config.css || {} + const { + modules: modulesOptions, + preprocessorOptions, + devSourcemap + } = config.css || {} const isModule = modulesOptions !== false && cssModuleRE.test(id) // although at serve time it can work without processing, we do need to // crawl them in order to register watch dependencies. @@ -653,6 +666,7 @@ async function compileCSS( } // important: set this for relative import resolving opts.filename = cleanUrl(id) + opts.enableSourcemap = devSourcemap ?? false const preprocessResult = await preProcessor( code, @@ -807,6 +821,16 @@ async function compileCSS( } } + if (!devSourcemap) { + return { + ast: postcssResult, + code: postcssResult.css, + map: { mappings: '' }, + modules, + deps + } + } + const rawPostcssMap = postcssResult.map.toJSON() const postcssMap = formatPostcssSourceMap( @@ -1078,6 +1102,7 @@ type StylePreprocessorOptions = { additionalData?: PreprocessorAdditionalData filename: string alias: Alias[] + enableSourcemap: boolean } type SassStylePreprocessorOptions = StylePreprocessorOptions & Sass.Options @@ -1167,7 +1192,8 @@ const scss: SassStylePreprocessor = async ( const { content: data, map: additionalMap } = await getSource( source, options.filename, - options.additionalData + options.additionalData, + options.enableSourcemap ) const finalOptions: Sass.Options = { ...options, @@ -1175,9 +1201,13 @@ const scss: SassStylePreprocessor = async ( file: options.filename, outFile: options.filename, importer, - sourceMap: true, - omitSourceMapUrl: true, - sourceMapRoot: path.dirname(options.filename) + ...(options.enableSourcemap + ? { + sourceMap: true, + omitSourceMapUrl: true, + sourceMapRoot: path.dirname(options.filename) + } + : {}) } try { @@ -1291,7 +1321,8 @@ const less: StylePreprocessor = async (source, root, options, resolvers) => { const { content, map: additionalMap } = await getSource( source, options.filename, - options.additionalData + options.additionalData, + options.enableSourcemap ) let result: Less.RenderOutput | undefined @@ -1299,10 +1330,14 @@ const less: StylePreprocessor = async (source, root, options, resolvers) => { result = await nodeLess.render(content, { ...options, plugins: [viteResolverPlugin, ...(options.plugins || [])], - sourceMap: { - outputSourceFiles: true, - sourceMapFileInline: false - } + ...(options.enableSourcemap + ? { + sourceMap: { + outputSourceFiles: true, + sourceMapFileInline: false + } + } + : {}) }) } catch (e) { const error = e as Less.RenderError @@ -1410,6 +1445,7 @@ const styl: StylePreprocessor = async (source, root, options) => { source, options.filename, options.additionalData, + options.enableSourcemap, '\n' ) // Get preprocessor options.imports dependencies as stylus @@ -1419,11 +1455,13 @@ const styl: StylePreprocessor = async (source, root, options) => { ) try { const ref = nodeStylus(content, options) - ref.set('sourcemap', { - comment: false, - inline: false, - basePath: root - }) + if (options.enableSourcemap) { + ref.set('sourcemap', { + comment: false, + inline: false, + basePath: root + }) + } const result = ref.render() @@ -1431,7 +1469,7 @@ const styl: StylePreprocessor = async (source, root, options) => { const deps = [...ref.deps(), ...importsDeps] // @ts-expect-error sourcemap exists - const map: ExistingRawSourceMap = ref.sourcemap + const map: ExistingRawSourceMap | undefined = ref.sourcemap return { code: result, @@ -1446,9 +1484,10 @@ const styl: StylePreprocessor = async (source, root, options) => { } function formatStylusSourceMap( - mapBefore: ExistingRawSourceMap, + mapBefore: ExistingRawSourceMap | undefined, root: string -): ExistingRawSourceMap { +): ExistingRawSourceMap | undefined { + if (!mapBefore) return undefined const map = { ...mapBefore } const resolveFromRoot = (p: string) => normalizePath(path.resolve(root, p)) @@ -1464,7 +1503,8 @@ function formatStylusSourceMap( async function getSource( source: string, filename: string, - additionalData?: PreprocessorAdditionalData, + additionalData: PreprocessorAdditionalData | undefined, + enableSourcemap: boolean, sep: string = '' ): Promise<{ content: string; map?: ExistingRawSourceMap }> { if (!additionalData) return { content: source } @@ -1477,6 +1517,10 @@ async function getSource( return newContent } + if (!enableSourcemap) { + return { content: additionalData + sep + source } + } + const ms = new MagicString(source) ms.appendLeft(0, sep) ms.appendLeft(0, additionalData)