Cómo usar npm con ASP.NET Core

117

Estoy usando npm para administrar jQuery, Bootstrap, Font Awesome y bibliotecas de cliente similares que necesito para mi aplicación ASP.NET Core.

El enfoque que funcionó para mí comenzó agregando un archivo package.json al 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:

ingrese la descripción de la imagen aquí

Como ASP.NET Core sirve los archivos estáticos de la carpeta wwwroot, y node_modules no está allí, tuve que hacer un par de cambios para que esto funcione, el primero: agregar app.UseFileServer justo antes de app.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 el segundo, que incluye node_modules en mis publishOptions en el archivo project.json:

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

Esto funciona en mi entorno de desarrollo y también funciona cuando lo implemento en 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 vino 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 entregar estos archivos desde fuera de wwwroot.

cualquier consejo será apreciado enormemente.

Carlos Figueroa
fuente
Puede ser un enlace útil: blog.nbellocam.me/2016/03/14/asp-net-core-and-angular-2
adem caglin
Este enlace tiene un ejemplo funcional en ASP.NET Core con npm : ievangelistblog.wordpress.com/2016/01/13/…
David Pine
2
Una cosa que se me ocurrió es usar el Bundler and Minifier- Especificar que la fuente es Fuera de wwwroot y cuando lo construyes, construye el JS en wwwroot. Esa es la forma correcta ... No debería servir contenido de node_modules
Piotr Kula
Yo desalentaría a cualquiera de servir estáticamente la node_modulescarpeta. a) no es así como está diseñado el ecosistema b) es un riesgo de seguridad, uno de sus paquetes instalados podría filtrar información confidencial. La forma correcta es configurar una canalización de construcción (grunt / gulp / node / webpack) que publique archivos en una carpeta srco whateverdedicada a servir archivos frontales estáticos
CervEd

Respuestas:

45

Publicando todo tu node_modules carpeta , está implementando muchos más archivos de los que realmente necesitará en producción.

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

A continuación, también puede eliminar completamente el FileServer configuración y confiar en ella UseStaticFiles.

Actualmente, gulp es el corredor de tareas VS preferido. Agrega ungulpfile.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 scriptssección a su project.json:

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

Que funcionaría con el siguiente gulpfile (el predeterminado cuando se hace un andamio con 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"]);
Calcetín
fuente
36
Estoy un poco confundido sobre cómo esta es la respuesta a la pregunta. Esto es casi exactamente lo que Microsoft tiene para configurar Gulp aquí ( docs.microsoft.com/en-us/aspnet/core/client-side/using-gulp ). Sin embargo, por lo que puedo decir, esto no toma contenido de mi directorio node_modules y lo agrega a 'lib' o lo hace utilizable en cualquiera de mis archivos ... Soy muy nuevo en esto, tan increíblemente confundido por lo aparentemente increíble complicado nuevo mundo del desarrollo web ...
Gerard Wilkinson
32
Complicado bien. Estoy listo para abandonar el front-end por completo y simplemente trabajar en API.
Luke Puplett
12
Este es el enfoque correcto en general, pero la respuesta omite un paso crucial: copiar los archivos de la carpeta node_modules en la carpeta wwwroot como una tarea de Gulp. Comience con var nodeRoot = './node_modules/'; y agregue una tarea que copie la subcarpeta deseada de nodeRoot en la subcarpeta correspondiente de webroot. No hay tiempo ahora para dar más detalles, pero si hay interés, puedo agregar detalles más adelante.
Doug
32
¿Por qué nadie ha planteado lo obvio: "¿Por qué tenemos que hacer esta pregunta?" ¿Por qué instalamos archivos intencionalmente en una ubicación donde no se pueden usar? Luego, debido a que nuestros archivos no son accesibles, instalamos y configuramos una elaborada utilidad para copiarlos a una ubicación donde se puedan usar. Es realmente ridículo.
Sam
8
Porque las herramientas aquí son una mierda, básicamente. Usar npm es simplemente usar npm, tal como lo haría con cualquier cosa . No hay nada específico para ASP.NET Core. Todo entra node_modulesporque eso es lo que hace npm. La tarea de tragar es necesaria para mover las cosas al lugar correcto, es decir, donde realmente las necesita. Creo que el problema es que Microsoft proporcionó una integración tan hermosa con Bower, pero ahora Bower está muerto (o al menos muriendo) y Microsoft no ha proporcionado ninguna herramienta alternativa.
Chris Pratt
41

ingrese la descripción de la imagen aquí

  • Usar npmpara administrar bibliotecas del lado del cliente es una buena opción (a diferencia de Bower o NuGet), está pensando en la dirección correcta :)
  • Divida los proyectos del lado del servidor (ASP.NET Core) y del lado del cliente (por ejemplo, Angular 2, Ember, React) en carpetas separadas (de lo contrario, su proyecto ASP.NET puede tener mucho ruido: pruebas unitarias para el código del lado del cliente, node_modules carpeta, construir artefactos, etc.). Los desarrolladores front-end que trabajan en el mismo equipo que usted se lo agradecerán :)
  • Restaure los módulos npm en el nivel de la solución (de manera similar a cómo restaura paquetes a través de NuGet, no en la carpeta del proyecto), de esta manera también puede tener pruebas unitarias y de integración en una carpeta separada (en lugar de tener pruebas de JavaScript del lado del cliente dentro de su Proyecto ASP.NET Core).
  • El uso puede no ser necesario FileServer, teniendoStaticFiles 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 fragmentos (paquetes)
  • Es posible que no necesite Gulp / Grunt si está utilizando un paquete de módulos como Webpack
  • Escriba scripts de automatización de compilación en ES2015 + JavaScript (a diferencia de Bash o PowerShell), funcionarán en varias plataformas y serán más accesibles para una variedad de desarrolladores web (todos hablan JavaScript hoy en día)
  • Cambie el nombre wwwroota public, de lo contrario, la estructura de carpetas en Azure Web Apps será confusa ( D:\Home\site\wwwroot\wwwrootvs D:\Home\site\wwwroot\public)
  • Publique solo la salida compilada en Azure Web Apps (nunca debe enviarla node_modulesa un servidor de alojamiento web). Vea tools/deploy.jscomo ejemplo.

Visite ASP.NET Core Starter Kit en GitHub (descargo de responsabilidad: soy el autor)

Konstantin Tarkus
fuente
2
Buena respuesta, felicitaciones por su trabajo para proporcionar a la comunidad un kit de inicio.
David Pine
7
Construí con éxito una gran aplicación pública Angular para una importante marca del Reino Unido a principios de este año y, sin embargo, ni siquiera podía entender la mayor parte de esta respuesta. Ni siquiera puedo empezar a aprenderlo porque está por todos lados. Literalmente teniendo una crisis profesional.
Luke Puplett
Este es un buen resumen de lo que se debe y no se debe hacer al escribir y administrar archivos y scripts del lado del cliente. Ahorré tiempo e investigación. ¡Felicitaciones a usted!
Sangeeta
Desafortunadamente, Visual Studio (estúpidamente en mi humilde opinión) trata el directorio "wwwroot" de forma especial, basándose solo en su nombre, dándole un icono especial de "raíz web" en el explorador de soluciones y marcando su contenido como "Ninguno" de forma predeterminada en lugar de "Contenido". . Si la intención es colocar archivos servidos estáticamente allí y está utilizando Visual Studio, probablemente debería dejar el nombre como "wwwroot". Aunque estoy de acuerdo en que es un mal nombre.
Jez
27

Instalar el Bundler y Minifier en Extensiones de Visual Studio

Luego crea un bundleconfig.jsone 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
  }
]

Por lo tanto, el empaquetador y el minificador (basado en gulp) tiene acceso a los archivos de origen (que deben excluirse de Visual Studio y también de GIT) y los coloca en wwwroot como se especifica

solo el efecto secundario cada vez que lo guarde ejecutará esto (pero puede configurarlo para que lo ejecute manualmente)

Piotr Kula
fuente
4
Después de ver que Bower está muerto y ya no puedo actualizar Bootstrap sin cambiar a NPM, este parece ser mi enfoque favorito. Gulp o Webpack parecen excesivos en comparación con esta sencilla solución que ya se encuentra en las últimas plantillas de proyectos MVC. ¡Gracias por compartir!
Matt Sanders
1
¿Cómo se manejan aquí las imágenes referenciadas en css? Estoy enfrentando un problema con las imágenes que aún están en la carpeta node_modules donde css y js se movieron a www. Algúna idea de cómo arreglar esto ?
VPP
1
¿Es esto independiente del IDE? ¿Cómo funcionará esto si algunos miembros de su equipo están usando VS Code, y cómo se integra en una canalización de compilación de CD?
Jacob Stamm
Cuando instala el paquete Bundler and Minifier NuGet, los documentos dicen que inyecta objetivos de compilación que se ejecutan en el momento de compilación y limpieza. Supongo que una vez que esté en su lugar, funcionará bien independientemente del IDE que se use, ¿verdad? Ver más: docs.microsoft.com/en-gb/aspnet/core/client-side/…
Ciaran Gallagher
El empaquetado solo es útil para especificar estos scripts fuera del entorno de desarrollo. Desde mi página _Layout, todavía tengo que hacer referencia manualmente a los archivos JS y CSS que necesito, pero la carpeta node_modules está fuera del sitio web ... así que no creo que esto resuelva el problema correctamente, aún necesita un script de Gulp para copiar sobre los archivos necesarios en mi carpeta wwwroot.
Ciaran Gallagher
21

Te doy dos respuestas. npm combinado con otras herramientas es poderoso pero requiere algo de trabajo para configurarlo. Si solo desea descargar algunas bibliotecas, es posible que desee utilizar el Administrador de bibliotecas lugar (lanzado en Visual Studio 15.8).

NPM (avanzado)

Primero agregue package.json en la raíz de su proyecto. Agrega 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 proyecto principal de asp.net en una carpeta llamada node_modules. El siguiente paso es copiar los archivos en un lugar apropiado. Para hacer esto usaremos gulp, que también fue descargado por NPM. Luego agregue un nuevo archivo en la raíz de su proyecto llamado gulpfile.js . Agrega 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 el proyecto se crea y se limpia. Copiará todos los archivos necesarios en lib2 ( no lib; puede cambiarlo fácilmente ). He usado la misma estructura que en un proyecto nuevo, pero es fácil cambiar archivos a una ubicación diferente. Si mueve los archivos, asegúrese de actualizar también _Layout.cshtml . Tenga en cuenta que todos los archivos del 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 minificar archivos JavaScript y CSS:

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

Administrador de biblioteca (simple)

Haga clic con el botón derecho en su proyecto y seleccione Administrar bibliotecas del lado del cliente . El archivo libman.json ahora está abierto. En este archivo, especifica qué biblioteca y archivos usar y dónde deben almacenarse localmente. ¡Realmente simple! El siguiente archivo copia las bibliotecas predeterminadas que se usan al crear un nuevo proyecto 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 mueve los archivos, asegúrese de actualizar también _Layout.cshtml .

PEK
fuente
2
Gerente de biblioteca: nunca he oído hablar de él, ¡pero es exactamente lo que necesito! Esta debería ser la respuesta correcta.
CodeMonkey
1
Para evitar un error de trago que tenía que cambiar la primera línea de la tarea por defecto en el archivo gulpfile.jsde gulp.task('default', function (done) {y luego añadir como última línea en esa función la siguiente: done();De lo contrario me gustaría conseguir el mensaje de errorThe following tasks did not complete: Did you forget to signal async completion?
Manfred
7

En lugar de intentar servir la carpeta de módulos de nodo, 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, la tarea Gulp no copia archivos de node_modules

Dave_750
fuente
4
Realmente me gusta el segundo enlace, parece familiar de alguna manera. ;)
David Pine
1
No es muy conveniente cuando mezcla archivos fuente de la aplicación web ASP.NET Core con módulos npm y salida de compilación de código del lado del cliente. Esa es la razón por la que el equipo de ASP.NET está eliminando Gulp, package.json de las plantillas de proyecto ASP.NET MVC predeterminadas.
Konstantin Tarkus
No sabía eso. Cuando estuve en VS Live en marzo, todos estaban de acuerdo, pero ha cambiado mucho desde entonces.
Dave_750
6

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

Hay muchos enfoques "correctos", solo tiene que decidir cuál se adapta mejor a sus necesidades. Parece que no está entendiendo cómo usar node_modules...

Si está familiarizado con NuGet , debería pensar en npm como su contraparte del lado del cliente. Donde el node_modulesdirectorio es como el bindirectorio de NuGet . La idea es que este directorio sea solo una ubicación común para almacenar paquetes, en mi opinión es mejor tomar dependencylos paquetes que necesita como lo ha hecho en el package.json. Luego use un corredor de tareas como, Gulppor ejemplo, para copiar los archivos que necesita en la wwwrootubicación deseada .

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

Creé un Gistque muestra gulpfile.jscomo ejemplo.

En su Startup.cssigue siendo importante utilizar archivos estáticos:

app.UseStaticFiles();

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

David Pine
fuente
3
"Escribí una publicación de blog sobre esto en enero que detalla npm, Gulp y un montón de otros detalles que aún son relevantes hoy". el hecho de que de enero a junio y que tengas que mencionar sigue siendo relevante es exactamente mi problema con molestarme en aprender cualquiera de estas cosas de la noche a la mañana. Ya tengo mucho que aprender sin perder el tiempo en modas. No es tu culpa David, estás siendo muy útil, pero no me gusta este nuevo mundo efímero.
Luke Puplett
5

Un enfoque mucho más simple es usar el paquete OdeToCode.UseNodeModules Nuget. Lo acabo de probar con .Net Core 3.0. Todo lo que necesita hacer es agregar el paquete a la solución y hacer referencia a él en el método Configure de la clase Startup:

app.UseNodeModules();

Lo aprendí del excelente curso Creación de una aplicación web con ASP.NET Core, MVC, Entity Framework Core, Bootstrap y Angular Pluralsight de Shawn Wildermuth.

Mariusz Bialobrzeski
fuente
1
¿Y cómo agregas paquetes npm?
Luca Ziegler
Hay varias formas de agregar paquetes npm a su proyecto. Prefiero simplemente escribirlos en el archivo package.json en el nodo de dependencias como se explica aquí: stackoverflow.com/a/49264424/5301317
Mariusz Bialobrzeski
@MariuszBialobrzeski Gracias por compartir. Esta es una buena solución.
Sau001
@MariuszBialobrzeski ¿Tuvo que hacer algo adicional para implementar el contenido estático de node_modules en sus canalizaciones de DevOps? ¿O buscaste en la carpeta node_modules?
Sau001
1
@ Sau001 Lamentablemente, nunca tuve la oportunidad de trabajar con canalizaciones de DevOps. La carpeta node_modules tiende a ser bastante grande, por lo que definitivamente evitaría registrarla si es posible.
Mariusz Bialobrzeski
1

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 archivo gulp en GitHub donde implementó la estrategia en el artículo. Puede copiar y pegar la mayor parte del contenido del archivo gulp en el suyo, pero asegúrese de agregar los paquetes apropiados en package.json en devDependencies: gulp gulp-uglify gulp-concat rimraf merge-stream

Andrés Boza
fuente
1

Encontré una mejor manera de administrar los paquetes JS en mi proyecto con los corredores de tareas NPM Gulp / Grunt. 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 si necesito ejecutar gulp. si copió todo con éxito y viceversa.

La forma NPM:

  • El minificador JS ya está incluido en el núcleo de ASP.net, busque bundleconfig.json para que esto no sea un problema para mí (no compilar algo personalizado)
  • Lo bueno de NPM es que tiene una buena estructura de archivos, por lo que siempre puedo encontrar las versiones precompiladas / minificadas de las dependencias en node_modules / module / dist
  • Estoy usando un script de NPM node_modules / .hooks / {eventname} que está manejando la copia / actualización / eliminación de los archivos Project / wwwroot / lib / module / dist / .js, 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 necesita mantener las fuentes manualmente

Peter Húbek
fuente
1

Disculpe la longitud de esta publicación.

Este es un ejemplo funcional con ASP.NET Core versión 2.5.

Algo a destacar es que project.json está obsoleto ( ver aquí ) a favor de .csproj . Un problema con .csproj . archivo es la gran cantidad de funciones y el hecho de que no hay una ubicación central para su documentación ( ver aquí ).

Una cosa más, este ejemplo es ejecutar ASP.NET core en un contenedor Docker Linux (alpine 3.9); para que los caminos reflejen eso. También usa gulp ^ 4.0. Sin embargo, con algunas modificaciones, debería funcionar con versiones anteriores de ASP.NET Core, Gulp, NodeJS y también sin Docker.

Pero aquí tienes una respuesta:

gulpfile.js vea el ejemplo de trabajo real aquí

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

Agregue un destino en el archivo .csproj . Tenga en cuenta que también agregamos un reloj para ver y excluir si aprovechamosdotnet run watch comando.

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>

Ahora, cuando dotnet run buildse ejecute, también instalará y creará módulos de nodo.

b01
fuente