Comments (7)
The underlying runtime may be CommonJS, but you're writing in ESM syntax. It would be unexpected if ESM doesn't behave like ESM.
from tsx.
@privatenumber Can you expand on what you mean by "writing in ESM syntax"? The only thing I can think you are referring to is the use of import
s, but this is a widely used TypeScript feature that transpiles down to require
when the module is set to commonjs
.
tsc --target es2022 --moduleResolution node --module commonjs src/main.ts
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const bootstrap_1 = require("./bootstrap"); // Transpiled to CJS
(0, bootstrap_1.bootstrap)().then();
Everything you state in previous comments holds true when the output is esm.
tsc --target es2022 --moduleResolution node --module esnext src/main.ts
import { bootstrap } from "./bootstrap";
bootstrap().then();
I assume tsx
transpiles to ESM by default so I added a tsconfig.json
and used an ENVIRONMENT value before executing tsx
, but I still get the same issue
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "Node"
}
}
"test-tsx": "TSX_TSCONFIG_PATH=./tsconfig.json node --import tsx --test 'test/**/*.test.ts'",
Again, please inform me if I misunderstand something fundamental. Trying to understand the nuances of CJS, ESM, TS and Node interoperability along with how tsx interacts with all of it is not the most clear for me...
from tsx.
I'm just relaying what it says in the spec.
It says imports are read-only: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
If you want to dig deeper, try finding the ES spec for imports.
from tsx.
I will try and clarify further. The spec you quote - from my understanding - is for 'newer' ESM modules in JS. But the spec relates only to JS, not TS. We both agree that JS code adhering to ESM using native ES imports, imports those modules as immutable objects.
However, TypeScript has functionality to output to either ESM or CJS, using module
;
https://www.typescriptlang.org/docs/handbook/modules/reference.html#emit
node16 and nodenext describe versions of Node.js that support ES modules, not just projects that use ES modules. Both ESM and CommonJS emit are supported, based on the detected module format of each file
When module
is set to node16
or nodeNext
, then TypeScript transpiles .ts
files as 'modern' ESM JS code, using native imports.
When module
is set to commonjs
(or the package.json
is missing "type": "module"
) - as is in my case - then TypeScript transpiles .ts
files as 'older' CJS JS, where import
is transpiled to require
.
So regardless if you want to output to ESM or CJS, when writing TypeScript .ts
files, you can use import package from 'package'
notation but this doesn't mean the transpiled JS is ESM by default.
It appears that typescript uses the following logic to determine whether a file is ESM or CJS. If package.json
is missing "type": "module"
, then .ts
files are output as CJS by default
.ts/.tsx/.js/.jsx/.d.ts files are ES modules if the nearest ancestor package.json file contains "type": "module", otherwise CommonJS modules.
So when a project is setup to output to CJS, I would expect tsx to allow mocking libraries to mutate imported modules.
from tsx.
I will update the minimal reproduction repository with a better example, since I believe part of the confusion comes from my (incorrect) test case which indeed only works under ESM...
from tsx.
Sorry but even if I were to be convinced to accept this issue, it would probably never be a priority for me to work on it unless I'm paid or encountering the issue myself.
I'm not convinced to stray away from spec. But if were you, and I wanted this feature so much to open 3 lengthly issues about it, I'd probably just implement it myself in a fork.
from tsx.
@privatenumber I apologize for opening multiple issues, i just wanted to try and leave one accurate issue remaining (which I still believe is #508 rather than this one) and you closed all others including the ability to comment further.
As for your stance not to tackle this issue, that is completely understandable and I respect that.
Just to clarify one final time however, I am not trying to mock immutable ESM module package imports but CJS required packages transpiled from TypeScript ESM-like import notation.
Should anyone else stumble across this issue when migrating a large project from CJS to ESM, my approach now will be to migrate to using tsx
after the code and ESM compatible mocking (module interception) library have been updated, rather than trying to move from ts-node
to tsx
first while still using CJS settings.
from tsx.
Related Issues (20)
- Environment variables support HOT 5
- Typescript REPL HOT 1
- Multiline input in Typescript REPL
- Feature request: Extend 'tsx watch' for run command on detects file changes HOT 2
- Parse error when using classes and complicated hashbangs
- Script not running when node=21, type="module", watchmode is enabled, is importing from "node:process" and using turborepo HOT 1
- Support `--input-type=ts` HOT 2
- tsx can't run code with endent HOT 3
- Is Bundle / Compile command planned? HOT 1
- Regression with MikroORM introduced with tsx v4.9.1 HOT 2
- Regression in 4.9.1 βΒ Cannot find module (β¦) Did you mean to import "β¦.js"? HOT 2
- Modules imported dynamically from an absolute path are not loaded/handled by tsx v4.9.1 HOT 3
- π Logo early preview and feedback
- `node:assert`'s `assert.ok(false)` is really slow when using tsx HOT 5
- Unexpected `top-level await error` for `type: module` + top level await in `node_modules` HOT 1
- [ESM / Node v22] Broken import of a correctly bundled library HOT 3
- Incompatible with `import-in-the-middle` loader HOT 4
- Parsing error when using variable `of` HOT 7
- Cannot be used with Nuxt HOT 5
- c8 incorrectly reports 100% coverage when using tsx HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tsx.