Taritsyn / JavaScriptEngineSwitcher

JavaScript Engine Switcher determines unified interface for access to the basic features of popular JavaScript engines. This library allows you to quickly and easily switch to using of another JavaScript engine.
Apache License 2.0
440 stars 49 forks source link

JavaScriptEngineSwitcher crashes in a dockerized .NET Core application #27

Closed omg-a-bear closed 7 years ago

omg-a-bear commented 7 years ago

I'm pre-rendering some javascript server side in a current project, using ReactJS.NET which in turn relies heavily on JavaScriptEngineSwitcher.

Running the project from a host OS, I have no problems what so ever. I'm using ChakraCore as the engine to pre-render my React components, and I have NuGet references for the following dependencies:

- JavaScriptEngineSwitcher.ChakraCore
- JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64
- JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64
- JavaScriptEngineSwitcher.ChakraCore.Native.win-x64

Running the project with dotnet run succeeds in Windows, Mac OS X and Ubuntu/Debian. Publishing the application and running it from the publish directory succeeds in all operating systems as well (using dotnet publish -c Release -o <MYPATH> && cd <MYPATH> && dotnet <DLLFILE>).

However, when creating a Docker container from my published files and running the application from a container (using base image microsoft/aspnetcore:1.1.1) I get the following exception (runtime, on first page load):

React.TinyIoC.TinyIoCResolutionException: Unable to resolve type: React.ReactEnvironment ---> React.TinyIoC.TinyIoCResolutionException: Unable to resolve type: React.JavaScriptEngineFactory ---> React.Exceptions.VroomJsInitialisationException: Failed to initialise VroomJs. This is most likely caused by the native library (libVroomJsNative.so) being out of date or your system lacking a compatible version of V8.

It seems like ChakraCore isn't registered as my default engine, or .NET Core can't find the library file? I register ChakraCore as my default javascript engine using;

services.AddJsEngineSwitcher(options =>
    options.DefaultEngineName = ChakraCoreJsEngine.EngineName
).AddChakraCore();

I've even tried using a ChakraCore binary (libChakraCore.so) compiled in my Docker image, but without success. Is there anything I'm missing, or is it something I'm missing in my setup?

I realize the problem might lie in ReactJS.NET as well - but since the main problem seems to be that the default engine isn't initialized I'm guessing it has something to do with JavaScriptEngineSwitcher.

Taritsyn commented 7 years ago

Hello, Björn!

options.DefaultEngineName = ChakraCoreJsEngine.EngineName

As far as I know, that this option is not used in ReactJS.NET version 3.X. The same error (Failed to initialise VroomJs.) is already registered in issue tracker of React.NET - “Cannot force to use Chakra engine instead of VroomJs”.

omg-a-bear commented 7 years ago

Hello Taritsyn, and thank you for the quick response!

I saw that thread when googling for a solution, but I'm not sure that it applies to my situation? The thing I think is weird, is that I can run the application without any problems on a fresh installation of Ubuntu - without Chrome or V8 installed on the system. Nodejs is however installed on that Ubuntu machine, so maybe libVroomJs is available through nodejs in that case?

Taritsyn commented 7 years ago

In your case, need to build the native assemblies of VroomJs - https://github.com/pauldotknopf/vroomjs-core#maclinux. But as far as I am aware, that this build script is not working.

I recommend you to read the “VroomJsInitialisationException: Failed to initialise VroomJs” discussion.

Daniel15 commented 7 years ago

ReactJS.NET iterates through all the engine factories and uses the first working one (see https://github.com/reactjs/React.NET/blob/master/src/React.Core/JavaScriptEngineFactory.cs#L254), so you just need to register your preferred engine first. It could be modified to use DefaultEngineName and fall back to checking the other engines - Feel free to send a pull request for that 😃

Note that ReactJS.NET has a default engine configuration (see https://github.com/reactjs/React.NET/blob/master/src/React.Core/JavaScriptEngineFactory.cs#L358-L384) that's used if you don't configure JavaScriptEngineSwitcher yourself. If you do configure JavaScriptEngineSwitcher, your config will override ReactJS.NET's one. So just call EngineFactories.AddChakraCore() and you should be fine.