Skip to content

Commit 66d2ab8

Browse files
committed
feat: more accurate template source map
1 parent d87336b commit 66d2ab8

File tree

2 files changed

+15
-35
lines changed

2 files changed

+15
-35
lines changed

Diff for: src/pitcher.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,9 @@ pitcher.pitch = function() {
8181
return ``
8282
}
8383

84-
// rewrite if we have deduped loaders
85-
if (loaders.length !== rawLoaders.length) {
86-
return genProxyModule(loaders, context)
87-
}
84+
// Rewrite request. Technically this should only be done when we have deduped
85+
// loaders. But somehow this is required for template source map to work...
86+
return genProxyModule(loaders, context)
8887
}
8988

9089
function genProxyModule(

Diff for: src/templateLoader.ts

+12-31
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import qs from 'querystring'
33
import chalk from 'chalk'
44
import loaderUtils from 'loader-utils'
55
import { VueLoaderOptions } from './'
6-
import { SourceMapConsumer, RawSourceMap } from 'source-map'
76
import { compileTemplate, generateCodeFrame } from '@vue/compiler-sfc'
8-
import mergeSourceMap from 'merge-source-map'
97

108
// Loader that compiles raw template into JavaScript functions.
119
// This is injected by the global pitcher (../pitch) for template
@@ -27,7 +25,7 @@ const TemplateLoader: webpack.loader.Loader = function(source, inMap) {
2725

2826
const compiled = compileTemplate({
2927
source,
30-
// avoid source content overwriting the original
28+
inMap,
3129
filename: loaderContext.resourcePath,
3230
compiler: options.compiler,
3331
compilerOptions: {
@@ -46,49 +44,32 @@ const TemplateLoader: webpack.loader.Loader = function(source, inMap) {
4644

4745
// errors
4846
if (compiled.errors && compiled.errors.length) {
49-
const lineOffset = inMap ? getLineOffset(inMap) : 0
5047
compiled.errors.forEach(err => {
5148
if (typeof err === 'string') {
5249
loaderContext.emitError(err)
5350
} else {
5451
if (err.loc) {
55-
const filePath = chalk.gray(
56-
`at ${loaderContext.resourcePath}:${err.loc.start.line +
57-
lineOffset}:${err.loc.start.column}`
52+
const loc = `:${err.loc.start.line}:${err.loc.start.column}`
53+
const filePath = chalk.gray(`at ${loaderContext.resourcePath}${loc}`)
54+
const originalSource = inMap
55+
? inMap.sourcesContent![0]
56+
: (source as string)
57+
const codeframe = generateCodeFrame(
58+
originalSource,
59+
err.loc.start.offset,
60+
err.loc.end.offset
5861
)
59-
6062
err.message = `\n${chalk.red(
6163
`Syntax Error: ${err.message}`
62-
)}\n${filePath}\n${chalk.yellow(
63-
generateCodeFrame(
64-
source as string,
65-
err.loc.start.offset,
66-
err.loc.end.offset,
67-
lineOffset
68-
)
69-
)}\n`
64+
)}\n${filePath}\n${chalk.yellow(codeframe)}\n`
7065
}
7166
loaderContext.emitError(err)
7267
}
7368
})
7469
}
7570

76-
let { code, map } = compiled
77-
if (map && inMap) {
78-
// avoid overwritting original *.vue source during merge
79-
map.sourcesContent = []
80-
map = mergeSourceMap(inMap, map)
81-
}
71+
const { code, map } = compiled
8272
loaderContext.callback(null, code, map)
8373
}
8474

85-
function getLineOffset(map: RawSourceMap): number {
86-
const consumer = new SourceMapConsumer(map)
87-
let offset = 0
88-
consumer.eachMapping(map => {
89-
offset = map.originalLine - map.generatedLine
90-
})
91-
return offset
92-
}
93-
9475
module.exports = TemplateLoader

0 commit comments

Comments
 (0)