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

Why does Import relative paths is changed by Fable depending on the destination ? #3698

Closed
leononame opened this issue Jan 14, 2024 · 2 comments
Labels

Comments

@leononame
Copy link

leononame commented Jan 14, 2024

Description

When running the fable compiler, jsNative functions with the Import attribute will change relative import paths if the output folder does not have the same depth as the fable project folder. I have this repo as an example: https://github.com/leononame/fable-repro

Repro code

module Repro
open Fable.Core

[<Import("log", "../../../../features/accounting/amount/Amount")>]
let log: string -> unit = jsNative

[<Import("log", "pkg/log")>]
let log2: string -> unit = jsNative

let sayHello =
    log "Hello"
    log2 "World"

Running:

dotnet fable projects/ClassLibrary1 -o bin

and

dotnet fable projects/ClassLibrary1 -o bin/nested

will produce two different files for Library.js:

import { log } from "../../../../features/accounting/amount/Amount";
import { log as log_1 } from "pkg/log";

export const sayHello = (log("Hello"), log_1("World"));

and

import { log } from "../../../features/accounting/amount/Amount";
import { log as log_1 } from "pkg/log";

export const sayHello = (log("Hello"), log_1("World"));

Expected and actual results

I kinda would expect the import paths to stay constant, not depending on output directory.

Related information

  • Fable version: 4.9.0
  • Operating system: Linux
@MangelMaxime
Copy link
Member

Hello,

This is the expected behaviour.

When using relative import Fable rewrite the imports so they always point to the same file depending on where you output the files. This is because Fable doesn't move JavaScript files so it adapt the relative imports to point to the original JavaScript position. Without that, you would need to move the JavaScript to the correct destination manually.

If you have the following structure where Program.fs use [<Import("log", "./util.js")>]

|- src
	|- Program.fs
	|- util.js

Then Fable will adapt the ./util.js path because Fable doesn't copy JavaScript file to the output.

So if you run dotnet build fable src you will get:

|- src
	|- Program.fs
	|- Program.fs.js
	|- util.js

So it will use import {log} from "./util.js"

But if you run dotnet build fable src --outDir dist/fable then you will get:

|- dist
	|- fable
		|- Program.js
|- src
	|- Program.fs
	|- util.js

And the import statement will be import {log} from "./../../util.js".

Note how both version will still be able to import the util.js file.

If you want your import path to not be rewritten by Fable, you can use ${outDir} macro in the import path and this will tell Fable that you have making your input path relative from the destination folder.

For example, [<Import("log", "${outDir}/util.js")>] but this means that in the second case you will need to move the util.js to the correct place.

@leononame
Copy link
Author

Ok, thanks for the response, I understand :)

@MangelMaxime MangelMaxime changed the title Import attribute changes relative paths when output folder is not equal to fable folder Why does Import relative paths is changed by Fable depending on the destination ? Jan 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants