TrilonIO / aspnetcore-angular-universal

ASP.NET Core & Angular Universal advanced starter - PWA w/ server-side rendering for SEO, Bootstrap, i18n internationalization, TypeScript, unit testing, WebAPI REST setup, SignalR, Swagger docs, and more! By @TrilonIO
https://www.trilon.io
MIT License
1.46k stars 435 forks source link

WebAPI using NodeServices to run JavaScript #722

Open alexbenitez opened 5 years ago

alexbenitez commented 5 years ago

I'm using this starter and I have question regarding NodeServices and the webpack configuration.

I have a webapi method that creates and returns a PDF. I'm using NodeServices to run a js script that uses jsreport to convert from HTML to PDF. Everything works in my development machine. However, when I publish and deploy to IIS I'm getting an exception because the js script ran by NodeService can't locate a module it needs (var jsreport = require('jsreport-core')();.

This is the Web API

    public async Task<IActionResult> GetPdf([FromServices] INodeServices nodeServices,string id) 
        { 
                var htmlContent = await lfrServices.GetHtml(id);
                var result = await nodeServices.InvokeAsync<byte[]>("./wwwroot/js/pdf", htmlContent); 
                return File(result,"application/pdf","file.pdf");
          } 

This is the package.json (used by the script ran by NodeServices)

    "jsreport-core": "^2.4.3",
    "jsreport-jsrender": "^2.0.0",
    "jsreport-phantom-pdf": "^2.2.0",

This is the script NodeServices is executing (which fails with module not found trying to get the jsreport-core module)

module.exports = function (callback, html) { 
    var jsreport = require('jsreport-core')(); 

    jsreport.init().then(function () { 
        return jsreport.render({ 
            template: { 
                content: html, 
                engine: 'jsrender', 
                recipe: 'phantom-pdf' 
            } 
        }).then(function (resp) { 
            callback(null, resp.content.toJSON().data); 
        }); 
    }).catch(function (e) { 
        callback(e, null); 
    }) 
}; 

As I mention, if I debug/F5 everything works fine. However it doesn't when targeting Prod and publishing to IIS.

What should I do to embed this javascript file with webpack (so it is part of the "dist" files) an ensure that it successfully works when it requires its npm dependencies it needs (in this case the jsrepor-core module)?

alexbenitez commented 5 years ago

OK... I guess I answered part of my own question... I copied the node_modules to the site and started to work. Not sure if this an adequate setup but is there anyway to configure the NodeServices so "require("jsreport-core") resolves modules from the same Angular location in a Production environment? (dist folder)

Chris3773 commented 4 years ago

You can use webpack to build your "./wwwroot/js/pdf" file as that will bundle "jsreport-core" with your script. Then you can run that script on NodeServices without needing to copy over the node_modules folder.

You can add it to entry of your webpack config and it should build the "./wwwroot/js/pdf" file from source.

entry: { 'pdf': './src/pdf.ts' }