Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cool idea, but a bit too low level (imo) #5

Open
fabis94 opened this issue Jul 26, 2023 · 2 comments
Open

Cool idea, but a bit too low level (imo) #5

fabis94 opened this issue Jul 26, 2023 · 2 comments
Labels
question Further information is requested

Comments

@fabis94
Copy link

fabis94 commented Jul 26, 2023

This library does solve the common issue of wanting to emit proper .mjs and .cjs extensions after TypeScript builds, but IMO this most common use case should just have a binary/CLI that you can easily invoke without having to write any code, figure out config & regexes etc.

@knightedcodemonkey
Copy link
Owner

Thanks for the feedback. I can appreciate your sentiment, and it sounds like you are looking for something like babel-dual-package but for TypeScript builds specifically (which that package does support, but with Babel).

This package is intentionally narrow in scope and build agnostic, with the exception that it runs on Node. It also allows you to write the updated source code to any filename and extension. It is easier to support complex decision logic in code than in a CLI too.

Is something like the below what you were wanting this package to expose?

package.json

"scripts": {
  "update:exts": "specifier dist --from .js --to .mjs --to .cjs"
}

So, you would be reading files from the tsc build output in a dist directory and updating each .js extension found in a specifier to .mjs and then again to .cjs. There is still the decision of where to write the updated files to and what their extensions should be as well, which could have sensible defaults like dist/mjs and dist/cjs and the file extensions match the specifier extensions. See how this quickly expands the scope of this package 😉 ?

You should be able to wrap this package and create something like above to suit your custom needs. Something along these lines:

update-exts.js

#!/usr/bin/env node

import { mkdir, writeFile } from 'node:fs/promises'
import { basename } from 'node:path'
import { glob } from 'glob'
import { specifier } from '@knighted/specifier'

const files = await glob('dist/*.js')

await mkdir('dist/mjs', { recursive: true })
await mkdir('dist/cjs', { recursive: true })

for (const file of files) {
  const mjs = await specifier.update(file, ({ value }) => {
    return value.replace(/\.js$/, '.mjs')
  })
  const cjs = await specifier.update(file, ({ value }) => {
    return value.replace(/\.js$/, '.cjs')
  })

  await writeFile(`dist/mjs/${basename(file).replace(/\.js$/, '.mjs')}`, mjs)
  await writeFile(`dist/cjs/${basename(file).replace(/\.js$/, '.cjs')}`, cjs)
}

Which can then be used like

user@comp $ ./update-exts.js

@knightedcodemonkey knightedcodemonkey added the enhancement New feature or request label Jul 26, 2023
@knightedcodemonkey
Copy link
Owner

@fabis94 you can check out @knighted/duel which makes use of @knighted/specifier to create a dual TypeScript build.

It is still very much a WIP, but any feedback would be helpful. Unfortunately, TypeScript has a ways to go in its implementation of dual package builds, in particular see microsoft/TypeScript#54573. Even if the file extension is .mts anytime --module commonjs is used, you get CJS modules, which obviously is antithetical to how Node determines module systems.

@knightedcodemonkey knightedcodemonkey added question Further information is requested and removed enhancement New feature or request labels Jul 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants