Skip to content

Does JavaScriptEngineFactory.cs really need a dependency on V8 or Chakra? #456

@JoshuaKGoldberg

Description

@JoshuaKGoldberg

Deploying multiple JS engine DLLs is a pain and extra time taken during server deployments. V8 in particular has a few DLL dependencies and can become DLL hell.

In setting up ReactJS.NET with a server, I ended up wanting to both set up my own container registrations and only ever use the Chakra engine. Here's the code it ended up with:

var container = AssemblyRegistration.Container;
var fileSystem = new SimpleFileSystem();

var msIeEngineFactory = new MsieJsEngineFactory();
JsEngineSwitcher.Instance.EngineFactories.Add(msIeEngineFactory);
JsEngineSwitcher.Instance.DefaultEngineName = "MsieJsEngine";

var engineFactory = new JavaScriptEngineFactory(
    JsEngineSwitcher.Instance,
    ReactSiteConfiguration.Configuration,
    fileSystem);

container.Register<IReactSiteConfiguration>((c, o) => ReactSiteConfiguration.Configuration);
container.Register<ICache, NullCache>();
container.Register<IFileCacheHash, FileCacheHash>().AsPerRequestSingleton();
container.Register<FileCacheHash, FileCacheHash>().AsPerRequestSingleton();
container.Register<IFileSystem, SimpleFileSystem>(fileSystem);
container.Register<JsEngineSwitcher>((c, o) => JsEngineSwitcher.Instance);
container.Register<IJavaScriptEngineFactory>(engineFactory);
container.Register<IReactEnvironment, ReactEnvironment>().AsPerRequestSingleton();
container.Register<ReactEnvironment, ReactEnvironment>().AsPerRequestSingleton();

ReactSiteConfiguration.Configuration
    .SetLoadBabel(false)
    .AddScriptWithoutTransform("local/Wat.js");

The JavaScriptEngineFactory call loads JavaScriptEngineFactory.cs, which has a dependency on JavaScriptEngineSwitcher.V8 or JavaScriptEngineSwitcher.ChakraCore:

#if NET40
using JavaScriptEngineSwitcher.V8;
#else
using JavaScriptEngineSwitcher.ChakraCore;
#endif

That means if you want to load that file, you have to load whichever engine switcher DLL is tied to your .NET version. Eww! In order to avoid having to figure out V8 deployments, I ended up copy & pasting JavaScriptEngineFactory into a new file and removing the references to V8. Forking is bad and I feel bad.

A better solution IMO would be to only load the DLLs deemed necessary. How about JavaScriptEngineFactory take in some sort of new IJavaScriptEngineProvider(s) via dependency injection? That way we can skip loading the V8 or Chakra DLLs unless necessary. It would also help remove some of the logic for switching between the two in the class itself, which as it stands now seems like a weird responsibility for the class to have.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions