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:
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é.
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"]);
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 :)FileServer
, avoir StaticFiles
devrait suffire pour servir des fichiers statiques (.js, images, etc.)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
_).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)
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)
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).
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
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 .
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
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.
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
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
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
.
<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.