Skip to content

Commit

Permalink
feat: improve sfc compilation error output
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed May 7, 2020
1 parent 19f8358 commit 44a8250
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 20 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
"@rollup/plugin-node-resolve": "^7.1.3",
"@types/koa": "^2.11.3",
"@vue/compiler-sfc": "^3.0.0-beta.9",
"@vue/shared": "^3.0.0-beta.9",
"chalk": "^4.0.0",
"chokidar": "^3.3.1",
"cssnano": "^4.1.10",
Expand Down
2 changes: 0 additions & 2 deletions playground/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ import App from './App.vue'
import './testHmrManual'

createApp(App).mount('#app')

console.log('foooo')
2 changes: 1 addition & 1 deletion src/node/esbuildService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import { startService, Service, TransformOptions, Message } from 'esbuild'
import chalk from 'chalk'
import { generateCodeFrame } from '@vue/shared'
import { generateCodeFrame } from '@vue/compiler-sfc'

const debug = require('debug')('vite:esbuild')

Expand Down
89 changes: 73 additions & 16 deletions src/node/server/serverPluginVue.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import chalk from 'chalk'
import path from 'path'
import { Plugin } from '.'
import {
SFCDescriptor,
SFCTemplateBlock,
SFCStyleBlock,
SFCStyleCompileResults
SFCStyleCompileResults,
generateCodeFrame
} from '@vue/compiler-sfc'
import { resolveCompiler } from '../utils/resolveVue'
import hash_sum from 'hash-sum'
Expand Down Expand Up @@ -124,10 +126,22 @@ export async function parseSFC(
})

if (errors.length) {
console.error(chalk.red(`\n[vite] SFC parse error: `))
errors.forEach((e) => {
console.error(`[vite] SFC parse error: `, e)
console.error(
chalk.underline(
`${filename}:${e.loc!.start.line}:${e.loc!.start.column}`
)
)
console.error(chalk.yellow(e.message))
console.error(
generateCodeFrame(
content as string,
e.loc!.start.offset,
e.loc!.end.offset
)
)
})
console.error(`source:\n`, content)
}

cached = cached || { styles: [] }
Expand Down Expand Up @@ -210,11 +224,11 @@ async function compileSFCMain(
function compileSFCTemplate(
root: string,
template: SFCTemplateBlock,
filePath: string,
filename: string,
publicPath: string,
scoped: boolean
): string {
let cached = vueCache.get(filePath)
let cached = vueCache.get(filename)
if (cached && cached.template) {
debug(`${publicPath} template cache hit`)
return cached.template
Expand All @@ -223,7 +237,7 @@ function compileSFCTemplate(
const start = Date.now()
const { code, map, errors } = resolveCompiler(root).compileTemplate({
source: template.content,
filename: filePath,
filename,
inMap: template.map,
transformAssetUrls: {
base: path.posix.dirname(publicPath)
Expand All @@ -237,16 +251,29 @@ function compileSFCTemplate(
})

if (errors.length) {
console.error(chalk.red(`\n[vite] SFC template compilation error: `))
errors.forEach((e) => {
console.error(`[vite] SFC template compilation error: `, e)
if (typeof e === 'string') {
console.error(e)
} else {
console.error(
chalk.underline(
`${filename}:${e.loc!.start.line}:${e.loc!.start.column}`
)
)
console.error(chalk.yellow(e.message))
const original = template.map!.sourcesContent![0]
console.error(
generateCodeFrame(original, e.loc!.start.offset, e.loc!.end.offset)
)
}
})
console.error(`source:\n`, template.content)
}

const finalCode = code + genSourceMapString(map)
cached = cached || { styles: [] }
cached.template = finalCode
vueCache.set(filePath, cached)
vueCache.set(filename, cached)

debug(`${publicPath} template compiled in ${Date.now() - start}ms.`)
return finalCode
Expand All @@ -256,10 +283,10 @@ async function compileSFCStyle(
root: string,
style: SFCStyleBlock,
index: number,
filePath: string,
filename: string,
publicPath: string
): Promise<SFCStyleCompileResults> {
let cached = vueCache.get(filePath)
let cached = vueCache.get(filename)
const cachedEntry = cached && cached.styles && cached.styles[index]
if (cachedEntry) {
debug(`${publicPath} style cache hit`)
Expand All @@ -272,7 +299,7 @@ async function compileSFCStyle(

const result = await resolveCompiler(root).compileStyleAsync({
source: style.content,
filename: filePath,
filename,
id: `data-v-${id}`,
scoped: style.scoped != null,
modules: style.module != null,
Expand All @@ -287,15 +314,45 @@ async function compileSFCStyle(
})

if (result.errors.length) {
result.errors.forEach((e) => {
console.error(`[vite] SFC style compilation error: `, e)
console.error(chalk.red(`\n[vite] SFC style compilation error: `))
result.errors.forEach((e: any) => {
if (typeof e === 'string') {
console.error(e)
} else {
const lineOffset = style.loc.start.line - 1
if (e.line && e.column) {
console.log(
chalk.underline(`${filename}:${e.line + lineOffset}:${e.column}`)
)
} else {
console.log(chalk.underline(filename))
}
const filenameRE = new RegExp(
'.*' +
path.basename(filename).replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') +
'(:\\d+:\\d+:\\s*)?'
)
const cleanMsg = e.message.replace(filenameRE, '')
console.error(chalk.yellow(cleanMsg))
if (e.line && e.column && cleanMsg.split(/\n/g).length === 1) {
const original = style.map!.sourcesContent![0]
const offset =
original
.split(/\r?\n/g)
.slice(0, e.line + lineOffset - 1)
.map((l) => l.length)
.reduce((total, l) => total + l + 1, 0) +
e.column -
1
console.error(generateCodeFrame(original, offset, offset + 1))
}
}
})
console.error(`source:\n`, style.content)
}

cached = cached || { styles: [] }
cached.styles[index] = result
vueCache.set(filePath, cached)
vueCache.set(filename, cached)

debug(`${publicPath} style compiled in ${Date.now() - start}ms`)
return result
Expand Down

0 comments on commit 44a8250

Please sign in to comment.