web-dev-qa-db-fra.com

Comment utiliser npm avec ASP.NET Core

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

L'approche qui a fonctionné pour moi a commencé par l'ajout d'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 packages dans le dossier node_modules qui se trouve au même niveau que wwwroot dans le répertoire du projet:

enter image description here

Comme ASP.NET Core traite les fichiers statiques à partir du dossier wwwroot, et que node_modules n’y est pas, j’ai dû apporter quelques modifications pour que cela fonctionne, le premier: ajouter 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 PathString("/node_modules"),
    EnableDirectoryBrowsing = true
});

app.UseStaticFiles();

et le second, incluant 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 é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 faire cela?

Cette solution est venue après avoir collecté de nombreuses informations provenant de plusieurs sources et en avoir essayé d'autres qui ne fonctionnaient pas, et il semble un peu étrange de devoir servir ces fichiers de l'extérieur de wwwroot.

Tout conseil sera grandement apprécié.

98
Carlos Figueroa

En publiant l'intégralité de votre dossier node_modules, vous déployez beaucoup plus de fichiers que vous n'en aurez réellement besoin en production.

Utilisez plutôt un programme d'exécution de tâches dans le cadre de votre processus de construction pour regrouper 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 ressources en même temps, au lieu de devoir desservir chaque bibliothèque séparément.

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

À l’heure actuelle, gulp est le gestionnaire de choix des tâches 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 ajouter la section scripts suivante à votre project.json:

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

Ce qui fonctionnerait avec le fichier gulp suivant (valeur par défaut lors de l'échafaudage avec 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"]);
37
Sock

enter image description here

  • Utiliser npm pour la gestion des bibliothèques côté client est un bon choix (contrairement à Bower ou NuGet), vous pensez aller dans la bonne direction :)
  • Divisez les projets côté serveur (ASP.NET Core) et côté client (par exemple, Angular 2, Ember, React) dans des dossiers distincts (sinon, votre projet ASP.NET risque de générer beaucoup de parasites. code côté client, dossier node_modules, générer des artefacts, etc.). Les développeurs front-end travaillant dans la même équipe avec vous 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 - et non dans le dossier du projet). Ainsi, vous pouvez également avoir des tests unitaires et d’intégration dans un dossier séparé (au lieu de tests JavaScript côté Projet ASP.NET Core).
  • Utiliser peut-être pas besoin de FileServer, avoir StaticFiles devrait suffire pour servir des fichiers statiques (.js, images, etc.)
  • Utilisez Webpack pour regrouper votre code côté client dans un ou plusieurs morceaux
  • Vous n’avez peut-être pas besoin de Gulp/Grunt si vous utilisez un bundle de modules tel que Webpack
  • Écrire des scripts d'automatisation de la construction dans ES2015 + JavaScript (contrairement à Bash ou PowerShell), ils fonctionneront sur plusieurs plateformes et seront plus accessibles à une variété de développeurs Web (tout le monde parle JavaScript aujourd'hui).
  • Renommez wwwroot en public, sinon la structure de 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 transmettre _node_modules_ à un serveur d'hébergement Web). Voir tools/deploy.js à titre d'exemple.

Visitez Kit de démarrage ASP.NET Core sur GitHub (disclaimer: je suis l'auteur)

40
Konstantin Tarkus

Installer le Bundler et Minifier dans les extensions Visual Studio.

Ensuite, vous créez un bundleconfig.json et entrez ce qui suit:

// 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 groupeur et le minifier (basés sur gulp) ont accès aux fichiers source (qui doivent être exclus de Visual Studio et également de GIT) et les met dans le répertoire wwwroot comme spécifié.

seul effet secondaire chaque fois que vous enregistrez le programme sera exécuté (ou vous pouvez le définir ou le lancer manuellement)

24
Piotr Kula

Je vous donne deux réponses. npm combiné avec d'autres outils est puissant mais nécessite quelques travaux de configuration. Si vous souhaitez uniquement télécharger des bibliothèques, vous pouvez utiliser plutôt le gestionnaire de bibliothèques (publié dans Visual Studio 15.8).

NPM (Avancé)

Commencez par ajouter package.json à la racine du 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"
  }
}

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

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

Ce fichier contient un code JavaScript qui est exécuté lors de la construction et du nettoyage du projet. Il va copier 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 les fichiers à un autre emplacement. Si vous déplacez les fichiers, veillez également à mettre à jour _ Layout.cshtml . Notez que tous les fichiers du répertoire lib2 seront supprimés lors du nettoyage du projet.

Si vous faites un clic droit sur gulpfile.js , vous pouvez sélectionner Task Runner Explorer À partir de là, vous pouvez exécuter gulp manuellement pour copier ou nettoyer des fichiers.

Gulp pourrait également être utile pour d'autres tâches telles que minify JavaScript et les fichiers CSS:

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

Gestionnaire de bibliothèque (simple)

Faites un clic 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 quelle bibliothèque et quels 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": "[email protected]",
      "files": [ "jquery.js", "jquery.min.map", "jquery.min.js" ],
      "destination": "wwwroot/lib/jquery/dist/"
    },
    {
      "library": "[email protected]",
      "files": [ "additional-methods.js", "additional-methods.min.js", "jquery.validate.js", "jquery.validate.min.js" ],
      "destination": "wwwroot/lib/jquery-validation/dist/"
    },
    {
      "library": "[email protected]",
      "files": [ "jquery.validate.unobtrusive.js", "jquery.validate.unobtrusive.min.js" ],
      "destination": "wwwroot/lib/jquery-validation-unobtrusive/"
    },
    {
      "library": "[email protected]",
      "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": "[email protected]",
      "files": [ "list.js", "list.min.js" ],
      "destination": "wwwroot/lib/listjs"
    }
  ]
}

Si vous déplacez les fichiers, veillez également à mettre à jour _ Layout.cshtml .

15
PEK

Au lieu d'essayer de servir le dossier des modules de noeuds, 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 aider aussi

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

7
Dave_750

Quelle est la bonne approche pour faire cela?

Il y a beaucoup d'approches "correctes", il vous suffit de décider laquelle convient le mieux à vos besoins. Il semble que vous compreniez mal comment utiliser node_modules...

Si vous êtes familier avec NuGet , vous devriez penser à npm comme contrepartie côté client. Où le répertoire node_modules ressemble au répertoire bin pour NuGet . L'idée est que ce répertoire est simplement un emplacement commun pour stocker les paquets. À mon avis, il est préférable de prendre un dependency sur les paquets dont vous avez besoin, comme vous l'avez fait dans le package.json. Utilisez ensuite un programme d'exécution tel que Gulp , par exemple, pour copier les fichiers dont vous avez besoin dans l'emplacement souhaité pour wwwroot.

J'ai écrit un article de blog à propos de cela 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 appelé l'attention sur ma SO question que j'ai posée et qui a finalement répondu moi-même ici , ce qui est probablement utile.

J'ai créé un Gist qui montre le gulpfile.js à titre d'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.

5
David Pine

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

L'article est lié au fichier gulp sur GitHub où il a mis en œuvre la stratégie décrite dans l'article. Vous pouvez simplement copier et coller la plupart des contenus de gulpfile dans le vôtre, mais veillez à ajouter les packages appropriés dans package.json sous devDependencies: gulp gulp-uglify gulp-concat rimraf fusionner stream

1
Andrew Boza

J'ai trouvé un meilleur moyen de gérer les packages JS dans mon projet avec les coureurs de tâches 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 d'exécuter simplement la mise à jour de npm sans autre souci si je dois exécuter des choses gulp, si tout copié avec succès et vice versa.

La façon NPM:

  • Le minificateur JS est déjà intégré dans le noyau ASP.net. Recherchez bundleconfig.json, ce n’est donc pas un problème pour moi (ne pas compiler quelque chose de personnalisé)
  • La bonne chose à propos de NPM, c’est qu’ils ont une bonne structure de fichiers afin que je puisse toujours trouver les versions pré-compilées/minifiées des dépendances sous le noeud node_modules/module/dist.
  • J'utilise un script NPM node_modules/.hooks/{eventname} qui gère la copie/la mise à jour/la suppression du fichier Project/wwwroot/lib/module/dist/. Js. peut trouver la documentation ici https://docs.npmjs.com/misc/scripts (Je mettrai à jour le script que j'utilise pour git une fois qu'il sera plus poli) Je ne le fais pas t besoin de coureurs de tâches supplémentaires (. js outils que je n’aime pas), ce qui garde mon projet propre et simple.

La manière python:

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

1
Peter Húbek

Veuillez excuser la longueur de ce post.

Ceci est un exemple de travail utilisant ASP.NET Core version 2.5.

Il est intéressant de noter que le projet , project.json est obsolète ( voir ici ) au profit de . csproj . Un problème avec . Csproj . fichier est la grande quantité de fonctionnalités et le fait qu’il n’y ait pas d’emplacement central pour sa documentation ( voir ici ).

Une autre chose, cet exemple exécute le noyau ASP.NET dans un conteneur Docker Linux (Alpine 3.9); alors les chemins vont refléter cela. Il utilise également gulp ^ 4.0. Toutefois, avec quelques modifications, il devrait fonctionner avec les anciennes versions d’ASP.NET Core, Gulp, NodeJS et également sans Docker.

Mais voici une réponse:

gulpfile.js voir le véritable exemple de travail ici

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

Ajoutez une cible dans le fichier . Csproj . Notez que nous avons également ajouté un Watch à surveiller et à exclure si nous tirons parti de la commande 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>

Maintenant, lorsque dotnet run build est exécuté, il installera et construira également des modules de nœud.

0
b01