15

How can I access the node_modules folder which is not included in the visual studio solution file from the wwwroot where my index.html is put. That index.html file need to reference the npm installed packages like angular.js.

But how?

I do not want to copy the whole node_modules folder into wwwroot. Those are not the files to live there...

I do not want to include the node_modules folder to the solution because that will slow down everything and hang up...

It seems Frontend development belongs not in VS...

Elisabeth
  • 20,496
  • 52
  • 200
  • 321

2 Answers2

15

There are at least two sane choices:

  • Serve other folders by using app.UseStaticFiles. The original solution is from Ode to Code. I use it for development, because Visual Studio doesn't seem to respect local .npmrc file set up with prefix = wwwroot/node_modules. Ideally, node_modules should be bundled for production. There is npm rollup plugin that can automatically bundle scripts using import feature (ES2015).

  • Serve node_modules from CDN (e.g. unpkg.com). This is fairly simple, the only downside is CDN's response time, especially if you've disabled browser caching for development purposes.

Here is the code to serve folders in ASP.NET Core. You only need to change the Startup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...some other stuff

    if (env.IsDevelopment())
    {
        ServeFromDirectory(app, env, "node_modules");
    }
}

public void ServeFromDirectory(IApplicationBuilder app, IHostingEnvironment env, string path)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.ContentRootPath, path)
        ),
        RequestPath = "/" + path
    });
}
rgripper
  • 1,066
  • 15
  • 23
  • 1
    This solution is too short-sighted: There's no way to publish any static files / resources outside from `wwwroot`! So how do you deploy `node_modules`? – Marcel Mar 28 '18 at 11:39
  • @Marcel My answer was a *working way* to serve files outside `wwwroot`. Generally noone publishes `node_modules` anymore - everyone uses bundlers. – rgripper Apr 02 '18 at 12:24
  • 1
    "Serve node_modules from CDN" - **this is really bad advice**. It's basically creating a timebomb that will make your website stop working as soon as the CDN company shuts down their domain-name in X-many years - and you're opening yourself up to vulnerabilities if the domain-name gets taken over and the scripts replaced with malware (e.g. Bitcoin mining scripts). Since 2020 there aren't any performance benefits to using shared CDNs anyway due to browsers implementing per-site cache isolation. – Dai Mar 08 '21 at 07:19
13

You are not supposed to access files from outside of wwwroot. The wwwroot folder is the public folder that's accessible from outside, when you host it.

Everything over it, is off-limits.

The typical publishing process is, that you have a gulp or grunt task that runs when your ASP.NET webproject is compiled or published, it would run the tasks there and copy over the necessary files inside wwwroot folder, i.e. wwwroot/libs or wwwdata/js.

Of course you can also manually copy the files over, but that's rather bad especially when you update many dependencies it's hard to keep track manually.

While it's not displayed in the solution (just indirectly, in the Dependencies/npm section), you can still make it visible by hitting the "Show all files" button on top of the Solution Explorer and copy over the files you need.

But it's best to set up a gulp task for it, but that's out of the scope of this question.

Tseng
  • 61,549
  • 15
  • 193
  • 205
  • So you advise setup a gulp task for all .js files in the node_modules that need to be copied over to /wwwroot/libs/ and then reference it from /wwwroot/index.html? – Elisabeth Feb 20 '16 at 19:32
  • @Elisabeth: Yes, that's the intended workflow. Just copy over the files you actually need. – Tseng Feb 20 '16 at 19:59
  • @Tseng Tried it but if there's a lot of files being copied, Visual Studio freezes for a moment. Is there a planned task to fix that? It really bothers me as it seems that is not the proper way to copy it. – Randal Cunanan May 08 '16 at 06:16
  • You shouldn't copy **EVERY** file from node_modules to the wwwdata folder, only the `*.min.js` or `*-all.js` or `*.js` that your application really needs. The package usually also include the source files, for debugging purposes. – Tseng May 08 '16 at 10:57
  • 7
    Is there a more automated way of doing this, tracking which file and what path for each npm dependency is tedious. – Randal Cunanan May 11 '16 at 09:43
  • @RueLeonheart: You have to do it anyways when you include that file into your html/view/_Layout.cshtml. This is the point where you also set up an gulp/grunt task to copy it over. Before this moment, you are effectively not using this package despite the fact that you have a dependency on it. – Tseng May 11 '16 at 12:31
  • 2
    @Tseng Not if I use SystemJS. Right now, I am stuck to using jspm instead and a duplicate dependency for node so that VS typescript won't complain. – Randal Cunanan May 11 '16 at 12:59
  • 1
    It took me a while to get this right so I'll share my knowledge: You are supposed to take deliberate steps to copy files you need, combine them with files you don’t need, and copy them to a place where you are unable to use them. Then, because you are unable to use the files you need, you repeatedly copy the files from the place where you cannot use them to a place where you can use them. My own personal Eureka moment came when I realized I could install and configure a utility to do this work for me. –  Jan 10 '17 at 17:41
  • @Sam which utility did you install? – Nate Anderson Mar 22 '17 at 04:04
  • @Sam The suspense is pretty intense over here Sam. What was the tool? :) – Brian MacKay Oct 05 '17 at 20:37
  • @BrianMacKay haha laughing at my own post. I forgot about that. At the time I was using Webpack... have since started using static files. [See here](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files) –  Oct 05 '17 at 22:56
  • @Sam Thanks for the reply. :) Static files in dev only, I assume? You must still be using webpack or gulp or whatever when you deploy, right? Still getting my head around why this is even worth doing. – Brian MacKay Oct 05 '17 at 23:58
  • 2
    @BrianMacKay the goal is to download your js into node_modules and use it from there without extraneous copying. You can set up your prod machine just like your dev machine and, as part of your deploy or build, run npm update. Your prod server will point to node_modules and everything should work. rgrippers answer below shows how to do this –  Oct 06 '17 at 01:49
  • 1
    @Sam Thanks Sam. Can't tell you how much time I wasted on this today trying to follow best practices that don't actually exist. Such a dumb, non-productive issue... There should be clear guidance here. – Brian MacKay Oct 06 '17 at 02:35