วิธีใช้ npm กับ ASP.NET Core


118

ฉันใช้ npm เพื่อจัดการ jQuery, Bootstrap, Font Awesome และไลบรารีไคลเอนต์ที่คล้ายกันที่ฉันต้องการสำหรับแอปพลิเคชัน ASP.NET Core ของฉัน

วิธีการที่ใช้ได้ผลสำหรับฉันเริ่มต้นด้วยการเพิ่มไฟล์ 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"
  }
}

npm คืนค่าแพ็กเกจเหล่านี้ลงในโฟลเดอร์ node_modules ซึ่งอยู่ในระดับเดียวกับ wwwroot ในไดเร็กทอรีโปรเจ็กต์:

ใส่คำอธิบายภาพที่นี่

เนื่องจาก ASP.NET Core ให้บริการไฟล์แบบคงที่จากโฟลเดอร์ wwwroot และไม่มี node_modules ฉันจึงต้องทำการเปลี่ยนแปลงสองสามอย่างเพื่อให้ทำงานนี้ได้อันแรกคือการเพิ่ม app.UseFileServer ก่อนแอป UseStaticFiles ใน Startup ของฉัน ไฟล์ cs:

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

app.UseStaticFiles();

และอันที่สองรวมถึง node_modules ใน PublishOptions ของฉันในไฟล์ project.json:

"publishOptions": {
  "include": [
    "web.config",
    "wwwroot",
    "Views",
    "node_modules"
  ]
},

สิ่งนี้ใช้งานได้ในสภาพแวดล้อมการพัฒนาของฉันและยังใช้งานได้เมื่อฉันปรับใช้กับอินสแตนซ์ Azure App Service ของฉัน jquery, bootstrap และไฟล์คงที่ที่น่ากลัวแบบอักษรจะได้รับการบริการที่ดี แต่ฉันไม่แน่ใจเกี่ยวกับการใช้งานนี้

แนวทางที่เหมาะสมในการทำเช่นนี้คืออะไร?

โซลูชันนี้เกิดขึ้นหลังจากรวบรวมข้อมูลจำนวนมากจากแหล่งข้อมูลหลายแหล่งและลองใช้บางส่วนที่ไม่ได้ผลและดูเหมือนว่าเป็นเรื่องแปลกที่ต้องให้บริการไฟล์เหล่านี้จาก wwwroot ภายนอก

คำแนะนำใด ๆ จะได้รับการชื่นชมอย่างมาก


อาจเป็นลิงค์ที่มีประโยชน์: blog.nbellocam.me/2016/03/14/asp-net-core-and-angular-2
adem caglin

ลิงค์นี้มีตัวอย่างการทำงานบนASP.NET Core w / npm : ievangelistblog.wordpress.com/2016/01/13/…
David Pine

2
สิ่งหนึ่งที่เกิดขึ้นกับฉันคือการใช้Bundler and Minifier- ระบุแหล่งที่มาคือภายนอก wwwroot และเมื่อคุณสร้างมันจะสร้าง JS ใน wwwroot นั่นคือวิธีที่เหมาะสม .. คุณไม่ควรให้บริการเนื้อหาจาก node_modules
Piotr Kula

ฉันจะไม่แนะนำให้ทุกคนให้บริการnode_modulesโฟลเดอร์แบบคงที่ ก) นั่นไม่ใช่วิธีการออกแบบระบบนิเวศ b) มีความเสี่ยงด้านความปลอดภัยหนึ่งในแพ็คเกจที่ติดตั้งของคุณอาจรั่วไหลข้อมูลที่ละเอียดอ่อน วิธีที่เหมาะสมคือการตั้งค่าไปป์ไลน์การสร้าง (grunt / gulp / node / webpack) ที่เผยแพร่ไฟล์ไปยังโฟลเดอร์srcหรือwhateverเฉพาะสำหรับการให้บริการไฟล์ฟ
รอนต์

คำตอบ:


45

โดยการเผยแพร่node_modulesโฟลเดอร์ทั้งหมดของคุณคุณกำลังปรับใช้ไฟล์จำนวนมากเกินกว่าที่คุณจะต้องใช้ในการผลิตจริง

ให้ใช้ Task Runner เป็นส่วนหนึ่งของกระบวนการสร้างของคุณเพื่อจัดแพ็คเกจไฟล์ที่คุณต้องการและปรับใช้กับwwwrootโฟลเดอร์ของคุณ นอกจากนี้ยังช่วยให้คุณสามารถเชื่อมต่อและลดขนาดเนื้อหาของคุณได้ในเวลาเดียวกันแทนที่จะต้องให้บริการแต่ละห้องสมุดแยกกัน

จากนั้นคุณสามารถลบการFileServerกำหนดค่าทั้งหมดและพึ่งพาUseStaticFilesแทนได้

ปัจจุบันอึกเป็นตัวเลือกงาน VS เพิ่ม a gulpfile.jsลงในรูทของโปรเจ็กต์ของคุณและกำหนดค่าให้ประมวลผลไฟล์สแตติกของคุณในการเผยแพร่

ตัวอย่างเช่นคุณสามารถเพิ่มscriptsส่วนต่อไปนี้ในproject.json:

 "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  },

ซึ่งจะทำงานร่วมกับ 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"]);

36
ฉันสับสนเล็กน้อยว่านี่คือคำตอบของคำถามได้อย่างไร นี่คือสิ่งที่ Microsoft มีสำหรับการกำหนดค่า Gulp ที่นี่ ( docs.microsoft.com/en-us/aspnet/core/client-side/using-gulp ) อย่างไรก็ตามเท่าที่ฉันสามารถบอกได้ว่าสิ่งนี้ไม่ได้ใช้เนื้อหาจากไดเร็กทอรี node_modules ของฉันและเพิ่มลงใน 'lib' หรือทำให้ใช้งานได้ในไฟล์ใด ๆ ของฉัน ... ฉันใหม่มากกับสิ่งนี้สับสนอย่างไม่น่าเชื่อกับสิ่งที่ดูเหมือนเหลือเชื่อ โลกใหม่ของการพัฒนาเว็บที่ซับซ้อน ...
เจอราร์ดวิลคินสัน

33
ซับซ้อนไม่เป็นไร ฉันพร้อมที่จะละทิ้งส่วนหน้าทั้งหมดและทำงานกับ API
Luke Puplett

12
นี่เป็นแนวทางที่ถูกต้องโดยทั่วไป แต่คำตอบจะทิ้งขั้นตอนที่สำคัญไว้: การคัดลอกไฟล์จากโฟลเดอร์ node_modules ไปยังโฟลเดอร์ wwwroot เป็นงาน Gulp เริ่มต้นด้วย var nodeRoot = './node_modules/'; และเพิ่มงานที่คัดลอกโฟลเดอร์ย่อยที่ต้องการจาก nodeRoot ไปยังโฟลเดอร์ย่อยที่เหมาะสมของ webroot ตอนนี้ยังไม่มีเวลาอธิบาย แต่ถ้ามีความสนใจฉันสามารถเพิ่มรายละเอียดได้ในภายหลัง
ดั๊ก

32
เหตุใดจึงไม่มีใครยกความชัดเจน: "ทำไมเราต้องถามคำถามนี้!" เหตุใดเราจึงตั้งใจติดตั้งไฟล์ในตำแหน่งที่ไม่สามารถใช้งานได้? ดังนั้นเนื่องจากไฟล์ของเราไม่สามารถเข้าถึงได้เราจึงติดตั้งและกำหนดค่ายูทิลิตี้ที่ซับซ้อนเพื่อคัดลอกไปยังตำแหน่งที่สามารถใช้งานได้ มันไร้สาระจริงๆ
สาม

8
เนื่องจากเครื่องมือที่นี่เป็นเรื่องไร้สาระโดยทั่วไป ใช้ NPM เป็นเพียงการใช้ NPM เช่นเดียวกับที่คุณต้องการสำหรับอะไร ASP.NET Core ไม่มีอะไรเฉพาะ ทุกอย่างเข้าสู่node_modulesเพราะนั่นคือสิ่งที่ npm ทำ งานอึกเป็นสิ่งจำเป็นในการเคลื่อนย้ายสิ่งของไปยังสถานที่ที่เหมาะสมนั่นคือที่ที่คุณต้องการจริงๆ ฉันคิดว่าปัญหาคือ Microsoft ให้การผสานรวมที่สวยงามกับ Bower แต่ตอนนี้ Bower ตายไปแล้ว (หรืออย่างน้อยก็ตาย) และ Microsoft ไม่ได้จัดหาเครื่องมืออื่นใดให้
Chris Pratt

41

ใส่คำอธิบายภาพที่นี่

  • การใช้npmสำหรับจัดการไลบรารีฝั่งไคลเอ็นต์เป็นทางเลือกที่ดี (เมื่อเทียบกับ Bower หรือ NuGet) คุณกำลังคิดในทิศทางที่ถูกต้อง :)
  • แยกฝั่งเซิร์ฟเวอร์ (ASP.NET Core) และฝั่งไคลเอ็นต์ (เช่น Angular 2, Ember, React) โปรเจ็กต์เป็นโฟลเดอร์แยกกัน (มิฉะนั้นโปรเจ็กต์ ASP.NET ของคุณอาจมีเสียงรบกวนมาก - การทดสอบหน่วยสำหรับโค้ดฝั่งไคลเอ็นต์ node_modules โฟลเดอร์สร้างสิ่งประดิษฐ์ ฯลฯ ) นักพัฒนาส่วนหน้าที่ทำงานในทีมเดียวกันกับคุณจะขอบคุณสำหรับสิ่งนั้น :)
  • กู้คืนโมดูล npm ที่ระดับโซลูชัน (เช่นเดียวกับวิธีที่คุณกู้คืนแพ็คเกจผ่าน NuGet - ไม่ใช่ในโฟลเดอร์ของโครงการ) วิธีนี้คุณสามารถมีการทดสอบหน่วยและการรวมในโฟลเดอร์แยกต่างหากได้เช่นกัน (ตรงข้ามกับการทดสอบ JavaScript ฝั่งไคลเอ็นต์ภายในของคุณ โครงการ ASP.NET Core)
  • การใช้งานอาจไม่จำเป็นต้องFileServerมีStaticFilesเพียงพอสำหรับการให้บริการไฟล์คงที่ (.js, รูปภาพ ฯลฯ )
  • ใช้ Webpack เพื่อรวมโค้ดฝั่งไคลเอ็นต์ของคุณเป็นกลุ่ม (บันเดิล) อย่างน้อยหนึ่งชิ้น
  • คุณอาจไม่จำเป็นต้องใช้ Gulp / Gruntหากคุณใช้ชุดรวมโมดูลเช่น Webpack
  • เขียนบิลด์อัตโนมัติสคริปต์ใน ES2015 + JavaScript (ตรงข้ามกับ Bash หรือ PowerShell) พวกเขาจะทำงานข้ามแพลตฟอร์มและสามารถเข้าถึงได้มากขึ้นสำหรับนักพัฒนาเว็บที่หลากหลาย (ทุกคนพูด JavaScript ในปัจจุบัน)
  • เปลี่ยนชื่อwwwrootเป็นpublicมิฉะนั้นโครงสร้างโฟลเดอร์ใน Azure Web Apps จะสับสน ( D:\Home\site\wwwroot\wwwrootเทียบกับD:\Home\site\wwwroot\public)
  • เผยแพร่เฉพาะเอาต์พุตที่คอมไพล์แล้วไปยัง Azure Web Apps (คุณไม่ควรส่งnode_modulesไปยังเว็บโฮสติ้งเซิร์ฟเวอร์) ดูtools/deploy.jsเป็นตัวอย่าง.

เยี่ยมชมASP.NET Core Starter Kitบน GitHub (ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้เขียน)


2
คำตอบที่ดีความรุ่งโรจน์สำหรับงานของคุณในการจัดหาชุดเริ่มต้นให้กับชุมชน!
David Pine

7
ฉันสร้างแอป Angular สาธารณะขนาดใหญ่สำหรับแบรนด์ใหญ่ ๆ ในสหราชอาณาจักรเมื่อต้นปีนี้สำเร็จ แต่ฉันก็ไม่เข้าใจคำตอบส่วนใหญ่นี้ด้วยซ้ำ ฉันไม่สามารถแม้แต่จะเริ่มเรียนรู้มันได้ในทุกที่ แท้จริงมีวิกฤตอาชีพ
Luke Puplett

นี่คือบทสรุปที่ดีของสิ่งที่ควรทำและสิ่งที่ไม่ควรทำในขณะที่เขียนและจัดการสคริปต์และไฟล์ฝั่งไคลเอ็นต์ ประหยัดเวลาและการวิจัยของฉัน ขอชื่นชมคุณ!
Sangeeta

น่าเสียดายที่ Visual Studio (IMHO แบบโง่ ๆ ) ปฏิบัติต่อไดเร็กทอรี "wwwroot" เป็นพิเศษโดยใช้ชื่อเพียงอย่างเดียวโดยให้ไอคอน "web root" พิเศษในตัวสำรวจโซลูชันและทำเครื่องหมายเนื้อหาเป็น "ไม่มี" ตามค่าเริ่มต้นแทนที่จะเป็น "เนื้อหา" . หากมีเจตนาที่จะใส่ไฟล์ที่แสดงแบบคงที่ไว้ในนั้นและคุณกำลังใช้ Visual Studio คุณควรปล่อยให้ชื่อเป็น "wwwroot" ฉันยอมรับว่ามันเป็นชื่อที่ไม่ดี
Jez

27

ติดตั้ง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
  }
]

ดังนั้นบันเดิลเลอร์และมินิไฟเออร์ (ตามอึก) จึงมีสิทธิ์เข้าถึงไฟล์ต้นฉบับ (ซึ่งควรแยกออกจาก Visual Studio และแยกออกจาก GIT ด้วย) และวางไว้ใน wwwroot ตามที่ระบุ

เฉพาะผลข้างเคียงทุกครั้งที่คุณบันทึกมันจะเรียกใช้สิ่งนี้ (แต่คุณสามารถตั้งค่าให้เรียกใช้ด้วยตนเองได้)


4
หลังจากเห็นว่า Bower ตายแล้วและฉันไม่สามารถอัปเดต Bootstrap ได้อีกต่อไปโดยไม่เปลี่ยนเป็น NPM นี่เป็นแนวทางที่ฉันชอบ Gulp หรือ Webpack ดูเหมือนจะมากเกินไปเมื่อเทียบกับโซลูชันง่ายๆนี้ซึ่งมีอยู่แล้วในเทมเพลตโครงการ MVC ล่าสุด ขอบคุณสำหรับการแชร์!
Matt Sanders

1
ภาพที่อ้างถึงใน css ถูกจัดการที่นี่อย่างไร? ฉันประสบปัญหากับรูปภาพที่ยังอยู่ในโฟลเดอร์ node_modules ซึ่งเมื่อ css และ js ถูกย้ายไปที่ www มีความคิดอย่างไรที่จะแก้ไขปัญหานี้
VPP

1
IDE นี้ไม่เชื่อเรื่องพระเจ้าหรือไม่? วิธีนี้จะทำงานอย่างไรหากบางทีมของคุณใช้ VS Code และสิ่งนี้จะเล่นในท่อสร้างซีดีอย่างไร
Jacob Stamm

เมื่อคุณติดตั้งแพคเกจ Bundler และ Minifier NuGet เอกสารจะบอกว่ามันฉีดบิลด์เป้าหมายที่ทำงานในเวลาสร้างและล้างข้อมูล ฉันคิดว่าเมื่อเข้าที่แล้วมันจะทำงานได้ดีไม่ว่าจะใช้ IDE ใดใช่ไหม? ดูเพิ่มเติม: docs.microsoft.com/en-gb/aspnet/core/client-side/…
Ciaran Gallagher

บันเดิลเลอร์มีประโยชน์สำหรับการระบุสคริปต์เหล่านี้นอกสภาวะแวดล้อมการพัฒนาเท่านั้น จากหน้า _Layout ของฉันฉันยังคงต้องอ้างอิงไฟล์ JS และ CSS ด้วยตนเองที่ฉันต้องการ แต่โฟลเดอร์ node_modules อยู่นอกเว็บไซต์ ... ดังนั้นฉันไม่คิดว่าสิ่งนี้จะแก้ไขปัญหาได้อย่างถูกต้องคุณยังคงต้องใช้สคริปต์ Gulp เพื่อคัดลอก ไฟล์ที่จำเป็นไปยังโฟลเดอร์ wwwroot ของฉัน
Ciaran Gallagher

21

ฉันให้คำตอบคุณสองข้อ npmรวมกับเครื่องมืออื่น ๆ มีประสิทธิภาพ แต่ต้องทำงานในการตั้งค่า หากคุณต้องการดาวน์โหลดไลบรารีบางส่วนคุณอาจต้องการใช้Library Managerแทน (เผยแพร่ใน 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"
  }
}

สิ่งนี้จะทำให้ NPM ดาวน์โหลด Bootstrap, JQuery และไลบรารีอื่น ๆ ที่ใช้ในโปรเจ็กต์หลักของ asp.net ใหม่ไปยังโฟลเดอร์ชื่อ 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"));
});

ไฟล์นี้มีโค้ด JavaScript ที่ดำเนินการเมื่อสร้างและล้างโปรเจ็กต์ มันจะคัดลอกไฟล์ที่จำเป็นทั้งหมดไปยังlib2 ( ไม่ใช่ lib - คุณสามารถเปลี่ยนสิ่งนี้ได้อย่างง่ายดาย ) ฉันใช้โครงสร้างเดียวกันกับในโปรเจ็กต์ใหม่ แต่เปลี่ยนไฟล์ไปยังตำแหน่งอื่นได้ง่าย หากคุณย้ายไฟล์ตรวจสอบให้แน่ใจว่าคุณได้อัปเดต_Layout.cshtmlด้วย โปรดสังเกตว่าไฟล์ทั้งหมดในไดเร็กทอรี lib2 จะถูกลบออกเมื่อโปรเจ็กต์ถูกล้าง

หากคุณคลิกขวาที่gulpfile.jsคุณสามารถเลือกงานวิ่ง Explorer ที่ จากที่นี่คุณสามารถเรียกใช้อึกด้วยตนเองเพื่อคัดลอกหรือล้างไฟล์

Gulp อาจมีประโยชน์สำหรับงานอื่น ๆ เช่น minify JavaScript และ CSS-files:

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

ผู้จัดการห้องสมุด (ง่าย)

คลิกขวาที่คุณโครงการและเลือกจัดการลูกค้าด้านห้องสมุด ขณะนี้ไฟล์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"
    }
  ]
}

หากคุณย้ายไฟล์ตรวจสอบให้แน่ใจว่าคุณได้อัปเดต_Layout.cshtmlด้วย


2
ผู้จัดการห้องสมุด - ไม่เคยได้ยินมาก่อน แต่เป็นสิ่งที่ฉันต้องการ! นี่น่าจะเป็นคำตอบที่ถูกต้อง
codeMonkey

1
เพื่อหลีกเลี่ยงข้อผิดพลาดอึกฉันต้องเปลี่ยนบรรทัดแรกของงานเริ่มต้นในไฟล์gulpfile.jsเป็นgulp.task('default', function (done) {แล้วเพิ่มเป็นบรรทัดสุดท้ายในฟังก์ชั่นดังต่อไปนี้: done();มิฉะนั้นฉันจะได้รับข้อความแสดงข้อผิดพลาดThe following tasks did not complete: Did you forget to signal async completion?
Manfred

7

แทนที่จะพยายามให้บริการโฟลเดอร์โมดูลโหนดคุณยังสามารถใช้ Gulp เพื่อคัดลอกสิ่งที่คุณต้องการไปยัง wwwroot

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

สิ่งนี้อาจช่วยได้เช่นกัน

Visual Studio 2015 ASP.NET 5 งานอึกไม่คัดลอกไฟล์จาก node_modules


4
ฉันชอบลิงค์ที่สองมากดูเหมือนจะคุ้นเคยดี ;)
David Pine

1
ไม่สะดวกมากเมื่อคุณผสมไฟล์ต้นฉบับของเว็บแอป ASP.NET Core กับโมดูล npm และเอาต์พุตการสร้างโค้ดฝั่งไคลเอ็นต์ นั่นเป็นเหตุผลว่าทำไมทีม ASP.NET จึงลบ Gulp, package.json ออกจากเทมเพลตโครงการ ASP.NET MVC เริ่มต้น
Konstantin Tarkus

ผมไม่ทราบว่า. ตอนที่ฉันอยู่ที่ VS Live ในเดือนมีนาคมพวกเขาทุกอย่างเกี่ยวกับเรื่องนี้ แต่มันเปลี่ยนไปมากตั้งแต่นั้นมา
Dave_750

6

แนวทางที่เหมาะสมในการทำเช่นนี้คืออะไร?

มีหลายวิธีที่ "ถูกต้อง" เพียงแค่คุณตัดสินใจเลือกห้องชุดที่ดีที่สุดที่คุณต้องการ ดูเหมือนว่าคุณเข้าใจผิดวิธีใช้node_modules...

หากคุณคุ้นเคยกับNuGetคุณควรคิดว่าnpmเป็นคู่สัญญาฝั่งไคลเอ็นต์ ในกรณีที่node_modulesไดเรกทอรีเป็นเหมือนbinไดเรกทอรีสำหรับNuGet แนวคิดก็คือไดเร็กทอรีนี้เป็นเพียงตำแหน่งทั่วไปสำหรับจัดเก็บแพ็คเกจในความคิดของฉันควรdependencyเลือกแพ็คเกจที่คุณต้องการเหมือนที่คุณทำในไฟล์package.json. จากนั้นใช้ Task Runner Gulpเช่นเพื่อคัดลอกไฟล์ที่คุณต้องการไปยังwwwrootตำแหน่งที่คุณต้องการ

ฉันเขียนบล็อกโพสต์เกี่ยวกับเรื่องนี้ในเดือนมกราคมซึ่งมีรายละเอียดnpm , Gulpและรายละเอียดอื่น ๆ ทั้งหมดที่ยังคงเกี่ยวข้องในปัจจุบัน นอกจากนี้มีคนเรียกร้องความสนใจให้กับคำถาม SO ของฉันที่ฉันถามและในที่สุดก็ตอบตัวเองที่นี่ซึ่งอาจเป็นประโยชน์

ฉันสร้างGistที่แสดงgulpfile.jsเป็นตัวอย่าง

ในของคุณStartup.csการใช้ไฟล์คงที่เป็นสิ่งสำคัญ:

app.UseStaticFiles();

เพื่อให้แน่ใจว่าแอปพลิเคชันของคุณสามารถเข้าถึงสิ่งที่ต้องการได้


3
"ฉันเขียนบล็อกโพสต์เกี่ยวกับเรื่องนี้ในเดือนมกราคมที่มีรายละเอียดเกี่ยวกับ npm อึกและรายละเอียดอื่น ๆ ทั้งหมดที่ยังคงเกี่ยวข้องในปัจจุบัน" ความจริงที่ว่าตั้งแต่เดือนมกราคม - มิถุนายนและที่คุณต้องพูดถึงนั้นยังคงมีความเกี่ยวข้องอยู่นั่นคือปัญหาของฉันที่รบกวนการเรียนรู้สิ่งต่างๆที่บินได้โดยคืนนี้ ฉันเรียนรู้มากเกินไปแล้วโดยไม่เสียเวลาไปกับแฟชั่น ไม่ใช่ความผิดของคุณดาวิดคุณมีประโยชน์มาก แต่ฉันไม่ชอบโลกใหม่ที่ไม่จีรังนี้
Luke Puplett

5

วิธีที่ง่ายมากคือการใช้OdeToCode.UseNodeModulesแพคเกจ Nuget ฉันเพิ่งทดสอบกับ. Net Core 3.0 สิ่งที่คุณต้องทำคือเพิ่มแพ็กเกจลงในโซลูชันและอ้างอิงในวิธีกำหนดค่าของคลาสเริ่มต้น:

app.UseNodeModules();

ฉันได้เรียนรู้เกี่ยวกับเรื่องนี้จากการสร้างเว็บแอปที่ยอดเยี่ยมด้วย ASP.NET Core, MVC, Entity Framework Core, Bootstrap และ Angular Pluralsight โดย Shawn Wildermuth


1
และคุณจะเพิ่มแพ็คเกจ npm ได้อย่างไร?
Luca Ziegler

มีหลายวิธีในการเพิ่มแพ็กเกจ npm ในโปรเจ็กต์ของคุณ ฉันชอบพิมพ์ลงในไฟล์ package.json ภายใต้โหนดการอ้างอิงตามที่อธิบายไว้ที่นี่: stackoverflow.com/a/49264424/5301317
Mariusz Bialobrzeski

@MariuszBialobrzeski ขอบคุณสำหรับการแบ่งปัน นี่เป็นวิธีแก้ปัญหาที่เรียบร้อย
Sau001

@MariuszBialobrzeski คุณต้องทำอะไรเพิ่มเติมเพื่อปรับใช้เนื้อหาแบบคงที่จาก node_modules ในไปป์ไลน์ DevOps ของคุณหรือไม่? หรือคุณตรวจสอบในโฟลเดอร์ node_modules?
Sau001

1
@ Sau001 น่าเสียดายที่ฉันไม่เคยมีโอกาสทำงานกับท่อส่ง DevOps โฟลเดอร์ node_modules มีแนวโน้มที่จะใหญ่พอสมควรดังนั้นฉันจะหลีกเลี่ยงการตรวจสอบอย่างแน่นอนถ้าเป็นไปได้
Mariusz Bialobrzeski

1

Shawn Wildermuth มีคำแนะนำที่ดีที่นี่: https://wildermuth.com/2017/11/19/ASP-NET-Core-2-0-and-the-End-of-Bower

บทความนี้เชื่อมโยงไปยัง gulpfile บน GitHub ซึ่งเขาใช้กลยุทธ์ในบทความ คุณสามารถคัดลอกและวางเนื้อหา gulpfile ส่วนใหญ่ลงในของคุณได้ แต่อย่าลืมเพิ่มแพ็คเกจที่เหมาะสมใน package.json ภายใต้ devDependencies: gulp gulp-uglify gulp-concat rimraf merge-stream


1

ฉันพบวิธีที่ดีกว่าในการจัดการแพ็คเกจ JS ในโครงการของฉันด้วยนักวิ่งงาน NPM Gulp / Grunt ฉันไม่ชอบความคิดที่จะมี NPM ที่มีไลบรารี javascript อีกชั้นเพื่อจัดการกับ "ระบบอัตโนมัติ" และข้อกำหนดอันดับหนึ่งของฉันคือการรันการอัปเดต npm อย่างง่ายโดยไม่ต้องกังวลว่าฉันจะต้องเรียกใช้งานอึกหรือเปล่า หากคัดลอกทุกอย่างสำเร็จและในทางกลับกัน

วิธี NPM:

  • ตัวย่อ JS นั้นรวมอยู่ในแกน ASP.net แล้วให้มองหา bundleconfig.json ดังนั้นนี่ไม่ใช่ปัญหาสำหรับฉัน (ไม่ได้รวบรวมสิ่งที่กำหนดเอง)
  • สิ่งที่ดีเกี่ยวกับ NPM คือมีโครงสร้างไฟล์ที่ดีดังนั้นฉันจึงสามารถค้นหาการอ้างอิงเวอร์ชันที่คอมไพล์ล่วงหน้า / ย่อขนาดได้ตลอดเวลาภายใต้ node_modules / module / dist
  • ฉันใช้สคริปต์ NPM node_modules / .hooks / {eventname} ซึ่งจัดการคัดลอก / อัปเดต / ลบไฟล์ Project / wwwroot / lib / module / dist / .js คุณสามารถดูเอกสารได้ที่นี่https: // docs.npmjs.com/misc/scripts (ฉันจะอัปเดตสคริปต์ที่ฉันใช้เพื่อคอมไพล์เมื่อมันจะได้รับการขัดเกลามากขึ้น) ฉันไม่ต้องการนักวิ่งงานเพิ่มเติม (เครื่องมือ .js ที่ฉันไม่ชอบ) สิ่งที่ทำให้โครงการของฉันสะอาดและเรียบง่าย

วิธีหลาม:

https://pypi.python.org/pyp ... แต่ในกรณีนี้คุณต้องดูแลแหล่งข้อมูลด้วยตนเอง


1

ขอแก้ตัวยาว ๆ ของกระทู้นี้

นี่คือตัวอย่างการทำงานโดยใช้ ASP.NET Core เวอร์ชัน 2.5

บางสิ่งบางอย่างที่ทราบก็คือว่าproject.jsonเป็นล้าสมัย ( ดูที่นี่ ) ในความโปรดปรานของ.csproj มีปัญหากับ.csproj ไฟล์เป็นคุณสมบัติจำนวนมากและไม่มีตำแหน่งศูนย์กลางสำหรับเอกสารประกอบ ( ดูที่นี่ )

อีกอย่างหนึ่งตัวอย่างนี้กำลังเรียกใช้ ASP.NET core ในคอนเทนเนอร์ Docker Linux (alpine 3.9) ดังนั้นเส้นทางจะสะท้อนถึงสิ่งนั้น นอกจากนี้ยังใช้ gulp ^ 4.0 อย่างไรก็ตามด้วยการปรับเปลี่ยนบางอย่างควรใช้งานได้กับ ASP.NET Core, Gulp, NodeJS เวอร์ชันเก่าและไม่มี Docker

แต่นี่คือคำตอบ:

gulpfile.js ดูตัวอย่างการทำงานจริงที่นี่

// ROOT and OUT_DIR are defined in the file above. The OUT_DIR value comes from .NET Core when ASP.net us built.
const paths = {
    styles: {
        src: `${ROOT}/scss/**/*.scss`,
        dest: `${OUT_DIR}/css`
    },
    bootstrap: {
        src: [
            `${ROOT}/node_modules/bootstrap/dist/css/bootstrap.min.css`,
            `${ROOT}/node_modules/startbootstrap-creative/css/creative.min.css`
        ],
        dest: `${OUT_DIR}/css`
    },
    fonts: {// enter correct paths for font-awsome here.
        src: [
            `${ROOT}/node_modules/fontawesome/...`,
        ],
        dest: `${OUT_DIR}/fonts`
    },
    js: {
        src: `${ROOT}/js/**/*.js`,
        dest: `${OUT_DIR}/js`
    },
    vendorJs: {
        src: [
            `${ROOT}/node_modules/jquery/dist/jquery.min.js`
            `${ROOT}/node_modules/bootstrap/dist/js/bootstrap.min.js`
        ],
        dest: `${OUT_DIR}/js`
    }
};

// Copy files from node_modules folder to the OUT_DIR.
let fonts = () => {
    return gulp
        .src(paths.styles.src)
        .pipe(gulp.dest(paths.styles.dest));
};

// This compiles all the vendor JS files into one, jsut remove the concat to keep them seperate.
let vendorJs = () => {
    return gulp
        .src(paths.vendorJs.src)
        .pipe(concat('vendor.js'))
        .pipe(gulp.dest(paths.vendorJs.dest));
}

// Build vendorJs before my other files, then build all other files in parallel to save time.
let build = gulp.series(vendorJs, gulp.parallel(js, styles, bootstrap));

module.exports = {// Only add what we intend to use externally.
    default: build,
    watch
};

เพิ่มTargetในไฟล์. csproj โปรดสังเกตว่าเราได้เพิ่มWatchเพื่อดูและยกเว้นหากเราใช้ประโยชน์จากdotnet run watchคำสั่ง

app.csprod

  <ItemGroup>
    <Watch Include="gulpfile.js;js/**/*.js;scss/**/*.scss" Exclude="node_modules/**/*;bin/**/*;obj/**/*" />
  </ItemGroup>

  <Target Name="BuildFrontend" BeforeTargets="Build">
    <Exec Command="yarn install" />
    <Exec Command="yarn run build -o $(OutputPath)" />
  </Target>

ตอนนี้เมื่อdotnet run buildเรียกใช้มันจะติดตั้งและสร้างโมดูลโหนด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.