weixin_39878698
weixin_39878698
2020-12-29 15:30

es4x-launcher: Cannot find file relative from sub directory

I have a compilation step using TypeScript to compile TypeScript source files into ES Modules within a directory called dist.

In package.json I have set main to be dist/index.mjs. I have also tried to run es4x from the output directory and tried to set the PWD environment variable with no luck.

When trying to run es4x-launcher, it complains that it cannot find a relative file to root, even though the compiled files are in another directory.

If I move the files as-is, out to the root of my project and run es4x, then they work fine. It seems as if it looks for files relative to the path of the package.json, rather than to the specified main entry.

I use the following TypeScript config for compilation:

json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "node",
    "target": "es2019",
    "lib": ["dom", "esnext"],
    "outDir": "dist",
    "baseUrl": ".",
    "strict": true,
    "sourceMap": false,
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "skipLibCheck": true
  },
  "include": ["src", "types"]
}

And rename all .js files to .mjs afterwards, since TypeScript can't output .mjs extensions yet.

The stack trace I get:


Does not resolve to a File: ./routes
        at io.reactiverse.es4x.impl.graal.VertxFileSystem.parsePath(VertxFileSystem.java:142)
        at com.oracle.truffle.api.TruffleLanguage$Env.getTruffleFile(TruffleLanguage.java:1975)
        at com.oracle.truffle.js.runtime.JSRealm$2.resolveImportedModule(JSRealm.java:1538)
        at com.oracle.truffle.js.parser.GraalJSEvaluator.hostResolveImportedModule(GraalJSEvaluator.java:345)
        at com.oracle.truffle.js.parser.GraalJSEvaluator.innerModuleInstantiation(GraalJSEvaluator.java:515)
        at com.oracle.truffle.js.parser.GraalJSEvaluator.moduleInstantiation(GraalJSEvaluator.java:487)
        at com.oracle.truffle.js.parser.GraalJSEvaluator$2.evalModule(GraalJSEvaluator.java:285)
        at com.oracle.truffle.js.parser.GraalJSEvaluator$2.execute(GraalJSEvaluator.java:279)
        at org.graalvm.polyglot.Context.eval(Context.java:342)
        at io.reactiverse.es4x.impl.graal.GraalRuntime.eval(GraalRuntime.java:173)
        at io.reactiverse.es4x.impl.graal.GraalRuntime.eval(GraalRuntime.java:34)
        at io.reactiverse.es4x.MJSVerticleFactory$1.start(MJSVerticleFactory.java:61)
        at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:552)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:495)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)
Caused by host exception: java.nio.file.InvalidPathException: Does not resolve to a File: ./routes
io.vertx.core.impl.NoStackTraceThrowable
Failed in deploying verticleio.vertx.core.impl.NoStackTraceThrowable
io.vertx.core.impl.NoStackTraceThrowable

该提问来源于开源项目:reactiverse/es4x

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

10条回答

  • weixin_39673002 weixin_39673002 4月前

    Small note: esm modules do not have the concept of relative paths, all imports are expected to be absolute to the project root.

    点赞 评论 复制链接分享
  • weixin_39878698 weixin_39878698 4月前

    So this is a GraalVM/Node-specific thing that it can find a file by relative path? As previously mentioned, it does work (with relative import) if files are moved to the root of the project.

    点赞 评论 复制链接分享
  • weixin_39673002 weixin_39673002 4月前

    yes the module resolution is still a on-going debate with node and on the browser side it assumes the root of the application so the relative paths from outside the project root are not allowed. With typescript this is allowed but it is not trivial to implement it also on graal because the module resolution happens before the code runs so there's no context when resolving paths (I can't tell the path of the parent module to calculate the relative path).

    I think a extra flag --esm is also needed in order to avoid stuff like you're doing (renaming all files) so this way we assume that modules are always in ESM format.

    Could you create a simple example project that shows this issue so I can play around and see if I can see a way to figure out how to resolve the relative paths if possible?

    点赞 评论 复制链接分享
  • weixin_39878698 weixin_39878698 4月前

    I think a extra flag --esm is also needed in order to avoid stuff like you're doing (renaming all files) so this way we assume that modules are always in ESM format.

    Yeah, I don't think the solution is to rename files, because sourcemaps would break too, unless you went in and replaced that part too, and that is honestly to much of a hassle to support ESM. Using a flag would make this more trivial.

    Could you create a simple example project that shows this issue so I can play around and see if I can see a way to figure out how to resolve the relative paths if possible?

    Yep, when I get home from work today, I'll push the exact example I had, which is still very simple, based on the example you have in this project.

    点赞 评论 复制链接分享
  • weixin_39673002 weixin_39673002 4月前

    when you have the time, please upload/gist/share the problematic project so I can investigate!

    点赞 评论 复制链接分享
  • weixin_39878698 weixin_39878698 4月前

    Hey sorry for the delay! Been quite busy in the past week. I made a repository with the project https://github.com/fnky/es4x-139-relative-path

    点赞 评论 复制链接分享
  • weixin_39673002 weixin_39673002 4月前

    I quickly hacked a working fix:

    
    $ es4x-launcher run -Des4x.prefix=./dist/ -esm ./index.js
    ./index.js -> ./dist/./index.js
    ./routes -> ./dist/./routes
    ./routes -> ./dist/./routes
    ./routes -> ./dist/./routes
    ./routes -> ./dist/./routes
    App running at http://localhost:8080
    Succeeded in deploying verticle
    ^C
    

    So the -esm will handle js as es6 modules and now I need to add a -prefix option that does the transformation printed in the log above. This seems a simple task (unless it will break tests) and will be released soon I hope.

    点赞 评论 复制链接分享
  • weixin_39878698 weixin_39878698 4月前

    Awesome! Really appreciate it :) I'll test it out

    点赞 评论 复制链接分享
  • weixin_39878698 weixin_39878698 4月前
     I have run into a little issue trying to test this out. I have compiled es4x using the `codegen` selection for Maven. I can find the runtime for ES4X (but requires me to extract it from a tar or zip file), but I can't seem to find es4x-launcher.
    

    Are these different things? And if so, how do I find the es4x-launcher after compiling ES4X.

    点赞 评论 复制链接分享
  • weixin_39673002 weixin_39673002 4月前

    es4x-launcher is created every time you do a es4x install. In that command the maven artifatcs are fetched from the local cache (and if missing from the internet) and the launcher is created with all the configured dependencies so you don't need to know anything about java class path settings to run the application.

    点赞 评论 复制链接分享

相关推荐