Cómo usar npm con ASP.NET Básica


Estoy usando npm para administrar las bibliotecas de clientes jQuery, Bootstrap, Font Awesome y similares que necesito para mi ASP.NET Aplicación principal.

El enfoque que funcionó para mí comenzó agregando un paquete.archivo json para el proyecto, que se ve así:

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

Npm restaura estos paquetes en la carpeta node_modules que está en el mismo nivel que wwwroot en el directorio del proyecto:

introduzca la descripción de la imagen aquí

As ASP.NET Core sirve los archivos estáticos del wwwroot carpeta, y node_modules no está allí, tuve que hacer un par de cambios para que esto funcione, el primero: agregar aplicación.UseFileServer justo antes de la aplicación.UseStaticFiles en mi Startup.archivo cs:

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

app.UseStaticFiles();

Y la segunda, incluyendo node_modules en mis publishOptions en el proyecto.archivo json:

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

Esto funciona en mi entorno de desarrollo y también funciona cuando lo despliego a mi instancia de Azure App Service, los archivos estáticos jquery, bootstrap y font-awesome se sirven bien, pero No estoy seguro de esta implementación.

¿Cuál es el enfoque correcto para hacer esto?

Esta solución se produjo después de recopilar muchos bits de información de varias fuentes y probar algunos que no funcionaron, y parece un poco extraño tener que servir estos archivos desde fuera de wwwroot.

Cualquier consejo será muy apreciado.

Author: Carlos Figueroa, 2016-06-21

8 answers

Al publicar toda su carpeta node_modules está desplegando muchos más archivos de los que realmente necesitará en producción.

En su lugar, use un ejecutor de tareas como parte de su proceso de compilación para empaquetar los archivos que necesita e implementarlos en su carpeta wwwroot. Esto también le permitirá concat y minificar sus activos al mismo tiempo, en lugar de tener que servir a cada biblioteca individual por separado.

También puede eliminar completamente la configuración FileServer y confiar en UseStaticFiles en su lugar.

Actualmente, gulp es el corredor de tareas VS de elección. Agregue un gulpfile.js a la raíz de su proyecto y configúrelo para procesar sus archivos estáticos al publicar.

Por ejemplo, puede agregar la siguiente sección scripts a su project.json:

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

Que funcionaría con el siguiente gulpfile (el valor predeterminado cuando se 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"]);
 28
Author: Sock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-18 21:56:07

introduzca la descripción de la imagen aquí

  • Usar npm para administrar bibliotecas del lado del cliente es una buena opción (a diferencia de Bower o NuGet), estás pensando en la dirección correcta:)
  • Dividir el lado del servidor (ASP.NET Core) y del lado del cliente (por ejemplo, Angular 2, Ember, React) proyectos en carpetas separadas (de lo contrario su ASP.NET el proyecto puede tener muchas pruebas de unidad de ruido para el código del lado del cliente, la carpeta node_modules, los artefactos de construcción, etc.). Desarrolladores Front-end trabajando en el mismo equipo con te lo agradecerás:)
  • Restore los módulos npm a nivel de solución (de manera similar, cómo restaura los paquetes a través de NuGet, no en la carpeta del proyecto), de esta manera puede tener pruebas de unidad e integración en una carpeta separada también (en lugar de tener pruebas JavaScript del lado del cliente dentro de su ASP.NET Core project).
  • El uso podría no necesitar FileServer, tener StaticFiles debería ser suficiente para servir archivos estáticos (.js, imágenes, etc.)
  • Utilice Webpack para agrupar su código del lado del cliente en uno o más trozos (paquetes)
  • Es posible que no necesite Gulp / Grunt si está utilizando un paquete de módulos como Webpack
  • Escribir scripts de automatización de compilación en ES2015 + JavaScript (a diferencia de Bash o PowerShell), funcionarán multiplataforma y serán más accesibles para una variedad de desarrolladores web (todo el mundo habla JavaScript hoy en día)
  • Cambie el nombre de wwwroot a public, de lo contrario, la estructura de carpetas en Azure Web Apps será confusa (D:\Home\site\wwwroot\wwwroot vs D:\Home\site\wwwroot\public)
  • Publicar solo la salida compilada a Azure Web Apps (nunca debe enviar node_modules a un servidor de alojamiento web). Véase tools/deploy.js como ejemplo.

Visita ASP.NET Kit de Inicio de Núcleo en GitHub (descargo de responsabilidad: Soy el autor)

 35
Author: Konstantin Tarkus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-23 01:38:22

Instale el Bundler y Minifier en las extensiones de Visual Studio

Luego crea un bundleconfig.json e ingresa lo siguiente como:

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

Así que el bundler y minifier (basado en gulp) tiene acceso a los archivos fuente (que deben excluirse de Visual Studio y también excluidos de GIT) y los coloca en el wwwroot como se especifica

Solo el efecto secundario cada vez que lo guardes ejecutará esto (o puedes configurarlo o ejecutarlo manualmente)

 21
Author: ppumkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 21:46:55

En lugar de intentar servir la carpeta node modules, también puede usar Gulp para copiar lo que necesita en wwwroot.

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

Esto también podría ayudar

Visual Studio 2015 ASP.NET 5, Gulp tarea no copiar archivos desde node_modules

 7
Author: Dave_750,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:31

¿Cuál es el enfoque correcto para hacer esto?

Hay muchos enfoques "correctos", solo tienes que decidir cuál se adapta mejor a tus necesidades. Parece que estás malinterpretando cómo usar node_modules...

Si está familiarizado con NuGet debe pensar en npm como su contraparte del lado del cliente. Donde el directorio node_modules es como el directorio binpara NuGet. La idea es que este directorio es solo una ubicación común para almacenar paquetes, en mi opinión es mejor tomar un dependency en los paquetes que necesita como lo ha hecho en el package.json. A continuación, utilice un corredor de tareas como Gulp por ejemplo, para copiar los archivos que necesita en su ubicación deseada wwwroot.

Escribí una entrada de blog sobre esto en enero que detalla npm, Gulp y un montón de otros detalles que siguen siendo relevantes hoy en día. Además, alguien llamó la atención sobre mi pregunta que hice y finalmente me respondí aquí, lo cual es probablemente útil.

He creado un Gist eso muestra el gulpfile.js como un ejemplo.

En su Startup.cs todavía es importante utilizar archivos estáticos:

app.UseStaticFiles();

Esto asegurará que su aplicación pueda acceder a lo que necesita.

 5
Author: David Pine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:14

Les doy dos respuestas. npm combinado con otras herramientas es potente pero requiere algo de trabajo para configurarlo. Si solo desea descargar algunas bibliotecas, es posible que desee usar Library Manager en su lugar (publicado en Visual Studio 15.8).

NPM (Avanzado)

Primero agregue paquete.json en la raíz de su proyecto. Agregue el siguiente contenido:

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

Esto hará que NPM descargue Bootstrap, jQuery y otras bibliotecas que se utilizan en un nuevo asp.net básica proyecto a una carpeta llamada node_modules. El siguiente paso es copiar los archivos a un lugar apropiado. Para ello utilizaremos gulp, que también fue descargado por NPM. Luego agregue un nuevo archivo en la raíz de su proyecto llamado gulpfile.js . Agregue el siguiente contenido:

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

Este archivo contiene un código JavaScript que se ejecuta cuando se construye y limpia el proyecto. Copiará todos los archivos necesarios a lib2 (no lib - puede cambiar esto fácilmente ). He usado el mismo estructura como en un nuevo proyecto, pero es fácil cambiar archivos a una ubicación diferente. Si mueve los archivos, asegúrese también de actualizar _Layout.cshtml . Tenga en cuenta que todos los archivos en el directorio lib2 se eliminarán cuando se limpie el proyecto.

Si hace clic derecho en gulpfile.js, puede seleccionar Task Runner Explorer. Desde aquí puede ejecutar gulp manualmente para copiar o limpiar archivos.

Gulp también podría ser útil para otras tareas como minify JavaScript y Archivos CSS:

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

Administrador de biblioteca (Simple)

Haga clic derecho en su proyecto y seleccione Administrar bibliotecas del lado del cliente. El archivo libman.json ya está abierto. En este archivo se especifica qué biblioteca y archivos usar y dónde deben almacenarse localmente. Muy simple! El siguiente archivo copia las bibliotecas predeterminadas que se utilizan al crear una nueva ASP.NET Básica 2.1 proyecto:

{
  "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 mueve los archivos, asegúrese de actualizar también _Layout.cshtml .

 3
Author: PEK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-16 05:26:01

Shawn Wildermuth tiene una buena guía aquí: https://wildermuth.com/2017/11/19/ASP-NET-Core-2-0-and-the-End-of-Bower

El artículo enlaza con el gulpfile en GitHub donde ha implementado la estrategia en el artículo. Puede copiar y pegar la mayoría del contenido de gulpfile en el suyo, pero asegúrese de agregar los paquetes apropiados en el paquete.json bajo devDependencies: trago gulp-uglify gulp-concat rimraf merge-stream

 1
Author: Andrew Boza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 23:29:38

He encontrado una mejor manera de gestionar paquetes JS en mi proyecto con NPM Gulp/Grunt task runners. No me gusta la idea de tener un NPM con otra capa de biblioteca javascript para manejar la "automatización", y mi requisito número uno es simplemente ejecutar la actualización npm sin ninguna otra preocupación acerca de si necesito ejecutar cosas gulp, si se copió con éxito todo y viceversa.

La manera NPM:

  • El minificador JS ya está incluido en el ASP.net básica, busca bundleconfig.json así que esto no es un problema para mí (no compilar algo personalizado)
  • Lo bueno de NPM es que tiene una buena estructura de archivos para que siempre pueda encontrar las versiones precompiladas / minificadas de las dependencias bajo el node_modules / module / dist
  • Estoy usando un NPM node_modules/.hooks / {eventname} script que está manejando la copia / actualización / eliminación de la Project / wwwroot/lib/module/dist / .js archivos, usted puede encontrar la documentación aquí https://docs.npmjs.com/misc/scripts (Actualizaré el script que estoy usando para git una vez que esté más pulido) No necesito corredores de tareas adicionales (.herramientas js que no me gustan) lo que mantiene mi proyecto limpio y simple.

La forma de python:

Https://pypi.python.org/pyp } pero en este caso es necesario mantener las fuentes manualmente

 1
Author: Peter Húbek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 17:34:26