Como usar o npm com ASP.NET Core

118

Estou usando o npm para gerenciar jQuery, Bootstrap, Font Awesome e bibliotecas de cliente semelhantes de que preciso para meu aplicativo ASP.NET Core.

A abordagem que funcionou para mim começou adicionando um arquivo package.json ao projeto, que se parece com isto:

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

O npm restaura esses pacotes na pasta node_modules que está no mesmo nível que wwwroot no diretório do projeto:

insira a descrição da imagem aqui

Como o ASP.NET Core fornece os arquivos estáticos da pasta wwwroot e node_modules não está lá, eu tive que fazer algumas alterações para fazer isso funcionar, a primeira: adicionar app.UseFileServer logo antes de app.UseStaticFiles em minha inicialização. arquivo cs:

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

app.UseStaticFiles();

e o segundo, incluindo node_modules em my publishOptions no arquivo project.json:

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

Isso funciona em meu ambiente de desenvolvimento e também funciona quando eu o implanto em minha instância do Azure App Service, os arquivos estáticos jquery, bootstrap e font-awesome são servidos bem, mas não tenho certeza sobre essa implementação.

Qual é a abordagem certa para fazer isso?

Esta solução veio depois de coletar muitas informações de várias fontes e tentar algumas que não funcionaram, e parece um pouco estranho ter que servir esses arquivos de fora do wwwroot.

Qualquer conselho será bem-vindo.

Carlos Figueroa
fonte
Este link tem um exemplo funcional no ASP.NET Core w / npm : ievangelistblog.wordpress.com/2016/01/13/…
David Pine
2
Uma coisa que me ocorreu foi usar o Bundler and Minifier- Especifique a fonte como Outside wwwroot e quando você construí-lo constrói o JS em wwwroot. Essa é a maneira correta. Você não deve veicular conteúdo de node_modules
Piotr Kula
Eu altamente desencorajaria qualquer um de servir a node_modulespasta estaticamente . a) não é assim que o ecossistema foi projetado b) é um risco de segurança, um de seus pacotes instalados pode vazar informações confidenciais. A maneira adequada é configurar um pipeline de construção (grunt / gulp / node / webpack) que publica arquivos em uma pasta srcou whateverdedicada a servir arquivos de front-end estáticos
CervEd

Respostas:

45

Ao publicar sua node_modulespasta inteira, você está implantando muito mais arquivos do que realmente precisa na produção.

Em vez disso, use um executor de tarefa como parte de seu processo de construção para empacotar os arquivos de que você precisa e implantá-los em sua wwwrootpasta. Isso também permitirá que você concatene e reduza seus recursos ao mesmo tempo, em vez de ter que servir cada biblioteca individual separadamente.

Você também pode remover completamente a FileServerconfiguração e confiar UseStaticFilesnela.

Atualmente, o gulp é o executor de tarefas do VS preferido. Adicione um gulpfile.jsà raiz do seu projeto e configure-o para processar seus arquivos estáticos na publicação.

Por exemplo, você pode adicionar a seguinte scriptsseção ao seu project.json:

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

Que funcionaria com o seguinte gulpfile (o padrão ao usar scaffolding 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"]);
Meia
fonte
36
Estou um pouco confuso sobre como essa é a resposta à pergunta. Isso é quase exatamente o que a Microsoft tem para configurar o Gulp aqui ( docs.microsoft.com/en-us/aspnet/core/client-side/using-gulp ). No entanto, pelo que eu posso dizer, isso não pega o conteúdo do meu diretório node_modules e o adiciona a 'lib' ou o torna utilizável em qualquer um dos meus arquivos ... Eu sou muito novo nisso, tão incrivelmente confuso com o aparentemente incrivelmente Novo mundo complicado de Desenvolvimento Web ...
Gerard Wilkinson
33
Complicado tudo bem. Estou pronto para abandonar completamente o front-end e trabalhar apenas em APIs.
Luke Puplett
12
Essa é a abordagem certa em geral, mas a resposta deixa de fora uma etapa crucial: copiar os arquivos da pasta node_modules para a pasta wwwroot como uma tarefa Gulp. Comece com var nodeRoot = './node_modules/'; e adicione uma tarefa que copie a subpasta desejada de nodeRoot para a subpasta apropriada de webroot. Não há tempo para elaborar, mas se houver interesse, posso adicionar detalhes mais tarde.
Doug
32
Por que ninguém levantou o óbvio: "Por que temos que fazer esta pergunta!" Por que instalamos arquivos intencionalmente em um local onde eles não podem ser usados? Então, como nossos arquivos não são acessíveis, instalamos e configuramos um elaborado utilitário para copiá-los para um local onde possam ser usados. É realmente ridículo.
Sam
8
Porque o ferramental aqui é uma porcaria, basicamente. Usar o npm é apenas usar o npm, exatamente como você faria para qualquer coisa . Não há nada específico para ASP.NET Core. Tudo entra node_modulesporque é isso que o npm faz. A tarefa gulp é necessária para colocar as coisas no lugar certo, ou seja, onde você realmente precisa delas. Acho que o problema é que a Microsoft forneceu uma integração tão bonita com o Bower, mas agora o Bower está morto (ou pelo menos morrendo) e a Microsoft não forneceu nenhuma ferramenta alternativa.
Chris Pratt
41

insira a descrição da imagem aqui

  • Usar npmpara gerenciar bibliotecas do lado do cliente é uma boa escolha (ao contrário do Bower ou NuGet), você está pensando na direção certa :)
  • Divida os projetos do lado do servidor (ASP.NET Core) e do lado do cliente (por exemplo, Angular 2, Ember, React) em pastas separadas (caso contrário, seu projeto ASP.NET pode ter muito ruído - testes de unidade para o código do lado do cliente, node_modules pasta, construir artefatos etc.). Os desenvolvedores front-end trabalhando na mesma equipe que você agradecerão por isso :)
  • Restaure módulos npm no nível da solução (da mesma forma como você restaura pacotes via NuGet - não na pasta do projeto), desta forma, você pode ter testes de unidade e integração em uma pasta separada também (em oposição a ter testes de JavaScript do lado do cliente dentro de seu Projeto ASP.NET Core).
  • O uso pode não ser necessário FileServer, mas StaticFilesdeve ser suficiente para servir arquivos estáticos (.js, imagens etc.)
  • Use o Webpack para agrupar seu código do lado do cliente em um ou mais blocos (agrupamentos)
  • Você pode não precisar do Gulp / Grunt se estiver usando um empacotador de módulo como o Webpack
  • Escreva scripts de automação de compilação em ES2015 + JavaScript (em oposição a Bash ou PowerShell), eles funcionarão em várias plataformas e serão mais acessíveis a vários desenvolvedores da web (todos falam JavaScript atualmente)
  • Renomear wwwrootpara public, caso contrário, a estrutura de pastas nos Aplicativos Web do Azure será confusa ( D:\Home\site\wwwroot\wwwrootvs D:\Home\site\wwwroot\public)
  • Publique apenas a saída compilada nos Aplicativos Web do Azure (você nunca deve enviar node_modulespara um servidor de hospedagem na web). Veja tools/deploy.jscomo exemplo.

Visite ASP.NET Core Starter Kit no GitHub (isenção de responsabilidade: eu sou o autor)

Konstantin Tarkus
fonte
2
Boa resposta, parabéns pelo seu trabalho em fornecer um kit inicial à comunidade!
David Pine
7
Eu construí com sucesso um enorme aplicativo Angular público para uma grande marca do Reino Unido no início deste ano, e ainda não conseguia entender a maior parte dessa resposta. Não consigo nem começar a aprender, porque está em todo lugar. Literalmente tendo uma crise de carreira.
Luke Puplett
este é um bom resumo do que fazer e não fazer ao escrever e gerenciar scripts e arquivos do lado do cliente. Economizei meu tempo e pesquisa. Parabéns para você!
Sangeeta
Infelizmente, o Visual Studio (estupidamente IMHO) trata o diretório "wwwroot" especialmente, baseado apenas em seu nome, dando a ele um ícone especial de "raiz da web" no gerenciador de soluções e marcando seu conteúdo como "Nenhum" por padrão em vez de "Conteúdo" . Se a intenção for colocar arquivos fornecidos estaticamente lá e você estiver usando o Visual Studio, provavelmente deverá deixar o nome como "wwwroot". Eu concordo que é um nome ruim.
Jez
27

Instale o Bundler e o Minificador nas extensões do Visual Studio

Em seguida, você cria um bundleconfig.jsone insere o seguinte, 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
  }
]

Portanto, o bundler e o minificador (baseado em gulp) têm acesso aos arquivos de origem (que devem ser excluídos do Visual Studio e também do GIT) e os coloca no wwwroot conforme especificado

apenas o efeito colateral toda vez que você salvá-lo irá executá-lo (mas você pode configurá-lo para executá-lo manualmente)

Piotr Kula
fonte
4
Depois de ver que o Bower está morto e não posso mais atualizar o Bootstrap sem mudar para o NPM, essa parece ser minha abordagem favorita. Gulp ou Webpack parecem exageros em comparação com esta solução simples que já está nos modelos de projeto MVC mais recentes. Obrigado por compartilhar!
Matt Sanders
1
Como as imagens referenciadas em css são tratadas aqui? Estou enfrentando um problema com as imagens ainda na pasta node_modules, onde css e js foram movidos para www. Alguma ideia de como consertar isso?
VPP de
1
Isso é agnóstico em relação ao IDE? Como isso funcionará se algum de sua equipe estiver usando o VS Code, e como isso funciona em um pipeline de construção de CD?
Jacob Stamm
Quando você instala o pacote NuGet Bundler and Minifier, os documentos dizem que ele injeta destinos de compilação que são executados no tempo de compilação e limpeza. Suponho que, uma vez implementado, funcionará bem, independentemente de qual IDE for usada, certo? Veja mais: docs.microsoft.com/en-gb/aspnet/core/client-side/…
Ciaran Gallagher
O bundler é útil apenas para especificar esses scripts fora do ambiente de Desenvolvimento. Na minha página _Layout, ainda preciso referenciar manualmente os arquivos JS e CSS de que preciso, mas a pasta node_modules está fora do site ... então não acho que isso resolva o problema de maneira adequada, você ainda precisa de um script Gulp para copiar sobre os arquivos necessários para minha pasta wwwroot.
Ciaran Gallagher
21

Eu te dou duas respostas. O npm combinado com outras ferramentas é poderoso, mas requer algum trabalho de configuração. Se você deseja apenas baixar algumas bibliotecas, pode usar o Library Manager (lançado no Visual Studio 15.8).

NPM (avançado)

Primeiro adicione o package.json na raiz do seu projeto. Adicione o seguinte conteúdo:

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

Isso fará com que o NPM baixe Bootstrap, JQuery e outras bibliotecas usadas em um novo projeto principal asp.net para uma pasta chamada node_modules. O próximo passo é copiar os arquivos para um local apropriado. Para fazer isso, usaremos o gulp, que também foi baixado pelo NPM. Em seguida, adicione um novo arquivo na raiz do seu projeto denominado gulpfile.js . Adicione o seguinte conteúdo:

/// <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 arquivo contém um código JavaScript que é executado quando o projeto é construído e limpo. Ele irá copiar todos os arquivos necessários para lib2 ( não lib - você pode facilmente alterar isso ). Usei a mesma estrutura de um novo projeto, mas é fácil mudar os arquivos para um local diferente. Se você mover os arquivos, certifique-se de atualizar também _Layout.cshtml . Observe que todos os arquivos no diretório lib2 serão removidos quando o projeto for limpo.

Se você clicar com o botão direito do mouse em gulpfile.js , poderá selecionar Task Runner Explorer . A partir daqui, você pode executar o gulp manualmente para copiar ou limpar arquivos.

O Gulp também pode ser útil para outras tarefas, como reduzir arquivos JavaScript e CSS:

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

Gerenciador de biblioteca (simples)

Clique com o botão direito em seu projeto e selecione Gerenciar bibliotecas do lado do cliente . O arquivo libman.json agora está aberto. Neste arquivo, você especifica qual biblioteca e arquivos usar e onde devem ser armazenados localmente. Muito simples! O arquivo a seguir copia as bibliotecas padrão usadas ao criar um novo projeto 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"
    }
  ]
}

Se você mover os arquivos, certifique-se de atualizar também _Layout.cshtml .

PEK
fonte
2
Gerenciador de biblioteca - nunca ouvi falar, mas é exatamente o que eu preciso! Esta deve ser a resposta correta.
codeMonkey de
1
Para evitar um erro gole eu tive que mudar a primeira linha da tarefa padrão no arquivo gulpfile.jspara gulp.task('default', function (done) {e, em seguida, adicionar como uma última linha nessa função o seguinte: done();Caso contrário, eu iria receber a mensagem de erroThe following tasks did not complete: Did you forget to signal async completion?
Manfred
7

Em vez de tentar servir a pasta de módulos de nó, você também pode usar o Gulp para copiar o que você precisa para wwwroot.

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

Isso pode ajudar também

Visual Studio 2015 ASP.NET 5, tarefa Gulp não copiando arquivos de node_modules

Dave_750
fonte
4
Gosto muito do segundo link, parece familiar de alguma forma. ;)
David Pine
1
Não é muito conveniente quando você mistura arquivos de origem do aplicativo Web ASP.NET Core com módulos npm e saída de compilação de código do lado do cliente. Essa é a razão pela qual a equipe ASP.NET está removendo Gulp, package.json dos modelos de projeto padrão ASP.NET MVC.
Konstantin Tarkus
Eu não sabia disso. Quando estive no VS Live em março, eles falavam muito sobre isso, mas mudou muito desde então.
Dave_750
6

Qual é a abordagem certa para fazer isso?

Existem várias abordagens "certas", você apenas precisa decidir qual delas atende melhor às suas necessidades. Parece que você está entendendo mal como usar node_modules...

Se você está familiarizado com o NuGet, deve pensar no npm como sua contraparte do lado do cliente. Onde o node_modulesdiretório é como o bindiretório do NuGet . A ideia é que este diretório seja apenas um local comum para armazenar pacotes, na minha opinião é melhor pegar um dependencynos pacotes que você precisa como fez no package.json. Em seguida, use um executor de tarefas, Gulppor exemplo, para copiar os arquivos que você precisa para o wwwrootlocal desejado .

Eu escrevi uma postagem no blog sobre isso em janeiro que detalha npm , Gulp e um monte de outros detalhes que ainda são relevantes hoje. Além disso, alguém chamou a atenção para minha pergunta de SO que fiz e, no final das contas, me respondeu aqui , o que provavelmente é útil.

Criei um Gistque mostra o gulpfile.jscomo exemplo.

No seu Startup.csainda é importante usar arquivos estáticos:

app.UseStaticFiles();

Isso garantirá que seu aplicativo possa acessar o que precisa.

David Pine
fonte
3
"Eu escrevi uma postagem no blog sobre isso em janeiro que detalha npm, Gulp e um monte de outros detalhes que ainda são relevantes hoje." o fato de que de janeiro a junho, e você tem que mencionar, ainda está sendo relevante é exatamente o meu problema em me preocupar em aprender qualquer dessas coisas passageiras. Já tenho muito que aprender sem perder meu tempo com modas. Não é sua culpa, David, você está sendo muito prestativo, mas não gosto desse novo mundo efêmero.
Luke Puplett
5

Uma abordagem muito mais simples é usar o pacote OdeToCode.UseNodeModules Nuget. Acabei de testá-lo com .Net Core 3.0. Tudo que você precisa fazer é adicionar o pacote à solução e referenciá-lo no método Configure da classe Startup:

app.UseNodeModules();

Aprendi sobre isso no excelente curso Construindo um aplicativo da Web com ASP.NET Core, MVC, Entity Framework Core, Bootstrap e Angular Pluralsight de Shawn Wildermuth.

Mariusz Bialobrzeski
fonte
1
E como você adiciona pacotes npm?
Luca Ziegler de
Existem várias maneiras de adicionar pacotes npm ao seu projeto. Prefiro apenas digitá-los no arquivo package.json no nó de dependências, conforme explicado aqui: stackoverflow.com/a/49264424/5301317
Mariusz Bialobrzeski
@MariuszBialobrzeski Obrigado por compartilhar. Esta é uma solução bacana.
Sau001
@MariuszBialobrzeski Você teve que fazer algo adicional para implantar o conteúdo estático de node_modules em seus pipelines DevOps? Ou você verificou a pasta node_modules?
Sau001
1
@ Sau001 Infelizmente, nunca tive a oportunidade de trabalhar com pipelines DevOps. A pasta node_modules tende a ficar muito grande, então eu definitivamente evitaria fazer o check-in, se possível.
Mariusz Bialobrzeski
1

Shawn Wildermuth tem um bom guia aqui: https://wildermuth.com/2017/11/19/ASP-NET-Core-2-0-and-the-End-of-Bower

O artigo está vinculado ao gulpfile no GitHub, onde ele implementou a estratégia do artigo. Você poderia simplesmente copiar e colar a maior parte do conteúdo do gulpfile no seu, mas certifique-se de adicionar os pacotes apropriados em package.json em devDependencies: gulp gulp-uglify gulp-concat rimraf merge-stream

Andrew Boza
fonte
1

Descobri uma maneira melhor de gerenciar pacotes JS em meu projeto com os executores de tarefas Gulp / Grunt do NPM. Não gosto da ideia de ter um NPM com outra camada de biblioteca javascript para lidar com a "automação", e meu requisito número um é simplesmente executar a atualização do npm sem nenhuma outra preocupação sobre se preciso executar gulp stuff, se copiou tudo com sucesso e vice-versa.

O jeito NPM:

  • O minificador JS já está empacotado no núcleo ASP.net, procure por bundleconfig.json, então isso não é um problema para mim (não compilando algo personalizado)
  • A coisa boa sobre o NPM é que ele tem uma boa estrutura de arquivos, então posso sempre encontrar as versões pré-compiladas / minimizadas das dependências em node_modules / module / dist
  • Estou usando um script NPM node_modules / .hooks / {eventname} que está lidando com a cópia / atualização / exclusão dos arquivos Project / wwwroot / lib / module / dist / .js. Você pode encontrar a documentação aqui https: // docs.npmjs.com/misc/scripts (atualizarei o script que estou usando para o git assim que estiver mais polido) Não preciso de executores de tarefas adicionais ( ferramentas .js das quais não gosto) o que mantém meu projeto limpo e simples.

O jeito python:

https://pypi.python.org/pyp ... mas, neste caso, você precisa manter as fontes manualmente

Peter Húbek
fonte
1

Por favor, desculpe a extensão desta postagem.

Este é um exemplo prático usando o ASP.NET Core versão 2.5.

Algo digno de nota é que o project.json está obsoleto ( veja aqui ) em favor do .csproj . Um problema com .csproj . arquivo é a grande quantidade de recursos e o fato de não haver um local central para sua documentação ( veja aqui ).

Mais uma coisa, este exemplo está executando o ASP.NET core em um contêiner Docker Linux (alpine 3.9); então os caminhos irão refletir isso. Ele também usa gulp ^ 4.0. No entanto, com algumas modificações, ele deve funcionar com versões mais antigas do ASP.NET Core, Gulp, NodeJS e também sem Docker.

Mas aqui está uma resposta:

gulpfile.js veja o verdadeiro exemplo de trabalho aqui

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

Adicione um destino no arquivo .csproj . Observe que também adicionamos um relógio para observar e excluir se aproveitarmos o dotnet run watchcomando.

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>

Agora, quando dotnet run buildfor executado, ele também instalará e construirá módulos de nó.

b01
fonte