Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
tsc-esm-fix
Advanced tools
Make tsc-compiled `es2020/esnext` bundles compatible with esm/mjs requirements
Make TS projects compatible with esm/mjs requirements
This workaround is aimed to bypass a bunch of tsc, ts-jest and esbuild issues right here and right now.
.js
extensions for relative module paths if compiled as es2020/esnext
.import.meta
is not allowed.Nightly build TypeScript 4.7 provides experimental esm support. But it still forces to add extensions by hand (tested on 4.7.0-dev.20220408).
src/main/ts/q/u/x/index.ts:1:21 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Did you mean '../../../foo.js'?
1 import { foo } from '../../../foo'
This lib covers 1 and 2 options.
import {foo} from './foo'
→ import {foo} from './foo.js'
import {baz} from 'external/baz'
→ import {baz} from 'external/baz.js'
import {bar} from './bar'
→ import {bar} from './bar/index.js'
outDir
found in tsconfig.json.__dirname
and __filename
refs with import.meta
.export {}
(esbuild issue 1043)require
statements with new file refs if ext changes (hybrid/dual pkg)Node.js ^12.20.0 || ^14.13.1 || >=16.0.0
yarn add -D tsc-esm-fix
tsc-esm-fix [options]
# to post-process outputs each time
tsc-esm-fix --target='target/es6'
# to patch ts sources once
tsc-esm-fix --target='src/main/ts' --ext='.js'
import { fix } from 'tsc-esm-fix'
await fix({
dirnameVar: true,
filenameVar: true,
ext: true
})
Input
code ref
import { foo } from './foo';
import './bar';
// external cjs module
import * as e1def from 'e1/a/b/c';
import * as e1root from 'e1';
const { e1 } = e1def;
const { e1: e1x } = e1root;
export { e1, e1x };
// external esm module with `main` in pkg.json
export { m1 } from 'm1';
export { m1 as m1x } from 'm1/index';
// external esm module with `exports` in pkg.json
export { e2 } from 'e2';
export { e2 as es3 } from 'e2/index';
export { e2 as es4 } from 'e2/alias';
export { e2foo } from 'e2/foo';
export { e2bar } from 'e2/bar-bundle';
export * from './foo';
export * from './baz';
export * from './q/u/x';
export const foobaz = foo + 'baz';
export { foo as foo1 } from './foo.js';
// Dir with index.js file inside: ./qux.js/index.js
export { qux } from './qux.js';
export const dirname = __dirname;
export const filename = __filename;
console.log(foobaz);
Output
import { foo } from './foo.js';
import './bar.js';
import * as e1def from 'e1/a/b/c/index.js';
import * as e1root from 'e1';
const { e1 } = e1def;
const { e1: e1x } = e1root;
export { e1, e1x };
export { m1 } from 'm1';
export { m1 as m1x } from 'm1/index.js';
export { e2 } from 'e2';
export { e2 as es3 } from 'e2/index';
export { e2 as es4 } from 'e2/alias';
export { e2foo } from 'e2/foo';
export { e2bar } from 'e2/bar-bundle';
export * from './foo.js';
export * from './baz/index.js';
export * from './q/u/x/index.js';
export const foobaz = foo + 'baz';
export { foo as foo1 } from './foo.js';
export { qux } from './qux.js/index.js';
export const dirname = /file:\\\\/\\\\/(.+)\\\\/[^/]/.exec(import.meta.url)[1];
export const filename = /file:\\\\/\\\\/(.+)/.exec(import.meta.url)[1];
tsc-esm-fix [opts]
Option | Description | Default |
---|---|---|
--tsconfig | Path to project's ts-config(s) | tsconfig.json |
--src | Entry points where the ts-source files are placed. If defined src option suppresses target | |
--target | tsc-compiled output directory | If not specified inherited from tsconfig.json compilerOptions.outDir |
--dirnameVar | Replace __dirname usages with import.meta | true |
--filenameVar | Replace __filename var references with import.meta statements | true |
--ext | Append extension to relative imports/re-exports | .js |
--unlink | Remove original files if ext changes | true |
--fillBlank | Fill blank files with export {} | false |
--cwd | cwd | process.cwd() |
--out | Output dir. Defaults to cwd , so files would be overwritten | process.cwd() |
--debug | Prints debug notes |
import { fix, IFixOptions } from 'tsc-esm-fix'
const fixOptions: IFixOptions = {
tsconfig: 'tsconfig.build.json',
dirnameVar: true,
filenameVar: true,
ext: true
}
await fix(fixOptions)
export interface IFixOptions {
cwd: string
src?: string | string[]
target?: string | string[]
out?: string
tsconfig?: string | string[]
dirnameVar: boolean
filenameVar: boolean
fillBlank?: boolean
ext: boolean | string
unlink?: boolean,
debug?: boolean | IFunction
}
Feel free to open any issues: bug reports, feature requests or questions. You're always welcome to suggest a PR. Just fork this repo, write some code, add some tests and push your changes. Any feedback is appreciated.
type="module"
{ default: {} }
FAQs
Make tsc-compiled `es2020/esnext` bundles compatible with esm/mjs requirements
The npm package tsc-esm-fix receives a total of 19,803 weekly downloads. As such, tsc-esm-fix popularity was classified as popular.
We found that tsc-esm-fix demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.