如何在ASP.NET Core中使用npm

Car*_*roa 104 c# asp.net-mvc npm gulp asp.net-core

我正在使用npm来管理我的ASP.NET核心应用程序所需的jQuery,Bootstrap,Font Awesome和类似的客户端库.

对我有用的方法首先将package.json文件添加到项目中,如下所示:

{
    "version": "1.0.0",
    "name": "myapp",
    "private": true,
    "devDependencies": {
  },
  "dependencies": {
    "bootstrap": "^3.3.6",
    "font-awesome": "^4.6.1",
    "jquery": "^2.2.3"
  }
}
Run Code Online (Sandbox Code Playgroud)

npm将这些包恢复到node_modules文件夹中,该文件夹与项目目录中的wwwroot处于同一级别:

在此输入图像描述

由于ASP.NET Core提供了来自wwwroot文件夹的静态文件,并且node_modules不在那里,我不得不进行一些更改才能完成这项工作,第一个:在app.UseStaticFiles之前添加app.UseFileServer. cs文件:

app.UseFileServer(new FileServerOptions()
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), @"node_modules")), 
    RequestPath = new PathString("/node_modules"),
    EnableDirectoryBrowsing = true
});

app.UseStaticFiles();
Run Code Online (Sandbox Code Playgroud)

第二个,包括project.json文件中的publishOptions中的node_modules:

"publishOptions": {
  "include": [
    "web.config",
    "wwwroot",
    "Views",
    "node_modules"
  ]
},
Run Code Online (Sandbox Code Playgroud)

这适用于我的开发环境,当我将它部署到我的Azure App Service实例时,它也可以工作,jquery,bootstrap和font-awesome静态文件得到很好的服务,但我不确定这个实现.

这样做的正确方法是什么?

这个解决方案是在从多个来源收集大量信息并尝试一些不起作用之后得出的,并且从wwwroot外部提供这些文件似乎有点奇怪.

任何建议将不胜感激.

Kon*_*kus 41

在此输入图像描述

  • 使用npm管理客户端库是一个不错的选择(而不是鲍尔或的NuGet),你在想在正确的方向:)
  • 将服务器端(ASP.NET Core)和客户端(例如Angular 2,Ember,React)项目拆分为单独的文件夹(否则您的ASP.NET项目可能会有很多噪音 - 客户端代码的单元测试,node_modules文件夹,建造人工制品等).和你一起在同一个团队工作的前端开发人员会感谢你:)
  • 在解决方案级别恢复npm模块(类似于如何通过NuGet恢复包 - 而不是在项目的文件夹中),这样您就可以在单独的文件夹中进行单元和集成测试(而不是在您的内部进行客户端JavaScript测试) ASP.NET核心项目).
  • 使用可能不需要FileServer,StaticFiles应该足以提供静态文件(.js,图像等)
  • 使用Webpack将客户端代码捆绑到一个或多个块(捆绑包)中
  • 如果您使用的是模块捆绑器(如Webpack),则可能不需要Gulp/Grunt
  • 使用ES2015 + JavaScript(而不是Bash或PowerShell)编写构建自动化脚本,它们将跨平台工作,并且更容易被各种Web开发人员访问(现在每个人都会说JavaScript)
  • 重命名wwwrootpublic,否则Azure Web Apps中的文件夹结构将会令人困惑(D:\Home\site\wwwroot\wwwrootvs D:\Home\site\wwwroot\public)
  • 仅将已编译的输出发布到Azure Web Apps(您永远不应该推node_modules送到Web托管服务器).见tools/deploy.js,例如,

访问GitHub上的ASP.NET核心入门套件(免责声明:我是作者)

  • 今年早些时候,我成功为一个主要的英国品牌建立了一个巨大的公共Angular应用程序,但我甚至无法理解这个答案的大部分内容.我甚至无法开始学习它到处都是.字面上有职业危机. (5认同)
  • 很好的答案,感谢您为社区提供入门套件的工作! (2认同)
  • 不幸的是,Visual Studio(愚蠢的恕我直言)仅根据其名称特殊对待“wwwroot”目录,在解决方案资源管理器中给它一个特殊的“web root”图标,并将其内容默认标记为“None”而不是“Content” 。如果目的是将静态提供的文件放在那里,并且您使用的是 Visual Studio,则可能应该将名称保留为“wwwroot”。我同意这是一个坏名字。 (2认同)

Soc*_*ock 39

通过发布整个node_modules文件夹,您将部署的文件远远多于生产中实际需要的文件.

而是使用任务运行器作为构建过程的一部分来打包所需的文件,并将它们部署到您的wwwroot文件夹中.这也可以让您同时连接和缩小资产,而不必单独为每个库提供服务.

然后,您还可以完全删除FileServer配置并依赖它UseStaticFiles.

目前,gulp是首选的VS任务选手.添加gulpfile.js到项目的根目录,并将其配置为在发布时处理静态文件.

例如,您可以将以下scripts部分添加到您的project.json:

 "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  },
Run Code Online (Sandbox Code Playgroud)

哪个适用于以下gulpfile(脚手架时的默认值yo):

/// <binding Clean='clean'/>
"use strict";

var gulp = require("gulp"),
    rimraf = require("rimraf"),
    concat = require("gulp-concat"),
    cssmin = require("gulp-cssmin"),
    uglify = require("gulp-uglify");

var webroot = "./wwwroot/";

var paths = {
    js: webroot + "js/**/*.js",
    minJs: webroot + "js/**/*.min.js",
    css: webroot + "css/**/*.css",
    minCss: webroot + "css/**/*.min.css",
    concatJsDest: webroot + "js/site.min.js",
    concatCssDest: webroot + "css/site.min.css"
};

gulp.task("clean:js", function (cb) {
    rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {
    rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css"]);

gulp.task("min:js", function () {
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

gulp.task("min:css", function () {
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(concat(paths.concatCssDest))
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

gulp.task("min", ["min:js", "min:css"]);
Run Code Online (Sandbox Code Playgroud)

  • 关于这个问题的答案,我有点困惑.这几乎就是微软在这里配置Gulp的原因(https://docs.microsoft.com/en-us/aspnet/core/client-side/using-gulp).但是据我所知,这不会从我的node_modules目录中获取内容并将其添加到'lib'或使其可用于我的任何文件中......我对此非常新,所以看起来令人难以置信的困惑复杂的Web开发新世界...... (32认同)
  • 为什么没有人提出明显的问题:"为什么我们要问这个问题!" 为什么我们故意在无法使用的位置安装文件?然后,因为我们的文件不可访问,所以我们安装并配置了一个复杂的实用程序,将它们复制到可以使用它们的位置.它真的很荒谬. (27认同)
  • 复杂没事.我已经准备完全放弃前端,只是在API上工作. (26认同)
  • 这是一般的正确方法,但答案遗漏了一个关键步骤:将文件从node_modules文件夹复制到wwwroot文件夹作为Gulp任务.从var nodeRoot ='./ node_modules /'开始; 并添加一个任务,将所需的子文件夹从nodeRoot复制到webroot的相应子文件夹中.现在没时间详细说明,但如果有兴趣,我可以稍后再添加细节. (12认同)
  • 因为这里的工具基本上就是垃圾.使用npm只是使用npm,就像你对*任何*一样.ASP.NET Core没有特定的功能.一切都进入`node_modules`,因为那就是npm所做的.gulp任务是将事物移动到正确的位置,即实际需要它们的必要条件.我认为问题在于微软提供了与Bower如此完美的整合,但现在Bower已经死了(或者至少死了),微软还没有提供任何替代工具. (7认同)
  • @Sam因为,通常,它们是开发依赖项,而不是生成依赖项.我同意,为了获得应用程序设置而必须经历舞蹈是一种负担,但我认为Mads Kristensen可能有一些事情可以帮助简化简单案例 (4认同)
  • 这根本不是问题的答案.唯一正确的是Gulp可用于节点模块发布任务. (2认同)
  • 目前仅在预览版中,但微软正在从Bower转向名为LibraryManager的轻量级替代品.它不适用于所有用例(即SPA应用程序),但对于简单的"在文件夹中删除jQuery",它应该是一个不错的选择.https://blogs.msdn.microsoft.com/webdev/2018/04/17/library-manager-client-side-content-manager-for-web-apps/ (2认同)
  • 据我了解,node_modules中的NPM软件包还包含该软件包的的“源代码”及其依赖关系,对吗?除非我们作为开发人员有要求也要调试和逐步执行软件包的javascript代码,否则我们真正感兴趣的只是'dist'文件夹中的文件对吗?因此,需要一种工具来处理从dist复制文件到我们希望在项目中静态提供文件的任何地方。服务node_modules似乎是错误的。我是webdev的新手,所以我的理解很可能是错误的,我很高兴接受这一方面的培训。 (2认同)
  • @Sock,不,我说。利布曼很糟糕而且浪费时间!即使是最常用的库,cdnjs 提供商也没有足够的选择。有一个 bootstrap 和一个 twitter-bootstrap。后者是版本 4,而前者是版本 3。Libman 的自动建议功能不会通过键入“bootstrap”来列出这两个库!我花了将近一个小时才找到版本 4,但它没有用,因为它不包含官方发行版的 sass 文件。 (2认同)

Pio*_*ula 26

Bundler和Minifier安装到Visual Studio Extensions中

然后你创建一个bundleconfig.json并输入以下内容:

// Configure bundling and minification for the project.
// More info at https://go.microsoft.com/fwlink/?LinkId=808241
[
 {
    "outputFileName": "wwwroot/js/jquery.min.js",
    "inputFiles": [
      "node_modules/jquery/dist/jquery.js"
    ],
    // Optionally specify minification options
    "minify": {
      "enabled": true,
      "renameLocals": false
    },
    // Optionally generate .map file
    "sourceMap": false
  }
]
Run Code Online (Sandbox Code Playgroud)

因此,bundler和minifier(基于gulp)可以访问源文件(应该从Visual Studio中排除,也可以从GIT中排除)并将它们放入指定的wwwroot中

每次保存时只有副作用会运行(或者您可以设置或手动运行)

  • 在看到Bower死了之后我无法再切换到NPM而无法更新Bootstrap,这似乎是我最喜欢的方法.与这个已经在最新的MVC项目模板中的简单解决方案相比,Gulp或Webpack似乎有些过分.谢谢你的分享! (4认同)
  • 这里如何处理 css 中引用的图像?我遇到的问题是图像仍在 node_modules 文件夹中,其中 css 和 js 已移至 www. 知道如何解决这个问题吗? (2认同)
  • 这与 IDE 无关吗?如果您的团队中的一些人正在使用 VS Code,这将如何工作?这如何在 CD 构建管道中发挥作用? (2认同)

PEK*_*PEK 16

我给你两个答案.npm结合其他工具功能强大,但需要一些工作来设置.如果您只想下载某些库,则可能需要使用库管理器(在Visual Studio 15.8中发布).

NPM(高级)

首先在项目的根目录中添加package.json.添加以下内容:

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "gulp": "3.9.1",
    "del": "3.0.0"
  },
  "dependencies": {
    "jquery": "3.3.1",
    "jquery-validation": "1.17.0",
    "jquery-validation-unobtrusive": "3.2.10",
    "bootstrap": "3.3.7"
  }
}
Run Code Online (Sandbox Code Playgroud)

这将使NPM将新的asp.net核心项目中使用的Bootstrap,JQuery和其他库下载到名为node_modules的文件夹中.下一步是将文件复制到适当的位置.要做到这一点,我们将使用gulp,也是由NPM下载的.然后在名为gulpfile.js的项目的根目录中添加一个新文件.添加以下内容:

/// <binding AfterBuild='default' Clean='clean' />
/*
This file is the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkId=518007
*/

var gulp = require('gulp');
var del = require('del');

var nodeRoot = './node_modules/';
var targetPath = './wwwroot/lib/';

gulp.task('clean', function () {
    return del([targetPath + '/**/*']);
});

gulp.task('default', function () {
    gulp.src(nodeRoot + "bootstrap/dist/js/*").pipe(gulp.dest(targetPath + "/bootstrap/dist/js"));
    gulp.src(nodeRoot + "bootstrap/dist/css/*").pipe(gulp.dest(targetPath + "/bootstrap/dist/css"));
    gulp.src(nodeRoot + "bootstrap/dist/fonts/*").pipe(gulp.dest(targetPath + "/bootstrap/dist/fonts"));

    gulp.src(nodeRoot + "jquery/dist/jquery.js").pipe(gulp.dest(targetPath + "/jquery/dist"));
    gulp.src(nodeRoot + "jquery/dist/jquery.min.js").pipe(gulp.dest(targetPath + "/jquery/dist"));
    gulp.src(nodeRoot + "jquery/dist/jquery.min.map").pipe(gulp.dest(targetPath + "/jquery/dist"));

    gulp.src(nodeRoot + "jquery-validation/dist/*.js").pipe(gulp.dest(targetPath + "/jquery-validation/dist"));

    gulp.src(nodeRoot + "jquery-validation-unobtrusive/dist/*.js").pipe(gulp.dest(targetPath + "/jquery-validation-unobtrusive"));
});
Run Code Online (Sandbox Code Playgroud)

此文件包含在构建和清理项目时执行的JavaScript代码.它会将所有必要的文件复制到lib2(而不是lib - 你可以轻松地改变它).我使用了与新项目相同的结构,但很容易将文件更改为其他位置.如果移动文件,请确保还更新_Layout.cshtml.请注意,清除项目时将删除lib2目录中的所有文件.

如果右键单击gulpfile.js,则可以选择Task Runner Explorer.从这里,您可以手动运行gulp来复制或清理文件.

Gulp对于缩小JavaScript和CSS文件等其他任务也很有用:

https://docs.microsoft.com/en-us/aspnet/core/client-side/using-gulp?view=aspnetcore-2.1

图书馆经理(简单)

右键单击您的项目,然后选择Manage client side-libraries.文件libman.json现已打开.在此文件中,您可以指定要使用的库和文件以及应在本地存储的位置.真的很简单!以下文件复制创建新的ASP.NET Core 2.1项目时使用的默认库:

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "library": "jquery@3.3.1",
      "files": [ "jquery.js", "jquery.min.map", "jquery.min.js" ],
      "destination": "wwwroot/lib/jquery/dist/"
    },
    {
      "library": "jquery-validate@1.17.0",
      "files": [ "additional-methods.js", "additional-methods.min.js", "jquery.validate.js", "jquery.validate.min.js" ],
      "destination": "wwwroot/lib/jquery-validation/dist/"
    },
    {
      "library": "jquery-validation-unobtrusive@3.2.10",
      "files": [ "jquery.validate.unobtrusive.js", "jquery.validate.unobtrusive.min.js" ],
      "destination": "wwwroot/lib/jquery-validation-unobtrusive/"
    },
    {
      "library": "twitter-bootstrap@3.3.7",
      "files": [
        "css/bootstrap.css",
        "css/bootstrap.css.map",
        "css/bootstrap.min.css",
        "css/bootstrap.min.css.map",
        "css/bootstrap-theme.css",
        "css/bootstrap-theme.css.map",
        "css/bootstrap-theme.min.css",
        "css/bootstrap-theme.min.css.map",
        "fonts/glyphicons-halflings-regular.eot",
        "fonts/glyphicons-halflings-regular.svg",
        "fonts/glyphicons-halflings-regular.ttf",
        "fonts/glyphicons-halflings-regular.woff",
        "fonts/glyphicons-halflings-regular.woff2",
        "js/bootstrap.js",
        "js/bootstrap.min.js",
        "js/npm.js"
      ],
      "destination": "wwwroot/lib/bootstrap/dist"
    },
    {
      "library": "list.js@1.5.0",
      "files": [ "list.js", "list.min.js" ],
      "destination": "wwwroot/lib/listjs"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果移动文件,请确保还更新_Layout.cshtml.

  • 图书馆经理-从未听说过,但这正是我所需要的!这应该是正确的答案。 (2认同)

Dav*_*750 7

您也可以使用Gulp复制wwwroot所需的内容,而不是尝试提供节点模块文件夹.

https://docs.asp.net/en/latest/client-side/using-gulp.html

这也可能有所帮助

Visual Studio 2015 ASP.NET 5,Gulp任务不从node_modules复制文件

  • 我真的很喜欢第二个链接,似乎很熟悉.;) (4认同)

Dav*_*ine 5

这样做的正确方法是什么?

有很多"正确"的方法,你只需决定哪一个最适合你的需求.好像你误解了如何使用node_modules......

如果您熟悉NuGet,您应该将npm视为其客户端对应方.凡node_modules目录就像bin对目录的NuGet.我的想法是这个目录只是一个存储包的常用位置,在我看来,最好是dependency按照你所做的那样打开你需要的包package.json.然后使用任务运行器Gulp,例如将您需要的文件复制到所需wwwroot位置.

我在1月份写了一篇关于这篇文章的博客文章,详细介绍了npm,Gulp和其他一些今天仍然相关的细节.另外,有人提醒我注意我问的问题并最终在这里回答,这可能是有帮助的.

我创建了一个Gist,显示gulpfile.js作为一个例子.

在您Startup.cs使用静态文件仍然很重要:

app.UseStaticFiles();
Run Code Online (Sandbox Code Playgroud)

这将确保您的应用程序可以访问它所需的内容.

  • "我在1月份写了一篇关于此事的博客文章,其中详细介绍了npm,Gulp和其他一些今天仍然相关的细节." 事实上,从1月到6月你必须提到仍然是相关的正是我的问题,困扰学习任何这种飞行的东西.在没有浪费时间的情况下,我已经学到了很多东西.不是你的错大卫,你是非常有帮助的,但我不喜欢这个短暂的新世界. (3认同)

Mar*_*ski 5

更简单的方法是使用OdeToCode.UseNodeModules Nuget 包。我刚刚用 .Net Core 3.0 对其进行了测试。您需要做的就是将包添加到解决方案中,并在 Startup 类的 Configure 方法中引用它:

app.UseNodeModules();
Run Code Online (Sandbox Code Playgroud)

我是从Shawn Wildermuth的优秀的Building a Web App with ASP.NET Core、MVC、Entity Framework Core、Bootstrap 和 Angular Pluralsight 课程中了解到的。

  • 以及如何添加 npm 包? (2认同)