Comment utiliser npm avec ASP.NET Core

J’utilise npm pour gérer les bibliothèques client jQuery, Bootstrap, Font Awesome et similaires dont j’ai besoin pour mon application ASP.NET Core.

L’approche qui a fonctionné pour moi a commencé en ajoutant un fichier package.json au projet, qui ressemble à ceci:

{ "version": "1.0.0", "name": "myapp", "private": true, "devDependencies": { }, "dependencies": { "bootstrap": "^3.3.6", "font-awesome": "^4.6.1", "jquery": "^2.2.3" } } 

npm restaure ces paquets dans le dossier node_modules qui se trouve au même niveau que wwwroot dans le répertoire du projet:

entrer la description de l'image ici

Comme ASP.NET Core sert les fichiers statiques du dossier wwwroot et que node_modules n’est pas là, j’ai dû apporter quelques modifications pour que cela fonctionne, le premier: append app.UseFileServer juste avant app.UseStaticFiles dans mon démarrage. fichier cs:

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

et le second, y compris node_modules dans mes publishOptions dans le fichier project.json:

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

Cela fonctionne dans mon environnement de développement et cela fonctionne également lorsque je le déploie sur mon instance Azure App Service, les fichiers statiques jquery, bootstrap et font-awesome sont bien servis, mais je ne suis pas sûr de cette implémentation.

Quelle est la bonne approche pour ce faire?

Cette solution est intervenue après avoir collecté beaucoup d’informations sur plusieurs sources et essayé certaines d’entre elles qui ne fonctionnaient pas, et cela semble un peu étrange de devoir servir ces fichiers depuis l’extérieur de wwwroot.

Tout conseil sera grandement apprécié.

En publiant l’intégralité de votre dossier node_modules , vous déployez beaucoup plus de fichiers que ce dont vous avez réellement besoin en production.

Au lieu de cela, utilisez un programme d’exécution dans le cadre de votre processus de génération pour empaqueter les fichiers dont vous avez besoin et déployez-les dans votre dossier wwwroot . Cela vous permettra également de concaténer et de minimiser vos actifs en même temps, plutôt que de devoir servir chaque bibliothèque séparément.

Vous pouvez ensuite également supprimer complètement la configuration de UseStaticFiles et vous fier à UseStaticFiles .

Actuellement, gulp est le coureur de tâche de choix de VS. Ajoutez un gulpfile.js à la racine de votre projet et configurez-le pour traiter vos fichiers statiques lors de la publication.

Par exemple, vous pouvez append la section de scripts suivante à votre project.json :

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

Qui fonctionnerait avec le fichier gulpfile suivant (la valeur par défaut lors de l’échafaudage avec yo ):

 ///  "use ssortingct"; 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"]); 

entrer la description de l'image ici

  • Utiliser npm pour gérer les bibliothèques côté client est un bon choix (par opposition à Bower ou NuGet), vous réfléchissez dans la bonne direction 🙂
  • Divisez les projets côté serveur (ASP.NET Core) et côté client (par exemple Angular 2, Ember, React) en des dossiers distincts (sinon votre projet ASP.NET peut avoir beaucoup de bruit – tests unitaires pour le code côté client, node_modules dossier, créer des artefacts, etc.). Les développeurs front-end travaillant avec vous dans la même équipe vous en remercieront 🙂
  • Restaurez les modules npm au niveau de la solution (de la même manière que vous restaurez des packages via NuGet – pas dans le dossier du projet), vous pouvez également avoir des tests d’unité et d’intégration dans un dossier séparé Projet ASP.NET Core).
  • Utiliser peut ne pas avoir besoin de FileServer , avoir StaticFiles devrait suffire pour servir des fichiers statiques (.js, images, etc.)
  • Utilisez Webpack pour regrouper votre code côté client en un ou plusieurs blocs
  • Vous n’avez peut-être pas besoin de Gulp / Grunt si vous utilisez un module tel que Webpack
  • Ecrire des scripts d’automatisation de la construction dans JavaScript ES2015 + (par opposition à Bash ou PowerShell), ils fonctionneront sur plusieurs plates-formes et seront plus accessibles à de nombreux développeurs Web (tout le monde parle JavaScript)
  • Renommez wwwroot en public , sinon la structure des dossiers dans Azure Web Apps sera source de confusion ( D:\Home\site\wwwroot\wwwroot vs D:\Home\site\wwwroot\public )
  • Publiez uniquement la sortie compilée sur Azure Web Apps (vous ne devez jamais node_modules à un serveur d’hébergement Web). Voir tools/deploy.js comme exemple.

Visitez ASP.NET Core Starter Kit sur GitHub (avertissement: je suis l’auteur)

Installer Bundler et Minifier dans les extensions Visual Studio

Ensuite, vous créez un bundleconfig.json et entrez les éléments suivants comme:

 // 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 } ] 

Ainsi, le bundler et le minifier (basé sur gulp) ont access aux fichiers source (qui devraient être exclus de Visual Studio et également exclus de GIT) et les placent dans le site Web spécifié.

seul effet secondaire à chaque fois que vous enregistrez le sera exécuté (ou vous pouvez le définir ou l’exécuter manuellement)

Au lieu d’essayer de servir le dossier des modules de noeud, vous pouvez également utiliser Gulp pour copier ce dont vous avez besoin sur wwwroot.

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

Cela pourrait aussi aider

Visual Studio 2015 ASP.NET 5, tâche Gulp ne copiant pas les fichiers depuis node_modules

Quelle est la bonne approche pour ce faire?

Il y a beaucoup d’approches “justes”, vous n’avez qu’à décider lequel répond le mieux à vos besoins. Il semble que vous node_modules mal comment utiliser node_modules

Si vous connaissez NuGet, vous devriez penser à npm comme son homologue côté client. Où le répertoire node_modules est comme le répertoire bin de NuGet . L’idée est que ce répertoire est juste un emplacement commun pour stocker des paquets, à mon avis, il est préférable de prendre une dependency sur les paquets dont vous avez besoin comme vous l’avez fait dans le package.json . Ensuite, utilisez un coureur de tâches comme Gulp par exemple, pour copier les fichiers dont vous avez besoin dans votre emplacement wwwroot souhaité.

J’ai écrit un article sur ce sujet en janvier, qui détaille NPM , Gulp et tout un tas d’autres détails qui sont toujours d’actualité. De plus, quelqu’un a attiré l’attention sur ma question SO que j’ai posée et que j’ai finalement répondu moi-même, ce qui est probablement utile.

J’ai créé un Gist qui montre le gulpfile.js comme exemple.

Dans votre Startup.cs il est toujours important d’utiliser des fichiers statiques:

 app.UseStaticFiles(); 

Cela garantira que votre application peut accéder à ce dont elle a besoin.

Je vous donne deux réponses. npm combiné à d’autres outils est puissant mais nécessite un travail de configuration. Si vous souhaitez simplement télécharger certaines bibliothèques, vous pouvez utiliser le gestionnaire de bibliothèque (publié dans Visual Studio 15.8).

MNP (avancé)

Ajoutez d’abord package.json à la racine de votre projet. Ajoutez le contenu suivant:

 { "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" } } 

Cela permettra à NPM de télécharger Bootstrap, JQuery et d’autres bibliothèques utilisées dans un nouveau projet core asp.net dans un dossier nommé node_modules. La prochaine étape consiste à copier les fichiers à un endroit approprié. Pour ce faire, nous utiliserons gulp, qui a également été téléchargé par NPM. Ajoutez ensuite un nouveau fichier dans la racine de votre projet nommé gulpfile.js . Ajoutez le contenu suivant:

 ///  /* 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")); }); 

Ce fichier contient un code JavaScript qui est exécuté lorsque le projet est créé et nettoyé. Il copiera tous les fichiers nécessaires dans lib2 ( pas lib – vous pouvez facilement changer cela ). J’ai utilisé la même structure que dans un nouveau projet, mais il est facile de changer de fichier à un autre endroit. Si vous déplacez les fichiers, assurez-vous de mettre également à jour _Layout.cshtml . Notez que tous les fichiers du répertoire lib2 seront supprimés lors du nettoyage du projet.

Si vous cliquez avec le bouton droit sur gulpfile.js , vous pouvez sélectionner Task Runner Explorer . De là, vous pouvez exécuter manuellement gulp pour copier ou nettoyer des fichiers.

Gulp pourrait également être utile pour d’autres tâches telles que la réduction de JavaScript et de fichiers CSS:

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

Gestionnaire de bibliothèque (simple)

Cliquez avec le bouton droit sur votre projet et sélectionnez Gérer les bibliothèques côté client . Le fichier libman.json est maintenant ouvert. Dans ce fichier, vous spécifiez la bibliothèque et les fichiers à utiliser et où ils doivent être stockés localement. Vraiment simple! Le fichier suivant copie les bibliothèques par défaut utilisées lors de la création d’un nouveau projet 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" } ] } 

Si vous déplacez les fichiers, assurez-vous de mettre également à jour _Layout.cshtml .

Shawn Wildermuth a un bon guide ici: https://wildermuth.com/2017/11/19/ASP-NET-Core-2-0-et-the-End-of-Bower

L’article se lie au fichier gulpfile sur GitHub où il a implémenté la stratégie dans l’article. Vous pouvez simplement copier et coller la plupart des contenus de gulpfile dans le vôtre, mais veillez à append les paquets appropriés dans package.json sous devDependencies: gulp-uglify gulp-concat rimraf merge-stream

J’ai trouvé un meilleur moyen de gérer les packages JS dans mon projet avec les utilisateurs de NPM Gulp / Grunt. Je n’aime pas l’idée d’avoir un NPM avec une autre couche de bibliothèque javascript pour gérer “l’automatisation”, et mon exigence numéro un est de simplement exécuter la mise à jour npm sans autre souci si j’ai besoin de lancer des trucs, s’il a tout copié avec succès et vice versa.

Le mode NPM:

  • Le minificateur JS est déjà inclus dans le kernel ASP.net, recherchez bundleconfig.json, ce n’est donc pas un problème pour moi (ne pas comstackr quelque chose de personnalisé)
  • La bonne chose à propos de NPM est qu’il a une bonne structure de fichiers, donc je peux toujours trouver les versions pré-compilées / minifiées des dépendances sous node_modules / module / dist.
  • J’utilise un script NPM node_modules / .hooks / {eventname} qui gère la copie / mise à jour / suppression des fichiers Project / wwwroot / lib / module / dist / .js, vous pouvez trouver la documentation ici https: // docs.npmjs.com/misc/scripts (Je mettrai à jour le script que j’utilise une fois qu’il sera plus fin) Je n’ai pas besoin de coureurs de tâches supplémentaires ( outils .js que je n’aime pas) ce qui maintient mon projet propre et simple.

Le python:

https://pypi.python.org/pyp … mais dans ce cas, vous devez gérer les sources manuellement