Git Product home page Git Product logo

Comments (7)

privatenumber avatar privatenumber commented on June 6, 2024

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.

darcyrush avatar darcyrush commented on June 6, 2024

@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 imports, 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.

privatenumber avatar privatenumber commented on June 6, 2024

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.

darcyrush avatar darcyrush commented on June 6, 2024

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.

darcyrush avatar darcyrush commented on June 6, 2024

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.

privatenumber avatar privatenumber commented on June 6, 2024

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.

darcyrush avatar darcyrush commented on June 6, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.