From 2e42abc9901c64ec5c28932ca08fef853071bd59 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Tue, 30 Aug 2022 17:42:07 +0900 Subject: [PATCH 1/2] feat(css): format error --- .../vite/src/node/__tests__/utils.spec.ts | 16 +++ packages/vite/src/node/plugins/css.ts | 125 ++++++++++-------- packages/vite/src/node/utils.ts | 2 + 3 files changed, 87 insertions(+), 56 deletions(-) diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 858ec8437362a1..9bfcb9c1730c42 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -6,6 +6,7 @@ import { getPotentialTsSrcPaths, injectQuery, isWindows, + posToNumber, resolveHostname } from '../utils' @@ -156,6 +157,21 @@ test('ts import of file with .js and query param', () => { ]) }) +describe('posToNumber', () => { + test('simple', () => { + const actual = posToNumber('a\nb', { line: 2, column: 0 }) + expect(actual).toBe(2) + }) + test('pass though pos', () => { + const actual = posToNumber('a\nb', 2) + expect(actual).toBe(2) + }) + test('empty line', () => { + const actual = posToNumber('a\n\nb', { line: 3, column: 0 }) + expect(actual).toBe(3) + }) +}) + describe('getHash', () => { test('8-digit hex', () => { const hash = getHash(Buffer.alloc(0)) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 4dc3aa7f158587..959e5424dec68c 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -803,8 +803,8 @@ async function compileCSS( atImportResolvers ) - if (preprocessResult.errors.length) { - throw preprocessResult.errors[0] + if (preprocessResult.error) { + throw preprocessResult.error } code = preprocessResult.code @@ -893,55 +893,66 @@ async function compileCSS( } } - // postcss is an unbundled dep and should be lazy imported - const postcssResult = await (await import('postcss')) - .default(postcssPlugins) - .process(code, { - ...postcssOptions, - to: id, - from: id, - ...(devSourcemap - ? { - map: { - inline: false, - annotation: false, - // postcss may return virtual files - // we cannot obtain content of them, so this needs to be enabled - sourcesContent: true - // when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources` - // prev: preprocessorMap, + let postcssResult: PostCSS.Result + try { + // postcss is an unbundled dep and should be lazy imported + postcssResult = await (await import('postcss')) + .default(postcssPlugins) + .process(code, { + ...postcssOptions, + to: id, + from: id, + ...(devSourcemap + ? { + map: { + inline: false, + annotation: false, + // postcss may return virtual files + // we cannot obtain content of them, so this needs to be enabled + sourcesContent: true + // when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources` + // prev: preprocessorMap, + } } - } - : {}) - }) - - // record CSS dependencies from @imports - for (const message of postcssResult.messages) { - if (message.type === 'dependency') { - deps.add(normalizePath(message.file as string)) - } else if (message.type === 'dir-dependency') { - // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#3-dependencies - const { dir, glob: globPattern = '**' } = message - const pattern = - glob.escapePath(normalizePath(path.resolve(path.dirname(id), dir))) + - `/` + - globPattern - const files = glob.sync(pattern, { - ignore: ['**/node_modules/**'] + : {}) }) - for (let i = 0; i < files.length; i++) { - deps.add(files[i]) - } - } else if (message.type === 'warning') { - let msg = `[vite:css] ${message.text}` - if (message.line && message.column) { - msg += `\n${generateCodeFrame(code, { - line: message.line, - column: message.column - })}` + + // record CSS dependencies from @imports + for (const message of postcssResult.messages) { + if (message.type === 'dependency') { + deps.add(normalizePath(message.file as string)) + } else if (message.type === 'dir-dependency') { + // https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#3-dependencies + const { dir, glob: globPattern = '**' } = message + const pattern = + glob.escapePath(normalizePath(path.resolve(path.dirname(id), dir))) + + `/` + + globPattern + const files = glob.sync(pattern, { + ignore: ['**/node_modules/**'] + }) + for (let i = 0; i < files.length; i++) { + deps.add(files[i]) + } + } else if (message.type === 'warning') { + let msg = `[vite:css] ${message.text}` + if (message.line && message.column) { + msg += `\n${generateCodeFrame(code, { + line: message.line, + column: message.column + })}` + } + config.logger.warn(colors.yellow(msg)) } - config.logger.warn(colors.yellow(msg)) } + } catch (e) { + e.message = `[postcss] ${e.message}` + e.code = code + e.loc = { + column: e.column, + line: e.line + } + throw e } if (!devSourcemap) { @@ -1256,6 +1267,7 @@ async function minifyCSS(css: string, config: ResolvedConfig) { return code } catch (e) { if (e.errors) { + e.message = '[esbuild css minify] ' + e.message const msgs = await formatMessages(e.errors, { kind: 'error' }) e.frame = '\n' + msgs.join('\n') e.loc = e.errors[0].location @@ -1365,7 +1377,7 @@ export interface StylePreprocessorResults { code: string map?: ExistingRawSourceMap | undefined additionalMap?: ExistingRawSourceMap | undefined - errors: RollupError[] + error?: RollupError deps: string[] } @@ -1469,14 +1481,14 @@ const scss: SassStylePreprocessor = async ( code: result.css.toString(), map, additionalMap, - errors: [], deps } } catch (e) { // normalize SASS error + e.message = `[sass] ${e.message}` e.id = e.file e.frame = e.formatted - return { code: '', errors: [e], deps: [] } + return { code: '', error: e, deps: [] } } } @@ -1588,13 +1600,15 @@ const less: StylePreprocessor = async (source, root, options, resolvers) => { } catch (e) { const error = e as Less.RenderError // normalize error info - const normalizedError: RollupError = new Error(error.message || error.type) + const normalizedError: RollupError = new Error( + `[less] ${error.message || error.type}` + ) normalizedError.loc = { file: error.filename || options.filename, line: error.line, column: error.column } - return { code: '', errors: [normalizedError], deps: [] } + return { code: '', error: normalizedError, deps: [] } } const map: ExistingRawSourceMap = result.map && JSON.parse(result.map) @@ -1606,8 +1620,7 @@ const less: StylePreprocessor = async (source, root, options, resolvers) => { code: result.css.toString(), map, additionalMap, - deps: result.imports, - errors: [] + deps: result.imports } } @@ -1721,11 +1734,11 @@ const styl: StylePreprocessor = async (source, root, options) => { code: result, map: formatStylusSourceMap(map, root), additionalMap, - errors: [], deps } } catch (e) { - return { code: '', errors: [e], deps: [] } + e.message = `[stylus] ${e.message}` + return { code: '', error: e, deps: [] } } } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 7378b080eafd0c..a084bd118ef0a5 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -436,6 +436,8 @@ export function posToNumber( for (let i = 0; i < line - 1; i++) { if (lines[i]) { start += lines[i].length + 1 + } else { + start++ } } return start + column From b71df66aeb55ce9fa375dfbdedb96e957d658d54 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Tue, 30 Aug 2022 17:54:02 +0900 Subject: [PATCH 2/2] refactor: out of range --- packages/vite/src/node/__tests__/utils.spec.ts | 4 ++++ packages/vite/src/node/utils.ts | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 9bfcb9c1730c42..dbad4cd4afd1a9 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -170,6 +170,10 @@ describe('posToNumber', () => { const actual = posToNumber('a\n\nb', { line: 3, column: 0 }) expect(actual).toBe(3) }) + test('out of range', () => { + const actual = posToNumber('a\nb', { line: 4, column: 0 }) + expect(actual).toBe(4) + }) }) describe('getHash', () => { diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index a084bd118ef0a5..d63691f3cdc922 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -433,12 +433,8 @@ export function posToNumber( const lines = source.split(splitRE) const { line, column } = pos let start = 0 - for (let i = 0; i < line - 1; i++) { - if (lines[i]) { - start += lines[i].length + 1 - } else { - start++ - } + for (let i = 0; i < line - 1 && i < lines.length; i++) { + start += lines[i].length + 1 } return start + column }