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

Running TypeScript compiler on Java Nashorn #8565

Closed
wants to merge 1 commit into from

Conversation

vojtechhabarta
Copy link

Fixes #1789.

This PR allows TypeScript compiler to run on Java 8 Nashorn JavaScript engine. Implementation of ts.System interface for Java environment is quite straightforward with one exception. There is no way to get the path of executing file (needed in ts.System.getExecutingFilePath() function) so I used executingFilePath Java system property to pass this information in.

Running from command line

Java provides jjs command which runs specified JavaScript files but unfortunately it cannot be used as host in Jakefile.js directly because it doesn't have the same parameters as node. Therefore I created jjs-host.cmd (not part of the PR) which passes parameters to jjs the way it expects them. It also adds executingFilePath property:

@echo off

set executingFilePath=%1
shift

set parameters=
:ParameterLoop
if "%1"=="" goto ExitParameterLoop
    set parameters=%parameters% %1
    shift
goto ParameterLoop
:ExitParameterLoop

jjs -DexecutingFilePath=%executingFilePath% %executingFilePath% -- %parameters%

Test

Then it is possible to test compiler on Java using following commands in PowerShell:

jake local
jake runtests
jake LKG
$env:TYPESCRIPT_HOST = "jjs-host"
jake local

Performance

Unfortunately running tsc.js on Java is very slow when compared to Node.js. I tried to compile TypeScript compiler itself using jake local and I also tried to compile single-line "Hello world" program. Results are in table bellow.

Sources to compile Java Node.js
"Hello world" program 0:40 0:01
TypeScript compiler (jake local) 10:48 0:21

I didn't expect it to be that bad. I hope it will improve in the future.

@msftclas
Copy link

Hi @vojtechhabarta, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!
We will now validate the agreement and then real humans will evaluate your PR.

TTYL, MSBOT;

@martyglaubitz
Copy link

even when execution time might not be the best, this deserves some love as it would enable CI servers & dev machines without node to run the compiler

@vladima
Copy link
Contributor

vladima commented May 24, 2016

I've tried to compile the compiler on Ubuntu using Nashorn (nashorn 1.8.0_91) and node (node 5.7.0) and results that I got:

  • total time on node: 4.5s
  • total time on nashorn: 103.1s (I have to include lib.d.ts explicitly in the list of files being compiled otherwise I was getting Cannot read file 'lib.d.ts'). it is ~23 times slower than node.

If we add Nashorn support then we need to use it when running our test suite on the CI server to make sure that we won't accidentally break something. Currently test run on Travis takes roughly 8 minutes so if we throw Nashorn into mix it presumably will be (8*23 =) 184 min. Given the relatively low demand for this feature (we have just a couple of requests for it) and high cost of it for developers to support I don't think we can accept this PR.

I can suggest the following: currently compiler checks for presence of ChakraHost object and if it exists it will be used as a underlying implementation of sys. What you can do is create a custom package that will wrap the compiler and implement ChakraHost using Nashorn API.

@vladima vladima closed this May 24, 2016
@vojtechhabarta
Copy link
Author

Thanks for trying this PR and confirming the performance problem with Nashorn. I agree that it is unusably slow.

Also thank you for the hint with ChakraHost. I will not implement this right now (given the Nashorn slow performance) but it is really good to know there is a way.

@wmono
Copy link

wmono commented May 25, 2016

@vojtechhabarta This is brilliant and exactly what we need. Can I suggest splitting this off as an independent Java project? I think you'd only need a small driver class to create a Nashorn instance, load your System object, then load tsc.js. Let me know if you want to do that. If not, I wouldn't mind giving it a shot myself.

@vojtechhabarta
Copy link
Author

@wmono we use frontend-maven-plugin for build and I am considering to use ts.transpileModule for embedded scenario so feel free to start Java project and copy&paste my System implementation. But currently the system is determined automatically so you cannot just set it up front and call tsc.js.

@vladima do you think this could be changed so that sys variable is only set if it is undefined?

@wmono second possibility is provide ChakraHost global object as suggested above.

@wmono
Copy link

wmono commented May 25, 2016

Indeed, it's the interaction between always setting ts.sys and including the ts.executeCommandLine call in tsc.js that is causing a problem here. Either setting ts.sys conditionally or moving the ts.executeCommandLine call to bin/tsc (and other entry points, if any) would effectively make the System implementation pluggable. The latter option makes everything else pluggable, too. (Sort of.)

I don't really consider making Nashorn pretend to be Chakra to be a proper solution. It looks like it could work for now, but how long until something is added to System that is implemented as a not-so-thin wrapper?

I have gotten as far as getting the usage message to appear by removing the last line of tsc.js and loading in a somewhat stubbed out System object. (There were a couple of gotchas due to this version of System living outside of TypeScript, both in language and in environment, so I left a few things out for the moment.) I haven't looked into the lib.d.ts issue yet but I can confirm that it still exists.

@vojtechhabarta
Copy link
Author

When you set executingFilePath Java system property, tsc should be able to locate lib.d.ts file. You can create jjs-host.cmd as described in PR description.

I realized there is a bug in getJavaSystem().readDirectory(). Here is a fix:
vojtechhabarta@046cbef

@wmono
Copy link

wmono commented Dec 13, 2016

If anyone is still interested, I've been tinkering with this again and have a proof of concept at https://github.com/wmono/jtsc.

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants