Local import in FFI file (PureScript v0.15)

Hi,

I’m nearly done migrating a PureScript app to v0.15 but am having some difficulty with a “local” (relative) import of a file called Shared.js into an FFI file. (I need to do this because I have several FFI files that need to share some JS code.)

Previously, in BarChart.js, the FFI file for BarChart.purs, I imported a shared local module using a relative path:

const shared = require("/src/app/Shared")

I used lebab to convert to ES6 modules, which turned this into:

import shared from "/src/app/Shared";

Building with spago build then worked fine. However, spago bundle-app reports:

✘ [ERROR] Could not resolve "/src/app/Shared"

    output/App.BarChart/foreign.js:4:19:
      4 │ import shared from "/src/app/Shared";

The output folder contains a directory App.BarChart containing foreign.js and index.js as expected. I can’t see any outputs that correspond to Shared.js, so it’s not surprising that the import can’t be resolved, but I’m not clear on how this worked previously, or what step of the process is responsible for ensuring any local JS modules needed by FFI files are bundled correctly.

Can anyone offer any help on this?

many thanks,
Roly

What is your overall file-structure?
I guess the main problem will be that esbuild starts in your output folder and you might have to find a valid path from there.

I have (after building):

src
   app
      BarChart.js
      BarChart.purs
      Shared.js
output
   App.BarChart
      foreign.js
      index.js

Maybe the problem is that Shared.js isn’t really part of my node environment and so won’t be resolvable when esbuild runs.

I’m wondering if I need to use npm-link to add a local directory containing my shared module to node_modules, and then add that as an explicit package dependency in package.json. I think then I should be able to import the local module without using a relative path.

I don’t think esbuild will allow you to step out of output and then into src so
npm-link might be a good idea here - I’d try with this - other options like copying Shared.js somewhere into output seems hacky

1 Like

Thanks. For now I’ve just duplicated the shared code across my various FFI impls, and I plan to come back to this issue once everything is running and tested. I’ll report back here if I find a solution.

2 Likes

For our application, with webpack, we use package aliases. We put shared code in a separate JS tree, and setup an alias that points to the tree. Since it doesn’t rely on relative paths, it doesn’t matter where the FFI ends up.

I don’t think esbuild supports this natively, but there may be a plugin, and from Google it looks like it supports resolving “paths” in tsconfig.

1 Like

Thanks, that’s useful.

If you’re interested in nix, purs-nix has an api for this situation.

1 Like