diff --git a/packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts b/packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts index 00610888bcd37d279468e0cc66cced06a147826a..d2f9be31b78c25ce258c1d6a17028515aaf51c7b 100644 --- a/packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts +++ b/packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts @@ -278,20 +278,24 @@ function createTryResolve( return async (source: string, code: string, { ss, se }: ImportSpecifier) => { const resolved = await wrapResolve(resolve)(source, importer) if (!resolved) { - const { start, end } = offsetToStartAndEnd(code, ss, se) + const { start, end } = offsetToStartAndEnd(code, ss, se - 1) const consumer = new SourceMapConsumer(resolvedMap) const startPos = consumer.originalPositionFor({ line: start.line, column: start.column, }) - if (startPos) { + if ( + startPos.line != null && + startPos.column != null && + startPos.source != null + ) { const endPos = consumer.originalPositionFor({ line: end.line, column: end.column, }) - if (endPos) { + if (endPos.line != null && endPos.column != null) { throw createResolveError( - consumer.sourceContentFor(endPos.source), + consumer.sourceContentFor(startPos.source), createResolveErrorMsg(source, importer), startPos as unknown as Position, endPos as unknown as Position diff --git a/packages/uni-cli-shared/package.json b/packages/uni-cli-shared/package.json index 5515368a3390ab5cfa53e3ddf5fc7e5c37876324..7146ab11e28ff8a4dbc0a19fe20d5bb7f38ba3cc 100644 --- a/packages/uni-cli-shared/package.json +++ b/packages/uni-cli-shared/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@ampproject/remapping": "^2.1.2", + "@babel/code-frame": "^7.23.5", "@babel/core": "^7.21.3", "@babel/parser": "^7.23.5", "@babel/types": "^7.20.7", @@ -48,6 +49,7 @@ "fs-extra": "^10.0.0", "hash-sum": "^2.0.0", "jsonc-parser": "^3.2.0", + "lines-and-columns": "^2.0.4", "magic-string": "^0.30.0", "merge": "^2.1.1", "mime": "^3.0.0", @@ -65,6 +67,7 @@ "gitHead": "33e807d66e1fe47e2ee08ad9c59247e37b8884da", "devDependencies": { "@dcloudio/uni-uts-v1": "3.0.0-alpha-4000020231215001", + "@types/babel__code-frame": "^7.0.6", "@types/babel__core": "^7.1.19", "@types/debug": "^4.1.7", "@types/estree": "^0.0.51", @@ -76,6 +79,7 @@ "@types/resolve": "^1.20.2", "@types/sass": "^1.43.1", "@types/stylus": "^0.48.36", + "code-frame": "link:@types/@babel/code-frame", "postcss": "^8.4.21", "unplugin-auto-import": "^0.16.7", "vue": "3.3.11" diff --git a/packages/uni-cli-shared/src/vite/plugins/vitejs/utils.ts b/packages/uni-cli-shared/src/vite/plugins/vitejs/utils.ts index d139346b6076a35ddaa2c61c3bdd3b561252cb9d..6b80714fb4ee87a461c5ee20686a412cadc84c4a 100644 --- a/packages/uni-cli-shared/src/vite/plugins/vitejs/utils.ts +++ b/packages/uni-cli-shared/src/vite/plugins/vitejs/utils.ts @@ -5,7 +5,8 @@ import os from 'os' import path from 'path' import remapping from '@ampproject/remapping' import type { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping' -import { SourceLocation } from '@vue/compiler-core' +import { Position, SourceLocation } from '@vue/compiler-core' +import { LinesAndColumns } from 'lines-and-columns' export function slash(p: string): string { return p.replace(/\\/g, '/') @@ -69,7 +70,7 @@ export function offsetToStartAndEnd( startOffset: number, endOffset: number ): SourceLocation { - const lines = source.split(splitRE) + const lines = new LinesAndColumns(source) return { start: offsetToLineColumnByLines(lines, startOffset), end: offsetToLineColumnByLines(lines, endOffset), @@ -77,25 +78,23 @@ export function offsetToStartAndEnd( } } -function offsetToLineColumnByLines(lines: string[], offset: number) { - let currentOffset = 0 - for (let i = 0; i < lines.length; i++) { - const lineLength = lines[i].length + 1 // Adding 1 for the newline character - if (currentOffset + lineLength > offset) { - const line = i + 1 // Line numbers start from 1 - const column = offset - currentOffset // Column numbers start from 0 - return { line, column, offset } - } - currentOffset += lineLength - } - return { line: lines.length, column: lines[lines.length - 1].length, offset } -} - export function offsetToLineColumn( source: string, offset: number ): { line: number; column: number } { - return offsetToLineColumnByLines(source.split(splitRE), offset) + return offsetToLineColumnByLines(new LinesAndColumns(source), offset) +} + +export function offsetToLineColumnByLines( + lines: LinesAndColumns, + offset: number +): Position { + let location = lines.locationForIndex(offset) + if (!location) { + location = lines.locationForIndex(offset)! + } + // lines-and-columns is 0-indexed while positions are 1-indexed + return { line: location.line + 1, column: location.column, offset: 0 } } export function posToNumber( @@ -103,16 +102,16 @@ export function posToNumber( pos: number | { line: number; column: number } ): number { if (typeof pos === 'number') return pos - const lines = source.split(splitRE) - return posToNumberByLines(lines, pos.line, pos.column) + return posToNumberByLines(new LinesAndColumns(source), pos.line, pos.column) } -function posToNumberByLines(lines: string[], line: number, column: number) { - let start = 0 - for (let i = 0; i < line - 1; i++) { - start += lines[i].length + 1 - } - return start + column +function posToNumberByLines( + lines: LinesAndColumns, + line: number, + column: number +) { + // lines-and-columns is 0-indexed while positions are 1-indexed + return lines.indexForLocation({ line: line - 1, column }) || 0 } export function locToStartAndEnd( @@ -122,7 +121,7 @@ export function locToStartAndEnd( end: { line: number; column: number } } ) { - const lines = source.split(splitRE) + const lines = new LinesAndColumns(source) const start = posToNumberByLines(lines, loc.start.line, loc.start.column) const end = loc.end ? posToNumberByLines(lines, loc.end.line, loc.end.column) diff --git a/packages/uni-cli-shared/src/vite/utils/utils.ts b/packages/uni-cli-shared/src/vite/utils/utils.ts index af17ae971d5ab9d0242ba65517af868d1611fe06..2d108e0680b40d93c8c82f505cd5dd12650e2594 100644 --- a/packages/uni-cli-shared/src/vite/utils/utils.ts +++ b/packages/uni-cli-shared/src/vite/utils/utils.ts @@ -1,8 +1,9 @@ import type { ConfigEnv, ResolvedConfig, UserConfig } from 'vite' -import { generateCodeFrame, locToStartAndEnd } from '../plugins/vitejs/utils' import { RollupError } from 'rollup' import { CompilerError } from '@vue/compiler-sfc' import { extend } from '@vue/shared' +import { codeFrameColumns } from '@babel/code-frame' +import { offsetToStartAndEnd } from '../plugins/vitejs/utils' export function withSourcemap(config: ResolvedConfig) { if (config.command === 'serve') { @@ -50,14 +51,16 @@ export function createRollupError( } if (source && source.length > 0) { if ('offsetStart' in error && 'offsetEnd' in error) { - rollupError.frame = generateCodeFrame( + rollupError.frame = codeFrameColumns( source, - error.offsetStart as number, - error.offsetEnd as number + offsetToStartAndEnd( + source, + error.offsetStart as number, + error.offsetEnd as number + ) ).replace(/\t/g, ' ') } else { - const { start, end } = locToStartAndEnd(source, error.loc) - rollupError.frame = generateCodeFrame(source, start, end).replace( + rollupError.frame = codeFrameColumns(source, error.loc).replace( /\t/g, ' ' ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e13ae71fe6071712a20f0131d7701deee5864c5b..2ea5d0ba8f9586fe147f4ae9765612416d5bf8f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + overrides: '@babel/plugin-transform-block-scoping': 7.19.4 @@ -555,6 +559,9 @@ importers: '@ampproject/remapping': specifier: ^2.1.2 version: 2.1.2 + '@babel/code-frame': + specifier: ^7.23.5 + version: 7.23.5 '@babel/core': specifier: ^7.21.3 version: 7.21.3 @@ -633,6 +640,9 @@ importers: jsonc-parser: specifier: ^3.2.0 version: 3.2.0 + lines-and-columns: + specifier: ^2.0.4 + version: 2.0.4 magic-string: specifier: ^0.30.0 version: 0.30.0 @@ -676,6 +686,9 @@ importers: '@dcloudio/uni-uts-v1': specifier: 3.0.0-alpha-4000020231215001 version: link:../uni-uts-v1 + '@types/babel__code-frame': + specifier: ^7.0.6 + version: 7.0.6 '@types/babel__core': specifier: ^7.1.19 version: 7.1.19 @@ -709,6 +722,9 @@ importers: '@types/stylus': specifier: ^0.48.36 version: 0.48.36 + code-frame: + specifier: link:@types/@babel/code-frame + version: link:@types/@babel/code-frame postcss: specifier: ^8.4.21 version: 8.4.23 @@ -1632,6 +1648,13 @@ packages: dependencies: '@babel/highlight': 7.18.6 + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + /@babel/compat-data@7.21.7: resolution: {integrity: sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==} engines: {node: '>=6.9.0'} @@ -1641,7 +1664,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.23.5 '@babel/generator': 7.21.5 '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.3) '@babel/helper-module-transforms': 7.21.5 @@ -1852,6 +1875,10 @@ packages: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.21.0: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} @@ -1885,6 +1912,14 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + /@babel/parser@7.21.8: resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==} engines: {node: '>=6.0.0'} @@ -2698,7 +2733,7 @@ packages: resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.23.5 '@babel/parser': 7.23.6 '@babel/types': 7.20.7 @@ -4468,6 +4503,10 @@ packages: resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} dev: true + /@types/babel__code-frame@7.0.6: + resolution: {integrity: sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==} + dev: true + /@types/babel__core@7.1.19: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: @@ -8603,6 +8642,11 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + /lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + /lint-staged@10.5.3: resolution: {integrity: sha512-TanwFfuqUBLufxCc3RUtFEkFraSPNR3WzWcGF39R3f2J7S9+iF9W0KTVLfSy09lYGmZS5NDCxjNvhGMSJyFCWg==} hasBin: true @@ -11202,7 +11246,3 @@ packages: optionalDependencies: commander: 9.5.0 dev: true - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false