Skip to content
This repository has been archived by the owner on Sep 2, 2023. It is now read-only.

ESM module load #442

Closed
gengjiawen opened this issue Nov 22, 2019 · 11 comments
Closed

ESM module load #442

gengjiawen opened this issue Nov 22, 2019 · 11 comments

Comments

@gengjiawen
Copy link
Member

index.js

import {a} from './a'

console.log(a)

a.js

export const a = 3

Using Node.js 13.2 node index.js

(node:76399) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:94
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module /Users/daniel/code/node-esm/a imported from /Users/daniel/code/node-esm/index.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:94:13)
    at Loader.resolve (internal/modules/esm/loader.js:74:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:148:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:41:40)
    at link (internal/modules/esm/module_job.js:40:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}
@MylesBorins
Copy link
Member

@gengjiawen file extension and directory resolution are no longer supported in the esm loader. If you put the full filename it will work

index.js

import {a} from './a.js'

console.log(a)

There are a number of reasons people on the Modules Team like this change including better performance and web compatibility.

There is support for the former algorithm with a flag --es-module-specifier-resolution=node.

There is still some discussion being had about the final behavior we'll land on with this.

@MylesBorins
Copy link
Member

I'm going to close this but please feel free to keep the conversation going.

@gengjiawen
Copy link
Member Author

gengjiawen commented Nov 22, 2019

There is two downside in this

Typescript support

ts generate js code without the extension, so if I change ts output to "module": "esnext", it won't work.

Common FE writing

Also it's quite common to use without extension, like react or vue. I think this will bring much confusion.

@rauschma
Copy link

IMO, what we want to see in the future should take precedence over current practices. Less magic and less divergence from browsers are benefits of not doing this.

@sheerun
Copy link

sheerun commented Nov 22, 2019

Referencing proposal that doesn't involve "magic" or --es-module-specifier-resolution=node and solves this issue: #444

@jkrems
Copy link
Contributor

jkrems commented Nov 22, 2019

ts generate js code without the extension

IIRC TS does work fine with the extension, it just doesn't add extensions not present in the source. The following should be accepted by tsc:

// a.ts
import b from './b.js';

// b.ts
export default 42;

TSC should be smart enough to figure out that you meant b.ts even though the import is using the target filename.

@gengjiawen
Copy link
Member Author

What I mean is generated code by tsc

image

@jkrems
Copy link
Contributor

jkrems commented Nov 24, 2019

Right, if you use the extension in your typescript, typescript will generate code that has the extension. :)

@jcjolley
Copy link

When using typescript, adding the extension only works if you're working with js files. You can't import from './a.ts'

@chase-moskal
Copy link

chase-moskal commented Feb 19, 2020

@jcjolley -- in your typescript source, when importing another typescript file, use the .js extension, and it will work

that is, when importing b.ts, the code in a.ts should look like this:

import * as b from "b.js"

the import path reflects what ends up in the compiled output, not the path to the typescript source

@GeoffreyBooth
Copy link
Member

the import path reflects what ends up in the compiled output, not the path to the typescript source

See microsoft/TypeScript#35589 (comment) and the comments preceding it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants