Skip to content

Commit

Permalink
source map: avoid null entry for 0-length parts
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 20, 2024
1 parent 199a0d3 commit 4b9322f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
4 changes: 2 additions & 2 deletions internal/linker/linker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5851,7 +5851,7 @@ func (c *linkerContext) generateChunkJS(chunkIndex int, chunkWaitGroup *sync.Wai
prevOffset.AdvanceBytes(compileResult.JS)

// Include a null entry in the source map
if c.options.SourceMap != config.SourceMapNone {
if len(compileResult.JS) > 0 && c.options.SourceMap != config.SourceMapNone {
if n := len(compileResultsForSourceMap); n > 0 && !compileResultsForSourceMap[n-1].isNullEntry {
compileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{
sourceIndex: compileResult.sourceIndex,
Expand Down Expand Up @@ -6358,7 +6358,7 @@ func (c *linkerContext) generateChunkCSS(chunkIndex int, chunkWaitGroup *sync.Wa
prevOffset.AdvanceBytes(compileResult.CSS)

// Include a null entry in the source map
if c.options.SourceMap != config.SourceMapNone && compileResult.sourceIndex.IsValid() {
if len(compileResult.CSS) > 0 && c.options.SourceMap != config.SourceMapNone && compileResult.sourceIndex.IsValid() {
if n := len(compileResultsForSourceMap); n > 0 && !compileResultsForSourceMap[n-1].isNullEntry {
compileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{
sourceIndex: compileResult.sourceIndex.GetIndex(),
Expand Down
53 changes: 48 additions & 5 deletions scripts/verify-source-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ const toSearchCodeSplitting = {
out: 'out.ts',
}

const testCaseCodeSplittingEmptyFile = {
'entry1.ts': `
import './a.ts'
import './empty.ts'
import './b.ts'
`,
'entry2.ts': `
import './a.ts'
import './empty.ts'
import './b.ts'
`,
'a.ts': `'foo'.print()`,
'empty.ts': `//! @preserve`,
'b.ts': `'bar'.print()`,
}

const toSearchCodeSplittingEmptyFile = {
foo: 'a.ts',
bar: 'b.ts',
}

const testCaseUnicode = {
'entry.js': `
import './a'
Expand Down Expand Up @@ -430,7 +451,7 @@ const toSearchNullSourcesContent = {
bar: 'bar.ts',
}

async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf, followUpFlags = [] }) {
async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf, followUpFlags = [], checkChunk }) {
let failed = 0

try {
Expand Down Expand Up @@ -470,6 +491,18 @@ async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf,

let outCode
let outCodeMap
let outPrefix = 'out'

// Optionally check the first chunk when splitting
if (checkChunk && flags.includes('--splitting')) {
const entries = await fs.readdir(tempDir)
for (const entry of entries.sort()) {
if (entry.startsWith('chunk-')) {
outPrefix = entry.slice(0, entry.indexOf('.'))
break
}
}
}

if (isStdin) {
outCode = stdout
Expand All @@ -478,9 +511,9 @@ async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf,
}

else {
outCode = await fs.readFile(path.join(tempDir, `out.${ext}`), 'utf8')
recordCheck(outCode.includes(`# sourceMappingURL=out.${ext}.map`), `.${ext} file must link to .${ext}.map`)
outCodeMap = await fs.readFile(path.join(tempDir, `out.${ext}.map`), 'utf8')
outCode = await fs.readFile(path.join(tempDir, `${outPrefix}.${ext}`), 'utf8')
recordCheck(outCode.includes(`# sourceMappingURL=${outPrefix}.${ext}.map`), `.${ext} file must link to .${ext}.map`)
outCodeMap = await fs.readFile(path.join(tempDir, `${outPrefix}.${ext}.map`), 'utf8')
}

// Check the mapping of various key locations back to the original source
Expand Down Expand Up @@ -558,7 +591,7 @@ async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf,

// Bundle again to test nested source map chaining
for (let order of [0, 1, 2]) {
const fileToTest = isStdin ? `stdout.${ext}` : `out.${ext}`
const fileToTest = isStdin ? `stdout.${ext}` : `${outPrefix}.${ext}`
const nestedEntry = path.join(tempDir, `nested-entry.${ext}`)
if (isStdin) await fs.writeFile(path.join(tempDir, fileToTest), outCode)
await fs.writeFile(path.join(tempDir, `extra.${ext}`), `console.log('extra')`)
Expand All @@ -572,6 +605,7 @@ async function check(kind, testCase, toSearch, { ext, flags, entryPoints, crlf,
'--bundle',
'--outfile=' + path.join(tempDir, `out2.${ext}`),
'--sourcemap',
'--format=esm',
].concat(followUpFlags), { cwd: testDir })

const out2Code = await fs.readFile(path.join(tempDir, `out2.${ext}`), 'utf8')
Expand Down Expand Up @@ -892,6 +926,15 @@ async function main() {
entryPoints: ['foo.js'],
crlf,
}),

// This checks for issues with files in a bundle that don't emit source maps
check('splitting-empty' + suffix, testCaseCodeSplittingEmptyFile, toSearchCodeSplittingEmptyFile, {
ext: 'js',
flags: flags.concat('--outdir=.', '--bundle', '--splitting', '--format=esm'),
entryPoints: ['entry1.ts', 'entry2.ts'],
crlf,
checkChunk: true,
})
)
}
}
Expand Down

0 comments on commit 4b9322f

Please sign in to comment.