如何在ASP.NET Core中使用npm
如何在ASP.NET Core中使用npm
我正在使用npm来管理我ASP.NET Core应用程序所需的jQuery、Bootstrap、Font Awesome等客户端库。我采用的方法是在项目中添加一个package.json文件,内容如下:\n{\n \"version\": \"1.0.0\",\n \"name\": \"myapp\",\n \"private\": true,\n \"devDependencies\": {\n },\n \"dependencies\": {\n \"bootstrap\": \"^3.3.6\",\n \"font-awesome\": \"^4.6.1\",\n \"jquery\": \"^2.2.3\"\n }\n}\n
\nnpm会将这些包恢复到与项目目录中的wwwroot同级的node_modules文件夹中:\n[图片链接](https://i.stack.imgur.com/5Xlw7.png)\n由于ASP.NET Core是从wwwroot文件夹中提供静态文件的,而node_modules不在其中,所以我必须做一些修改才能使其工作。首先,在我的Startup.cs文件中,在app.UseStaticFiles之前添加app.UseFileServer:\n
app.UseFileServer(new FileServerOptions() { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), @"node_modules")), RequestPath = new PathString("/node_modules"), EnableDirectoryBrowsing = true }); app.UseStaticFiles();
\n其次,在我的project.json文件中将node_modules包含在我的publishOptions中:\n\"publishOptions\": {\n \"include\": [\n \"web.config\",\n \"wwwroot\",\n \"Views\",\n \"node_modules\"\n ]\n},\n
\n这在我的开发环境中运行良好,并且在部署到Azure App Service实例时也可以正常工作,jquery、bootstrap和font-awesome静态文件都能正常提供。但是,我对这种实现方法不太确定。\n请问有什么正确的方法来做这个呢?\n这个解决方案是在收集了很多信息并尝试了一些不起作用的方法之后得出的,而且从wwwroot之外提供这些文件似乎有点奇怪。\n非常感谢您的建议。
文章标题:如何在ASP.NET Core中使用npm
在ASP.NET Core中使用npm需要一些设置工作。如果只是想下载一些库,可以使用Visual Studio 15.8中发布的Library Manager代替。
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"
}
}
这样,npm会将Bootstrap、JQuery和其他在新的ASP.NET Core项目中使用的库下载到一个名为node_modules的文件夹中。接下来,需要将这些文件复制到合适的位置。为此,可以使用通过npm下载的gulp。
然后,在项目的根目录下添加一个名为gulpfile.js的新文件,内容如下:
////* 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")); });
这个文件包含了一个JavaScript代码,该代码在项目构建和清理时被执行。它将所有必要的文件复制到lib2目录(而不是lib,可以很容易地更改)。我使用了与新项目中相同的结构,但是很容易将文件更改为不同的位置。如果移动了文件,请确保还更新了_Layout.cshtml。注意,项目清理时lib2目录中的所有文件都将被删除。
右键单击gulpfile.js,选择“Task Runner Explorer”,可以在其中手动运行gulp以复制或清理文件。
Gulp还可以用于其他任务,如压缩JavaScript和CSS文件。
Library Manager(简单)
右键单击项目,选择“Manage client side-libraries”。现在打开了libman.json文件。在这个文件中,可以指定要使用的库和文件以及它们在本地的存储位置。非常简单!下面的文件复制了创建新的ASP.NET Core 2.1项目时使用的默认库:
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "jquery.3.1",
"files": [ "jquery.js", "jquery.min.map", "jquery.min.js" ],
"destination": "wwwroot/lib/jquery/dist/"
},
{
"library": "jquery-validate.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.2.10",
"files": [ "jquery.validate.unobtrusive.js", "jquery.validate.unobtrusive.min.js" ],
"destination": "wwwroot/lib/jquery-validation-unobtrusive/"
},
{
"library": "twitter-bootstrap.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.5.0",
"files": [ "list.js", "list.min.js" ],
"destination": "wwwroot/lib/listjs"
}
]
}
如果移动了文件,请确保还更新了_Layout.cshtml。
为了避免gulp错误,我不得不将文件gulpfile.js中默认任务的第一行更改为gulp.task('default', function (done) {
,然后在该函数的最后一行添加以下内容:done();
。否则,会出现错误消息The following tasks did not complete: Did you forget to signal async completion?
。
在使用ASP.NET Core时如何使用npm的问题出现的原因是:有人想要在ASP.NET Core项目中管理客户端库,但不知道如何正确使用npm来完成这个任务。为了解决这个问题,下面列出了一些使用npm与ASP.NET Core的建议和解决方案。
解决方法如下:
1. 将服务器端(ASP.NET Core)和客户端(如Angular 2、Ember、React)项目分别放在不同的文件夹中,这样可以减少ASP.NET项目中的冗余内容。
2. 在解决方案级别上恢复npm模块,这样可以将单元测试和集成测试放在不同的文件夹中。
3. 使用StaticFiles来提供静态文件,不一定需要使用FileServer。
4. 使用Webpack将客户端代码打包成一个或多个块(bundles)。
5. 如果使用Webpack这样的模块打包工具,可能不需要使用Gulp/Grunt。
6. 使用ES2015+ JavaScript编写构建自动化脚本,可以跨平台运行,并且对于各种web开发人员更易于理解。
7. 将wwwroot重命名为public,以避免在Azure Web应用程序中的文件夹结构混乱。
8. 只发布编译后的输出到Azure Web应用程序,不要将node_modules推送到Web托管服务器。
9. 不要将node_modules推送到Web托管服务器,可以参考tools/deploy.js的示例。
这些建议和解决方案可以帮助开发人员更好地使用npm与ASP.NET Core,并提高项目的开发效率和可维护性。
以上是关于如何使用npm与ASP.NET Core的一些建议和解决方案,希望对你有所帮助。
如何在ASP.NET Core中使用npm
在发布整个node_modules文件夹时,您部署的文件比实际在生产中需要的文件要多得多。
相反,使用任务运行器作为构建过程的一部分来打包您需要的文件,并将其部署到您的wwwroot文件夹中。这还将允许您同时合并和压缩资产,而不必单独为每个库提供服务。
然后,您还可以完全删除FileServer配置,而依赖UseStaticFiles。
目前,gulp是VS任务运行器的首选。在项目的根目录中添加一个gulpfile.js,并配置它在发布时处理您的静态文件。
例如,您可以将以下脚本部分添加到您的project.json中:
"scripts": {
"prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
}
这将与以下gulpfile一起工作(使用yo脚手架时的默认设置):
///"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"]);
我有点困惑,不知道这是问题的答案。这几乎与Microsoft在此处配置Gulp的方式完全相同(learn.microsoft.com/en-us/aspnet/core/client-side/using-gulp)。然而,就我所知,这不会从我的node_modules目录中获取内容并将其添加到'lib'中或使其在我的文件中可用...我在这方面非常新,对Web开发的这个看似非常复杂的新世界感到困惑...
确实很复杂。我准备完全放弃前端,只专注于API。
这是一般的正确方法,但是答案省略了一个关键步骤:将文件从node_modules文件夹复制到wwwroot文件夹作为Gulp任务的一部分。从var nodeRoot = './node_modules/';开始,并添加一个任务将所需的子文件夹从nodeRoot复制到webroot的适当子文件夹中。现在没有时间详细说明,但如果有兴趣,我可以稍后添加细节。
为什么没有人提出一个明显的问题:“为什么我们必须问这个问题!”为什么我们故意在无法使用的位置安装文件?然后,因为我们的文件不可访问,我们安装和配置一个复杂的实用程序将它们复制到可以使用的位置。这真的很荒谬。
因为通常它们是开发依赖关系,而不是生产依赖关系。我同意,为了设置一个应用程序而必须经过这个过程确实是一种负担,但我认为Mads Kristensen可能会有一些方法来简化简单的情况,对于那个任务是什么样子感兴趣。具体而言,如果我们有多个node_modules;我们必须明确/单独编写每个任务吗?我想我们可以使用数组和forEach,但是否有更好的方法?(“从nodeRoot复制所需的子文件夹到适当的子文件夹”)
这根本不是问题的答案。这里唯一正确的是Gulp可以用于node_modules发布任务。
因为这里的工具链很烂。使用npm只是使用npm,就像您对于任何东西一样。没有任何特定于ASP.NET Core的东西。所有内容都放在node_modules中,因为这是npm的工作方式。Gulp任务是必要的,以将事物移动到正确的位置,即您实际需要它们的地方。我认为问题在于Microsoft提供了与Bower的完美集成,但现在Bower已经死了(或至少快要死了),而Microsoft没有提供任何替代工具。
目前它仅处于预览阶段,但Microsoft正在从Bower转向一个轻量级的替代工具,称为LibraryManager。它不适用于所有用例(即SPA应用程序),但对于简单的“将jQuery放在一个文件夹中”应该是一个不错的选择。
我理解的是,node_modules中的NPM包还包括包的“源代码”以及它的依赖关系,对吗?除非作为开发人员,我们还希望调试和逐步进行包的JavaScript代码,否则我们真正关心的只是“dist”文件夹中的文件对吗?因此,我们需要一个工具,只需从dist复制文件到我们希望在项目中静态提供文件的位置。提供node_modules似乎是错误的。我对Web开发还不太了解,所以我的理解可能是错误的,我很乐意接受指导。
嗨,Doug - 你提到还有一些额外的代码,你介意看一下这个,看看你能否提供帮助?stackoverflow.com/questions/51050816
project.json在ASP.NET Core项目中不再存在,但是这些构建任务的XML等效项是什么?能否修改此答案以包含此示例?
不,我说。Libman很糟糕,浪费时间!cdnjs提供者提供的库选择不足。有一个bootstrap和一个twitter-bootstrap。后者是版本4,而前者是版本3。Libman的自动建议功能在键入“bootstrap”时没有列出这两个库!我花了将近一个小时才找到版本4,而且它是无用的,因为它不包括官方发布的sass文件。