|
1 | 1 | import { ResolvedConfig, TransformResult, Plugin } from 'vite'; |
2 | 2 | import MagicString from 'magic-string'; |
3 | | -import { Preprocessor, PreprocessorGroup, ResolvedOptions } from './options'; |
| 3 | +import { Preprocessor, PreprocessorGroup, Processed, ResolvedOptions } from './options'; |
4 | 4 | import { TransformPluginContext } from 'rollup'; |
5 | 5 | import { log } from './log'; |
| 6 | +import { buildSourceMap } from './sourcemap'; |
6 | 7 |
|
7 | 8 | const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss']; |
8 | 9 |
|
@@ -38,13 +39,13 @@ function createPreprocessorFromVitePlugin( |
38 | 39 | moduleId |
39 | 40 | )) as TransformResult; |
40 | 41 | // TODO vite:css transform currently returns an empty mapping that would kill svelte compiler. |
41 | | - const hasMap = !!transformResult.map?.mappings; |
| 42 | + const hasMap = transformResult.map && transformResult.map?.mappings !== ''; |
42 | 43 | if (transformResult.map?.sources?.[0] === moduleId) { |
43 | 44 | transformResult.map.sources[0] = filename as string; |
44 | 45 | } |
45 | 46 | return { |
46 | 47 | code: transformResult.code, |
47 | | - map: hasMap ? (transformResult.map as object) : null, |
| 48 | + map: hasMap ? (transformResult.map as object) : undefined, |
48 | 49 | dependencies: transformResult.deps |
49 | 50 | }; |
50 | 51 | }; |
@@ -73,7 +74,7 @@ function createInjectScopeEverythingRulePreprocessorGroup(): PreprocessorGroup { |
73 | 74 | s.append(' *{}'); |
74 | 75 | return { |
75 | 76 | code: s.toString(), |
76 | | - map: s.generateDecodedMap({ file: filename }) |
| 77 | + map: s.generateDecodedMap({ source: filename, hires: true }) |
77 | 78 | }; |
78 | 79 | } |
79 | 80 | }; |
@@ -158,4 +159,62 @@ export function addExtraPreprocessors(options: ResolvedOptions, config: Resolved |
158 | 159 | options.preprocess = [options.preprocess, ...extra]; |
159 | 160 | } |
160 | 161 | } |
| 162 | + const generateMissingSourceMaps = !!options.experimental?.generateMissingPreprocessorSourcemaps; |
| 163 | + if (options.preprocess && generateMissingSourceMaps) { |
| 164 | + options.preprocess = Array.isArray(options.preprocess) |
| 165 | + ? options.preprocess.map((p, i) => validateSourceMapOutputWrapper(p, i)) |
| 166 | + : validateSourceMapOutputWrapper(options.preprocess, 0); |
| 167 | + } |
| 168 | +} |
| 169 | + |
| 170 | +function validateSourceMapOutputWrapper(group: PreprocessorGroup, i: number): PreprocessorGroup { |
| 171 | + const wrapper: PreprocessorGroup = {}; |
| 172 | + |
| 173 | + for (const [processorType, processorFn] of Object.entries(group) as Array< |
| 174 | + // eslint-disable-next-line no-unused-vars |
| 175 | + [keyof PreprocessorGroup, (options: { filename?: string; content: string }) => Processed] |
| 176 | + >) { |
| 177 | + wrapper[processorType] = async (options) => { |
| 178 | + const result = await processorFn(options); |
| 179 | + |
| 180 | + if (result && result.code !== options.content) { |
| 181 | + let invalidMap = false; |
| 182 | + if (!result.map) { |
| 183 | + invalidMap = true; |
| 184 | + log.warn.enabled && |
| 185 | + log.warn.once( |
| 186 | + `preprocessor at index ${i} did not return a sourcemap for ${processorType} transform`, |
| 187 | + { |
| 188 | + filename: options.filename, |
| 189 | + type: processorType, |
| 190 | + processor: processorFn.toString() |
| 191 | + } |
| 192 | + ); |
| 193 | + } else if ((result.map as any)?.mappings === '') { |
| 194 | + invalidMap = true; |
| 195 | + log.warn.enabled && |
| 196 | + log.warn.once( |
| 197 | + `preprocessor at index ${i} returned an invalid empty sourcemap for ${processorType} transform`, |
| 198 | + { |
| 199 | + filename: options.filename, |
| 200 | + type: processorType, |
| 201 | + processor: processorFn.toString() |
| 202 | + } |
| 203 | + ); |
| 204 | + } |
| 205 | + if (invalidMap) { |
| 206 | + try { |
| 207 | + const map = buildSourceMap(options.content, result.code, options.filename); |
| 208 | + log.warn.once('adding generated sourcemap to preprocesor result'); |
| 209 | + result.map = map; |
| 210 | + } catch (e) { |
| 211 | + log.error(`failed to build sourcemap`, e); |
| 212 | + } |
| 213 | + } |
| 214 | + } |
| 215 | + return result; |
| 216 | + }; |
| 217 | + } |
| 218 | + |
| 219 | + return wrapper; |
161 | 220 | } |
0 commit comments