InsightSoftwareConsortium / ITK-Wasm

High performance spatial analysis in a web browser and across programming languages and hardware architectures
https://wasm.itk.org
Apache License 2.0
194 stars 49 forks source link

Issue with package.json "exports" and TypeScript #567

Open ty-ler opened 2 years ago

ty-ler commented 2 years ago

I am unable to use the latest release version of itk-wasm (1.0.0-b.8) with TypeScript 4.6. When compiling and executing my script which imports from itk-wasm, this error is thrown:

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in <path-to-project>/node_modules/itk-wasm/package.json

I have created a basic example project which reproduces the issue: itk-wasm-ts-test

It seems that the "exports" field in package.json is unsupported in versions of TypeScript lower than 4.7 (which is currently just in beta). More discussion on the issue can be found here:

thewtex commented 2 years ago

Hi @ty-ler ,

Thanks for the detailed report and example project :clap: .

It seems the Typescript compilation in the project passes, but the execution of node dist/index.js fails because the output is commonjs. The error message is not too clear, but itk-wasm only outputs ESM, not commonjs, and this may be the issue. Outputting commonjs in addition to es2020 seems difficult because we use import.meta.url in our Typescript sources.

FezVrasta commented 2 years ago

I get the same error, we are using tsc to run the code on node.

I'm using TS 4.7.2 and ts-node 10.8.0

If I change compilerOptions.module to NodeNext the error becomes:

 Cannot find module 'itk-wasm' or its corresponding type declarations.

And if I @ts-ignore it I go back to:

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined ...
thewtex commented 2 years ago

Hi @FezVrasta , are these errors with ESM or CommonJS modules?

FezVrasta commented 2 years ago

This is the tsconfig configuration @thewtex

{
  "compileOnSave": true,
  "compilerOptions": {
    "strict": true /* Enable all strict type-checking options. */,
    "target": "ES2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "outDir": "./build" /* Redirect output structure to the directory. */,
    "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */,
    "sourceMap": true,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
    "lib": ["ES2019", "DOM", "DOM.Iterable"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

I have been trying to get ts-node to work with module: ESNext but I can't get the baseUrl imports to work with it. Reading online it looks like either TS or ts-node are not compatible with it.

Even after I applied tens of workarounds to make the code compile I eventually end up with errors due to some of our dependencies being commonjs modules rather than es modules, nothing we can do about that unfortunately.

I think this package should provide a commonjs version for node :-(

thewtex commented 2 years ago

@FezVrasta thanks for the hard work investigating. The JS ecosystem is in a frustrating place now with ESM migration.

I think I know the answer, but to confirm -- you want commonjs modules, but your eventual target is the browser, not node, correct? I want to confirm because can generate the commonjs modules, but the worker loading will be more difficult.

FezVrasta commented 2 years ago

Our use case would be to run itk-wasm on node specifically, but I just recently synced with the rest of the team and it looks like we will move the DICOM tags extraction and sorting up the pipeline to the python backend so please don't spend time on this issue just for us as we won't use it in the foreseeable future.

ty-ler commented 1 year ago

@thewtex Hi again! I originally gave up on this last year, but unfortunately the same exact issue has shown up while trying to implement something with a bit more serious use case.

I am trying to use itk-wasm to turn some DICOM files, fetched from an API, into an itk Image object. This needs to happen in node, not the browser, but I can't get past the same error above.

Here is the tsconfig.json for the project:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "strict": false,
    "resolveJsonModule": true
  },
  "exclude": [
    ...
  ]
}

Please let me know if I can provide any more information to help debug this.