Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@knighted/module",
"version": "1.2.0",
"version": "1.2.1",
"description": "Bidirectional transform for ES modules and CommonJS.",
"type": "module",
"main": "dist/module.js",
Expand Down
12 changes: 10 additions & 2 deletions src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,10 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) =>
seen.add(propName)
if (rhs.type === 'Identifier') {
const rhsId = rhsSourceFor(rhs)
if (rhsId === rhs.name) {
const rhsName = rhs.name
if (rhsId === rhsName && rhsName === propName) {
exportsOut.push(`export { ${propName} };`)
} else if (rhsId === rhsName) {
exportsOut.push(`export { ${rhsId} as ${propName} };`)
} else {
exportsOut.push(`export const ${propName} = ${rhsId};`)
Expand All @@ -815,7 +818,12 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) =>
}
}

replacements.push({ start: write.start, end: write.end })
// Trim trailing whitespace and one optional semicolon so the idiomatic export
// replacement does not leave the original `;` behind (avoids emitting `;;`).
let end = write.end
while (end < src.length && (src[end] === ' ' || src[end] === '\t')) end++
if (end < src.length && src[end] === ';') end++
replacements.push({ start: write.start, end })
}

if (!seen.size) return { ok: false, reason: 'no-seen' }
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/idiomaticShorthand.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function example() {
return 'ok'
}

exports.example = example
20 changes: 20 additions & 0 deletions test/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,26 @@ describe('@knighted/module', () => {
assert.equal((mod as any).bar(), 'bar')
})

it('emits shorthand exports when names match', async t => {
const fixturePath = join(fixtures, 'idiomaticShorthand.cjs')
const outFile = join(fixtures, 'idiomaticShorthand.mjs')

t.after(() => rm(outFile, { force: true }))

const result = await transform(fixturePath, { target: 'module' })
await writeFile(outFile, result)

assert.equal(result.includes('__exports'), false)
assert.ok(result.includes('export { example };'))
assert.equal(result.includes(';;'), false)

const { status } = spawnSync('node', [outFile], { stdio: 'inherit' })
assert.equal(status, 0)

const mod = await import(pathToFileURL(outFile).href)
assert.equal((mod as any).example(), 'ok')
})

it('respects idiomaticExports: off and keeps helper bag', async t => {
const fixturePath = join(fixtures, 'idiomaticSafe.cjs')
const outFile = join(fixtures, 'idiomaticOff.mjs')
Expand Down