Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Cannot find module" from .ts file. #26

Open
rbtcollins opened this issue Oct 7, 2019 · 8 comments
Open

"Cannot find module" from .ts file. #26

rbtcollins opened this issue Oct 7, 2019 · 8 comments

Comments

@rbtcollins
Copy link

I'm not sure whats going on here - rather new to parcel. I have a wasm project in a parallel direction to the js tree:

npm-project
+src
 |+foo.ts
wasm-project
+Cargo.toml

in foo.ts I have tried each of

import lib from "../wasm-project/Cargo.toml";
import lib from "../../wasm-project/Cargo.toml";
import lib from "../../../wasm-project/Cargo.toml";

all of them report 'Cannot find module'.

The npm project using parcel is an existing mature code base that works fine in other regards as far as I can tell :).

Any suggestions? Is this a supported feature?

@catsigma
Copy link
Collaborator

catsigma commented Oct 7, 2019

Your folder is:

npm-project
  +src
    +foo.ts
wasm-project
  +Cargo.toml

right?

And what cmd did you use to complie the foo.ts?

@rbtcollins
Copy link
Author

rbtcollins commented Oct 7, 2019

Yes, thats right.

Compiled the typescript via > tsc -p . - the build does a

npm run compile && npm run bundle:browser && npm run bundle:node

then

tsc -p .

Which is when the error from typescript occurs.

I've attempted to work around this using a js thunk file - I copied the .d.ts from the rust pkg directory to 'src/wasmthunk.d.ts' and made a 'wasmthunk.js' that imports from the Cargo.toml and then exports everything.

That sort of worked.

I say sort of worked because its throwing an error in the browser:

TypeError: s.readFile is not a function wasm-loader.js:437

which is from

    function E(r) {
      const s = require("fs");

      return new Promise(function (e, n) {
        s.readFile(t + r, function (t, r) {
          t ? n(t) : e(r.buffer);
        });
      }).then(e => WebAssembly.instantiate(e, {
        "./foo_wasm": n
...

Thank you for responding so amazingly fast btw!

@rbtcollins
Copy link
Author

Re the workaround failing, we bundle twice: once for browser and once for node:

parcel build -d browser --out-file browser.js --global foo src/index.ts

and

parcel build --target node src/index.ts

Then we call parcel serve -d out path-to-index.html

@catsigma
Copy link
Collaborator

catsigma commented Oct 7, 2019

In my own test project, I can directly use parcel to build a .ts file with Cargo.toml import.

@jamieparkinson
Copy link

I encountered a similar sort of thing to this - I believe that the reason that parcel can build the .ts file importing a Cargo module with this plugin is because Parcel is not actually performing proper TS checking & module resolution (see here for example).

To "prove" this you can move the definition generated by wasm-pack, /pkg/<module name>.d.ts, to Cargo.toml.d.ts and you should see that TS is happy with this (although it lacks the default wasm export, which is typed in /pkg/<module_name>_bg.d.ts).

I think that one option for this would be to merge the generated definitions into this.wasm_bindgen_js in the Asset class, or (probably better) to merge them into a new Cargo.toml.d.ts file, like what's done here for CSS Modules.

This merging & string-twiddling does seem brittle to me so perhaps it would be better to export the raw wasm stuff separately, like the Webpack loader does. Hopefully the situation will improve when Parcel's TS support is better!

@sliminality
Copy link

I'm having the same problem, it's a huge headache. This issue is also related: rustwasm/wasm-bindgen#182 (comment)

@chinoto
Copy link

chinoto commented Dec 27, 2020

I've spent a couple days trying to figure this out* and settled on ln -s ./pkg/{package_name}.d.ts Cargo.toml.d.ts. Slightly better than copying since it only has to be done once and works forever instead of needing to be included in a build script.
*partially due to being new to TypeScript and not understanding how .d.ts files are handled right away.

npx parcel build Cargo.toml works, so I could potentially import * as my_tool from './my_tool/pkg' in index.html and run npx parcel <build|watch|serve> my_tool/Cargo.toml index.html assuming they are built in that order and not concurrently.

@chinoto
Copy link

chinoto commented Jan 16, 2021

I've found a partial* workaround for this: ln -s pkg/{package_name}.d.ts Cargo.toml.d.ts. The next time you run parcel, the typing file in pkg will be created and the symbolic link will make your import of Cargo.toml properly typed. Slightly better than copying because there's no need to hook into Parcel's build process to make sure a copy happens. Would be nice if you could tell TypeScript "treat importing this file as if I imported this other file that is fully typed".
*You don't get typings for {package_name}_bg.wasm.d.ts, not sure how to get around this, though it shouldn't usually matter.

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

No branches or pull requests

5 participants