public Visualizer(string baseDir)
        {
            _baseDir = baseDir;
            var services = new ServiceCollection();

            services.AddNodeServices();
            var options = new NodeServicesOptions(services.BuildServiceProvider())
            {
                ProjectPath = Directory.GetCurrentDirectory()
            };

            _node = NodeServicesFactory.CreateNodeServices(options);
        }
        private static INodeServices CreateNodeServicesInstance(
            IApplicationBuilder appBuilder, string sourcePath)
        {
            // Unlike other consumers of NodeServices, AngularCliMiddleware dosen't share Node instances, nor does it
            // use your DI configuration. It's important for AngularCliMiddleware to have its own private Node instance
            // because it must *not* restart when files change (it's designed to watch for changes and rebuild).
            var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices)
            {
                WatchFileExtensions = new string[] { }, // Don't watch anything
                ProjectPath         = Path.Combine(Directory.GetCurrentDirectory(), sourcePath),
            };

            return(NodeServicesFactory.CreateNodeServices(nodeServicesOptions));
        }
        public HandlerFactoryFixture()
        {
            var resolvers = new List <IMetadataReferenceResolver> {
                new DefaultMetadataReferenceResolver()
            };
            var builder = new DefaultAssemblyBuilder(new DefaultAssemblyLoadContextProvider(), resolvers);

            var options = new NodeServicesOptions(new ServiceCollection().BuildServiceProvider())
            {
                ProjectPath = Directory.GetCurrentDirectory()
            };
            var nodeServices = NodeServicesFactory.CreateNodeServices(options);

            Factory = new HandlerFactory(builder, nodeServices, typeof(string).GetTypeInfo().Assembly);             // mscorlib
        }
Example #4
0
        public static void Validate(string typescriptSource)
        {
            if (s_nodeServices == null)
            {
                var options = new NodeServicesOptions(NullServiceProvider.Instance);
                s_nodeServices = NodeServicesFactory.CreateNodeServices(options);
            }

            var task   = s_nodeServices.InvokeAsync <string>("TypeScriptValidator.js", typescriptSource);
            var result = task.GetAwaiter().GetResult();

            if (result != "success")
            {
                Assert.Fail("\n" + typescriptSource + "\n\nErrors:\n" + result);
            }
        }
        /// <summary>
        /// Adds NodeServices support to the <paramref name="serviceCollection"/>.
        /// </summary>
        /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
        /// <param name="setupAction">A callback that will be invoked to populate the <see cref="NodeServicesOptions"/>.</param>
        public static void AddNodeServices(this IServiceCollection serviceCollection, Action <NodeServicesOptions> setupAction)
        {
            if (setupAction == null)
            {
                throw new ArgumentNullException(nameof(setupAction));
            }

            serviceCollection.AddSingleton(typeof(INodeServices), serviceProvider =>
            {
                // First we let NodeServicesOptions take its defaults from the IServiceProvider,
                // then we let the developer override those options
                var options = new NodeServicesOptions(serviceProvider);
                setupAction(options);

                return(NodeServicesFactory.CreateNodeServices(options));
            });
        }
        public Task <NodePackage> GetInstalledPackageAsync(string path)
        {
            var pp = this.ParsePath(path);

            return(cache.GetOrCreateAsync <NodePackage>(pp.Package + "@" + pp.Version, async entry => {
                entry.SlidingExpiration = TimeSpan.FromHours(1);

                await InstallAsync(pp);

                var options = this.Options.NodeServicesOptions ?? new NodeServicesOptions(services)
                {
                    ProjectPath = pp.TagFolder,
                    NodeInstanceOutputLogger = services.GetService <ILogger <NodePackageService> >()
                };

                if (this.Options.EnvironmentVariables != null)
                {
                    if (options.EnvironmentVariables == null)
                    {
                        options.EnvironmentVariables = new Dictionary <string, string>();
                    }
                    foreach (var item in this.Options.EnvironmentVariables)
                    {
                        options.EnvironmentVariables[item.Key] = item.Value;
                    }
                }

                var s = NodeServicesFactory.CreateNodeServices(options);

                entry.RegisterPostEvictionCallback((x1, x2, x3, x4) => {
                    try
                    {
                        s.Dispose();
                    } catch (Exception ex)
                    {
                        Trace.WriteLine(ex);
                    }
                });

                return new NodePackage {
                    Path = pp,
                    NodeServices = s
                };
            }));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NodeRenderEngine" /> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="options">The options.</param>
        public NodeRenderEngine(IServiceProvider serviceProvider, NodeRenderEngineOptions options)
        {
            _options = options;

            var nodeOptions = new NodeServicesOptions(serviceProvider)
            {
                HostingModel        = options.NodeHostingModel,
                ProjectPath         = options.ProjectDirectory,
                WatchFileExtensions = options.WatchFileExtensions
            };

            if (options.NodeInstanceOutputLogger != null)
            {
                nodeOptions.NodeInstanceOutputLogger = options.NodeInstanceOutputLogger;
            }

            _nodeServices = NodeServicesFactory.CreateNodeServices(nodeOptions);
        }
Example #8
0
        public static IServiceCollection AddSmidgeJavaScriptServices(this IServiceCollection services)
        {
            services.AddSingleton <SmidgeJavaScriptServices>(provider =>
            {
                var env = provider.GetRequiredService <IHostingEnvironment>();
                return(new SmidgeJavaScriptServices(NodeServicesFactory.CreateNodeServices(
                                                        new NodeServicesOptions(provider)
                {
                    ProjectPath = env.ContentRootPath,
                    WatchFileExtensions = new string[] { }
                })));
            });

            //pre processors
            services.AddSingleton <IPreProcessor, UglifyNodeMinifier>();

            return(services);
        }
Example #9
0
        private static async Task RunServiceAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Start server
            INodeServices nodeService = ServiceLocator.Current.GetService <INodeServices>();

            if (nodeService == null)
            {
                nodeService = NodeServicesFactory.CreateNodeServices(new NodeServicesOptions(ServiceLocator.Current));
            }

            string result = nodeService.InvokeAsync <string>("server.js").Result;

            PrintNodeJsOutput(result);

            await AwaitCancellation(cancellationToken);

            //await nodeService.InvokeAsync<string>("Shutdown").Result;
        }
Example #10
0
        /// <summary>
        /// Creates a new instance of <see cref="PrerenderTagHelper"/>.
        /// </summary>
        /// <param name="serviceProvider">The <see cref="IServiceProvider"/>.</param>
        public VueRenderTagHelper(IServiceProvider serviceProvider)
        {
            _hostEnv             = (IHostingEnvironment)serviceProvider.GetService(typeof(IHostingEnvironment));
            _nodeServices        = (INodeServices)serviceProvider.GetService(typeof(INodeServices)) ?? _fallbackNodeServices;
            _applicationBasePath = _hostEnv.ContentRootPath;

            var applicationLifetime = (IApplicationLifetime)serviceProvider.GetService(typeof(IApplicationLifetime));

            _applicationStoppingToken = applicationLifetime.ApplicationStopping;

            // Consider removing the following. Having it means you can get away with not putting app.AddNodeServices()
            // in your startup file, but then again it might be confusing that you don't need to.
            if (_nodeServices == null)
            {
                _nodeServices = _fallbackNodeServices = NodeServicesFactory.CreateNodeServices(
                    new NodeServicesOptions(serviceProvider));
            }
        }
        public static IApplicationBuilder UseParcelBundler(this IApplicationBuilder app, ParcelBundlerOptions options)
        {
            var environment = app.ApplicationServices.GetService <IHostingEnvironment>();

            var nodeServiceOptions = new NodeServicesOptions(app.ApplicationServices)
            {
                WatchFileExtensions = new string[] { }
            };

            string content = LoadScriptContent();
            var    script  = new StringAsTempFile(content, nodeServiceOptions.ApplicationStoppingToken);

            var node = NodeServicesFactory.CreateNodeServices(nodeServiceOptions);

            var args = new
            {
                entryPoints = options.EntryPoints,
                options     = new
                {
                    outDir         = Path.Combine(environment.WebRootPath, options.OutDir ?? ""),
                    outFile        = options.OutFile,
                    publicUrl      = options.PublicUrl,
                    watch          = options.Watch,
                    cache          = options.Cache,
                    cacheDir       = options.CacheDir,
                    contentHash    = options.ContentHash,
                    minify         = options.Minify,
                    scopeHoist     = options.ScopeHoist,
                    target         = options.Target?.ToString().ToLower(),
                    https          = options.Https?.ToParcelOptions(),
                    hmr            = options.HotModuleReload?.IsEnabled,
                    hmrPort        = options.HotModuleReload?.Port,
                    sourcemaps     = options.SourceMaps,
                    hmrHostname    = options.HotModuleReload?.Hostname,
                    detailedReport = options.DetailedReport
                }
            };

            var response = node.InvokeExportAsync <ParcelServerInfo>(script.FileName, "runParcelBundler", JsonConvert.SerializeObject(args, SerializerSettings))
                           .Result;

            return(app);
        }
Example #12
0
        public PugRenderingTestsFixture()
        {
            var optionsMock = new Mock <IOptions <PugzorViewEngineOptions> >();

            optionsMock.SetupGet(q => q.Value)
            .Returns(new PugzorViewEngineOptions
            {
                // true: makes a lot of tests to fail
                Pretty = false
            });

            var mockServices       = new Mock <IServiceProvider>();
            var nodeServiceOptions = new NodeServicesOptions(mockServices.Object)
            {
                ProjectPath = TemporaryDirectoryHelper.CreateTemporaryDirectory(true)
            };
            var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServiceOptions);

            Renderer = new PugRendering(nodeServices, optionsMock.Object);
        }
Example #13
0
        public void Setup()
        {
            var websiteInfo = new Mock <IWebsiteInfo>();

            websiteInfo.Setup(x => x.GetBasePath()).Returns("/");
            websiteInfo.Setup(x => x.GetBaseUrl()).Returns(new Uri("http://test.com"));

            _jsMin   = new JsMinifier();
            _nuglify = new NuglifyJs(
                new NuglifySettings(new NuglifyCodeSettings(null), new CssSettings()),
                Mock.Of <ISourceMapDeclaration>());

            var nodeServices = new SmidgeJavaScriptServices(NodeServicesFactory.CreateNodeServices(
                                                                new NodeServicesOptions(new NullServiceProvider())
            {
                ProjectPath         = AssemblyPath,
                WatchFileExtensions = new string[] {}
            }));

            _jsUglify = new UglifyNodeMinifier(nodeServices);
        }
Example #14
0
        public NodeBindingTests()
        {
            var options = new NodeServicesOptions
            {
                ApplicationStoppingToken = stopTokenSource.Token,
                ProjectPath = AppDomain.CurrentDomain.BaseDirectory,
                NodeInstanceOutputLogger = Mock.Of <ILogger>(),
                DebuggingPort            = 9000,
                LaunchWithDebugging      = true
            };

            options.UseSocketHosting();
            nodeServices = NodeServicesFactory.CreateNodeServices(options);

            rpcHost = new JsonRpcBindingHost(js => new LineDelimitedJsonConnection(js));
            rpcHost.Repository.AddBinding("test", new TestBound());

            var initTask = nodeServices.InvokeExportAsync <Stream>("binding-init", "initialize", rpcHost.Repository.Objects);

            this.initTask = initTask.ContinueWith(t => (rpcHost.Connection as LineDelimitedJsonConnection)?.Initialize(t.Result, t.Result));
        }
        public static async Task <TResult> RunAsync <TData, TResult>(string module, TData data)
        {
            var services = new ServiceCollection();

            services.AddNodeServices(a =>
            {
                // a.ProjectPath = Directory.GetCurrentDirectory();
                // Set any properties that you want on 'options' here
            });

            var serviceProvider = services.BuildServiceProvider();
            var options         = new NodeServicesOptions(serviceProvider)
            {
                ProjectPath = Directory.GetCurrentDirectory() + "/tmphost",
                InvocationTimeoutMilliseconds = 60000 * 5,
            };
            var nodeServices = NodeServicesFactory.CreateNodeServices(options);



            var sb = new StringBuilder();

            // sb.AppendLine("return function (data,callback){");
            sb.AppendLine("var requirejs = require(\"requirejs\");");
            sb.AppendLine($"var r = requirejs.config({{   baseUrl:'{Path.Combine(Directory.GetCurrentDirectory(), "artifacts/app").Replace("\\", "/")}'}});");

            sb.AppendLine("module.exports= function (callback,data){ try{");
            sb.AppendLine($"r([\"{module}\"], function (program) {{ program.default(data, callback); }},function(err){{ console.log('host failed'); callback(err,null) }})");



            sb.AppendLine("}catch(error){console.log('host catch');callback(error,null); }}");

            Directory.CreateDirectory("tmphost");
            File.WriteAllText("tmphost/run.js", sb.ToString());

            return(await nodeServices.InvokeAsync <TResult>("./run", data));

            //  return JToken.FromObject(await Edge.Func(sb.ToString())(data)).ToObject<TResult>();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NodeRenderEngine" /> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="options">The options.</param>
        public NodeRenderEngine(IServiceProvider serviceProvider, NodeRenderEngineOptions options)
        {
            _options = options;

            var nodeOptions = new NodeServicesOptions(serviceProvider ?? new EmptyServiceProvider())
            {
                ProjectPath          = options.ProjectDirectory,
                WatchFileExtensions  = options.WatchFileExtensions,
                EnvironmentVariables = options.EnvironmentVariables,
                DebuggingPort        = options.DebuggingPort,
                LaunchWithDebugging  = options.LaunchWithDebugging
            };

            if (options.NodeInstanceFactory != null)
            {
                nodeOptions.NodeInstanceFactory = options.NodeInstanceFactory;
            }
            if (options.NodeInstanceOutputLogger != null)
            {
                nodeOptions.NodeInstanceOutputLogger = options.NodeInstanceOutputLogger;
            }

            _nodeServices = NodeServicesFactory.CreateNodeServices(nodeOptions);
        }
Example #17
0
        /// <summary>
        /// Sends a message using Gmail API
        /// </summary>
        /// <param name="msg">Message to send</param>
        /// <returns>JSON serialized string of a result object</returns>
        public string Send(EmailMessage msg)
        {
            string emailTemplate = GetMsgTemplate(msg.template.templateId);

            if (null == emailTemplate)
            {
                _logger.LogError($"Unable to load Email template with id {msg.template.templateId}");
                return(null);
            }

            string htmlBody = null;
            string subject  = null;

            ServiceCollection services = new ServiceCollection();

            services.AddNodeServices();

            using (ServiceProvider serviceProvider = services.BuildServiceProvider())
            {
                NodeServicesOptions options = new NodeServicesOptions(serviceProvider) /* Assign/override any other options here */ }
                {
                    ;
                    using (INodeServices nodeServices = NodeServicesFactory.CreateNodeServices(options))
                    {
                        htmlBody = nodeServices.InvokeAsync <string>("pugcompile", emailTemplate, null == msg.bodyModel ? null: JsonConvert.DeserializeObject(msg.bodyModel)).Result;
                        subject  = nodeServices.InvokeAsync <string>("pugcompile", msg.template.subjectTemplate, null == msg.subjectModel ? null : JsonConvert.DeserializeObject(msg.subjectModel)).Result;
                    }
            }

            services.Clear();

            if (null == subject)
            {
                _logger.LogError($"Unable to load email subject");
                return(null);
            }

            if (null == emailTemplate)
            {
                _logger.LogError($"Unable to load Email template with id {msg.template.templateId}");
                return(null);
            }

            UserCredential credential;

            string[] scopes = { GmailService.Scope.GmailSend };

            using (FileStream stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
            {
                // The file token.json stores the user's access and refresh tokens, and is created
                // automatically when the authorization flow completes for the first time.
                string credPath = "token.json";
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;

                _logger.LogInformation("Google credential file saved to: " + credPath);
            }

            // Create Gmail API service.
            using (GmailService service = new GmailService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "MailGmail",
            }))
            {
                Google.Apis.Gmail.v1.Data.Message message       = CreateGmailMessage(msg.from, msg.to, subject, htmlBody);
                Google.Apis.Gmail.v1.Data.Message messageResult = service.Users.Messages.Send(message, "me").Execute();

                return(JsonConvert.SerializeObject(messageResult));
            }
        }
Example #18
0
        private async Task <int> OnExecuteAsync(CommandLineApplication app)
        {
            if (string.IsNullOrEmpty(Url) && string.IsNullOrEmpty(RemotePageLocation) && !HelloWorld)
            {
                app.ShowHelp();
                return(0);
            }
            Console.WriteLine(HostFolder);

            Directory.CreateDirectory(HostFolder);
            Directory.CreateDirectory("output");
            await InstallNPMPackage(HostFolder, "requirejs");
            await  InstallNPMPackage(HostFolder, "puppeteer");
            await InstallNPMPackage(HostFolder, "websocket");
            await InstallNPMPackage(HostFolder, "isomorphic-fetch");
            await InstallNPMPackage(HostFolder, "earthml-temply-headless");


            var engine = new RazorLightEngineBuilder()
                         .UseEmbeddedResourcesProject(typeof(Program))
                         .UseMemoryCachingProvider()
                         .Build();

            Console.WriteLine(string.Join(" ", app.RemainingArguments));

            var args = new JObject();

            for (var j = 0; j < app.RemainingArguments.Count; j += 2)
            {
                args[app.RemainingArguments[j].Trim('-')] = app.RemainingArguments[j + 1];
            }

            IWebHost host = new WebHostBuilder()
                            .UseKestrel()

                            .Configure(appbuilder =>
            {
                appbuilder.Use(async(context, next) =>
                {
                    Console.WriteLine(context.Request.Path);

                    if (context.Request.Path == "/installDependencies")
                    {
                        var dps = JToken.Parse(await new StreamReader(context.Request.Body).ReadToEndAsync());
                        foreach (JProperty dependency in dps.SelectToken("$.dependencies"))
                        {
                            await InstallNPMPackage(HostFolder, dependency.Name, dependency.Value.ToString());
                        }

                        context.Response.StatusCode = 200;
                        return;
                    }

                    if (context.Request.Path == "/hello-world")
                    {
                        await context.Response.WriteAsync(@"<html><head><script src=""node_modules/requirejs/require.js""></script></head><body><script type=""text/javascript"">require.config({paths:{'earthml-temply-headless':'node_modules/earthml-temply-headless/artifacts/src'}}); require(['earthml-temply-headless/remotepage/remotepage'],(RemotePageModule)=>{console.log(RemotePageModule);let rp = new RemotePageModule.RemotePage(); rp.helloWorld(); })</script></body></html>");
                        return;
                    }

                    if (context.Request.Path == "/")
                    {
                        try
                        {
                            string result = await engine.CompileRenderAsync("GenericRemoteHost.cshtml", new { Name = "John Doe" });

                            await context.Response.WriteAsync(result);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                        }
                        return;
                    }


                    await next();

                    Console.WriteLine($"{context.Request.Path} {context.Response.StatusCode}");
                });
                foreach (var volumne in Volumes)
                {
                    appbuilder.Map(volumne.Split(':').Last(), (b) =>
                    {
                        b.Use(async(ctx, next) =>
                        {
                            await next();

                            Console.WriteLine($"{ctx.Request.Path} {ctx.Response.StatusCode}");
                        });
                        b.UseStaticFiles(new StaticFileOptions {
                            FileProvider = new PhysicalFileProvider(string.Join(":", volumne.Split(':').Reverse().Skip(1).Reverse()))
                        });
                    });
                }

                //appbuilder.Map("/appinsight", (b) =>
                //{
                //    b.UseStaticFiles(new StaticFileOptions { FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider(@"C:\dev\EarthML\EarthML.TemplyHeadless\samples\ApplicationInsightsGraphGenerator\wwwroot") });

                //});

                //appbuilder.Map("/AscendRegistration", (b) =>
                //{
                //    b.UseStaticFiles(new StaticFileOptions { FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider(@"C:\dev\Ascend\AscendRecording\AscendRecording\www\libs\AscendRegistration") });

                //});

                //appbuilder.Map("/node_modules/earthml-temply-headless/artifacts/src", (b) =>
                //{
                //    b.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider("C:/dev/EarthML/EarthML.TemplyHeadless/src/EarthML.TemplyHeadless/artifacts/src") });
                //});

                appbuilder.UseStaticFiles(new StaticFileOptions {
                    FileProvider = new PhysicalFileProvider(HostFolder)
                });
            })
                            .Build();


            await host.StartAsync();;

            if (HelloWorld)
            {
                Url = host.ServerFeatures.Get <IServerAddressesFeature>().Addresses
                      .Select(a => a.Replace("://+", "://localhost").Replace("[::]", "127.0.0.1")).FirstOrDefault() + "/hello-world";
            }

            if (!string.IsNullOrEmpty(RemotePageLocation))
            {
                Url = host.ServerFeatures.Get <IServerAddressesFeature>().Addresses
                      .Select(a => a.Replace("://+", "://localhost").Replace("[::]", "127.0.0.1")).FirstOrDefault() + $"?remote-main={RemotePageMain}&remote-location={WebUtility.UrlEncode(RemotePageLocation)}";
            }


            {
                var services = new ServiceCollection();
                services.AddNodeServices(a =>
                {
                    // a.ProjectPath = Directory.GetCurrentDirectory();
                    // Set any properties that you want on 'options' here
                });

                var serviceProvider = services.BuildServiceProvider();
                var options         = new NodeServicesOptions(serviceProvider)
                {
                    ProjectPath = HostFolder,
                    InvocationTimeoutMilliseconds = 60000 * 10,
                    WatchFileExtensions           = new string[] { }
                };
                var _nodeServices = NodeServicesFactory.CreateNodeServices(options);

                try
                {
                    var data = await RequireJS.RunAsync <object, JToken>(_nodeServices, HostFolder, "earthml-temply-headless/Headless/headless", new
                    {
                        url          = Url,
                        headlessHost = host.ServerFeatures.Get <IServerAddressesFeature>().Addresses
                                       .Select(a => a.Replace("://+", "://localhost").Replace("[::]", "127.0.0.1")).FirstOrDefault(),
                        headless = true,
                        size     = new
                        {
                            width  = Width,
                            height = Height
                        },
                        data         = args,
                        inputPrefix  = InputFolder,
                        outputPrefix = OutputFolder
                    });


                    Console.WriteLine(data.ToString());
                }catch (Exception ex)
                {
                    Console.WriteLine(ex);

                    await Task.Delay(60000);
                }
            }
            if (host != null)
            {
                await host.StopAsync();
            }
            return(0);
        }
        /// <summary>
        /// Enables Webpack dev middleware support. This hosts an instance of the Webpack compiler in memory
        /// in your application so that you can always serve up-to-date Webpack-built resources without having
        /// to run the compiler manually. Since the Webpack compiler instance is retained in memory, incremental
        /// compilation is vastly faster that re-running the compiler from scratch.
        ///
        /// Incoming requests that match Webpack-built files will be handled by returning the Webpack compiler
        /// output directly, regardless of files on disk. If compilation is in progress when the request arrives,
        /// the response will pause until updated compiler output is ready.
        /// </summary>
        /// <param name="appBuilder">The <see cref="IApplicationBuilder"/>.</param>
        /// <param name="options">Options for configuring the Webpack compiler instance.</param>
        public static void UseWebpackDevMiddleware(
            this IApplicationBuilder appBuilder,
            WebpackDevMiddlewareOptions options = null)
        {
            // Prepare options
            if (options == null)
            {
                options = new WebpackDevMiddlewareOptions();
            }

            // Validate options
            if (options.ReactHotModuleReplacement && !options.HotModuleReplacement)
            {
                throw new ArgumentException(
                          "To enable ReactHotModuleReplacement, you must also enable HotModuleReplacement.");
            }

            // Unlike other consumers of NodeServices, WebpackDevMiddleware dosen't share Node instances, nor does it
            // use your DI configuration. It's important for WebpackDevMiddleware to have its own private Node instance
            // because it must *not* restart when files change (if it did, you'd lose all the benefits of Webpack
            // middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't
            // as fast as some theoretical future alternative.
            var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices);

            nodeServicesOptions.WatchFileExtensions = new string[] { }; // Don't watch anything
            if (!string.IsNullOrEmpty(options.ProjectPath))
            {
                nodeServicesOptions.ProjectPath = options.ProjectPath;
            }

            if (options.EnvironmentVariables != null)
            {
                foreach (var kvp in options.EnvironmentVariables)
                {
                    nodeServicesOptions.EnvironmentVariables[kvp.Key] = kvp.Value;
                }
            }

            var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServicesOptions);

            // Get a filename matching the middleware Node script
            var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
                                                     "/Content/Node/webpack-dev-middleware.js");
            var nodeScript = new StringAsTempFile(script, nodeServicesOptions.ApplicationStoppingToken); // Will be cleaned up on process exit

            // Ideally, this would be relative to the application's PathBase (so it could work in virtual directories)
            // but it's not clear that such information exists during application startup, as opposed to within the context
            // of a request.
            var hmrEndpoint = !string.IsNullOrEmpty(options.HotModuleReplacementEndpoint)
                ? options.HotModuleReplacementEndpoint
                : "/__webpack_hmr"; // Matches webpack's built-in default

            // Tell Node to start the server hosting webpack-dev-middleware
            var devServerOptions = new
            {
                webpackConfigPath = Path.Combine(nodeServicesOptions.ProjectPath, options.ConfigFile ?? DefaultConfigFile),
                suppliedOptions   = options,
                understandsMultiplePublicPaths  = true,
                hotModuleReplacementEndpointUrl = hmrEndpoint
            };
            var devServerInfo =
                nodeServices.InvokeExportAsync <WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer",
                                                                      JsonConvert.SerializeObject(devServerOptions, jsonSerializerSettings)).Result;

            // If we're talking to an older version of aspnet-webpack, it will return only a single PublicPath,
            // not an array of PublicPaths. Handle that scenario.
            if (devServerInfo.PublicPaths == null)
            {
                devServerInfo.PublicPaths = new[] { devServerInfo.PublicPath };
            }

            // Proxy the corresponding requests through ASP.NET and into the Node listener
            // Anything under /<publicpath> (e.g., /dist) is proxied as a normal HTTP request with a typical timeout (100s is the default from HttpClient),
            // plus /__webpack_hmr is proxied with infinite timeout, because it's an EventSource (long-lived request).
            foreach (var publicPath in devServerInfo.PublicPaths)
            {
                appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath + hmrEndpoint, devServerInfo.Port, Timeout.InfiniteTimeSpan);
                appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath, devServerInfo.Port, TimeSpan.FromSeconds(100));
            }
        }
        /// <summary>
        /// Enables Parcel dev middleware support. This hosts an instance of Parcel in memory
        /// in your application so that you can always serve up-to-date Parcel-built resources without having
        /// to run it manually. Since Parcel is retained in memory, incremental
        /// compilation is vastly faster that re-running it from scratch.
        ///
        /// Incoming requests that match Parcel-built files will be handled by returning the Parcel
        /// output directly, regardless of files on disk. If compilation is in progress when the request arrives,
        /// the response will pause until updated compiler output is ready.
        /// </summary>
        /// <param name="appBuilder">The <see cref="IApplicationBuilder"/>.</param>
        /// <param name="options">Options for configuring Parcel.</param>
        public static void UseParcelDevMiddleware(
            this IApplicationBuilder appBuilder,
            ParcelBundlerOptions options = null)
        {
            // Prepare options
            if (options == null)
            {
                options = new ParcelBundlerOptions();
            }

            // Unlike other consumers of NodeServices, ParcelDevMiddleware dosen't share Node instances, nor does it
            // use your DI configuration. It's important for ParcelDevMiddleware to have its own private Node instance
            // because it must *not* restart when files change (if it did, you'd lose all the benefits of Parcel
            // middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't
            // as fast as some theoretical future alternative.
            var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices);

            nodeServicesOptions.WatchFileExtensions = new string[] { }; // Don't watch anything
            if (!string.IsNullOrEmpty(options.ProjectPath))
            {
                nodeServicesOptions.ProjectPath = options.ProjectPath;
            }

            if (options.EnvironmentVariables != null)
            {
                foreach (var kvp in options.EnvironmentVariables)
                {
                    nodeServicesOptions.EnvironmentVariables[kvp.Key] = kvp.Value;
                }
            }

            var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServicesOptions);

            // Get a filename matching the middleware Node script
            //Actual resource name: RudiBech.AspNetCore.SpaServices.Parcel.parcel-dev-middleware.js
            var script = EmbeddedResourceReader.Read(typeof(ParcelDevMiddelware), "/parcel-dev-middleware.js");

            // Will be cleaned up on process exit
            var nodeScript = new StringAsTempFile(script, nodeServicesOptions.ApplicationStoppingToken);

            // Tell Node to start the server hosting webpack-dev-middleware
            var parcelOptions = new
            {
                watch          = options.Watch,
                hmrPort        = options.Port,
                outDir         = options.OutDir,
                outFile        = options.OutFile,
                publicUrl      = options.PublicUrl,
                cache          = options.Cache,
                cacheDir       = options.CacheDir,
                minify         = options.Minify,
                target         = options.Target,
                logLevel       = (int)options.LogLevel,
                sourceMaps     = options.SourceMaps,
                detailedReport = options.DetailedReport,
                entryPoint     = options.EntryPoint
            };

            var devServerInfo =
                nodeServices.InvokeExportAsync <ParcelDevServerInfo>(nodeScript.FileName, "createParcelDevServer",
                                                                     JsonConvert.SerializeObject(parcelOptions, jsonSerializerSettings)).Result;

            // Proxy the corresponding requests through ASP.NET and into the Node listener
            // Anything under /<publicpath> (e.g., /dist) is proxied as a normal HTTP request with a typical timeout (100s is the default from HttpClient)
            foreach (var publicPath in devServerInfo.PublicPaths)
            {
                appBuilder.UseProxyToLocalParcelDevMiddleware(publicPath, devServerInfo.Port, TimeSpan.FromSeconds(100));
            }
        }
Example #21
0
 public HandlerFactory() : this(AssemblyBuilder.Default.Value,
                                NodeServicesFactory.CreateNodeServices(DefaultNodeServicesOptions()))
 {
 }
Example #22
0
 public HandlerFactory() : this(
         new DefaultAssemblyBuilder(new DefaultAssemblyLoadContextProvider(),
                                    new IMetadataReferenceResolver[] { new DefaultMetadataReferenceResolver() }),
         NodeServicesFactory.CreateNodeServices(DefaultNodeServicesOptions()))
 {
 }