it-swarm.com.ru

Как использовать npm с ASP.NET Core

Я использую npm для управления jQuery, Bootstrap, Font Awesome и аналогичными клиентскими библиотеками, которые нужны для моего приложения ASP.NET Core.

Подход, который работал для меня, начался с добавления файла package.json в проект, который выглядит следующим образом:

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

npm восстанавливает эти пакеты в папке node_modules, которая находится на том же уровне, что и wwwroot в каталоге проекта:

enter image description here

Поскольку ASP.NET Core обслуживает статические файлы из папки wwwroot, а node_modules там нет, мне пришлось внести несколько изменений, чтобы это сработало, первое: добавить app.UseFileServer прямо перед app.UseStaticFiles в моем автозагрузке. CS файл:

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

app.UseStaticFiles();

и второй, включая node_modules в моих publishOptions в файле project.json:

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

Это работает в моей среде разработки и также работает, когда я развертываю его в своем экземпляре службы приложений Azure, jquery, bootstrap и ​​статичные файлы с отличными шрифтами хорошо работают, но я не уверен насчет этой реализации ,.

Каков правильный подход для этого?

Это решение появилось после того, как мы собрали много информации из нескольких источников и попробовали те, которые не работали, и кажется немного странным необходимость обслуживать эти файлы извне wwwroot.

Любые советы будут с благодарностью.

95
Carlos Figueroa

Публикуя всю свою папку node_modules, вы развертываете гораздо больше файлов, чем вам потребуется на самом деле.

Вместо этого используйте средство запуска задач как часть процесса сборки, чтобы упаковать нужные вам файлы и развернуть их в папке wwwroot. Это также позволит вам объединять и минимизировать ваши активы одновременно, вместо того, чтобы обслуживать каждую отдельную библиотеку в отдельности.

Затем вы также можете полностью удалить конфигурацию FileServer и использовать вместо нее UseStaticFiles.

В настоящее время Gulp является выбранным для выполнения задач VS. Добавьте gulpfile.js в корневой каталог вашего проекта и настройте его для обработки статических файлов при публикации.

Например, вы можете добавить следующий раздел scripts к своему project.json:

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

Который будет работать со следующим gulpfile (по умолчанию, когда 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"]);
36
Sock

enter image description here

  • Использование npm для управления библиотеками на стороне клиента - хороший выбор (в отличие от Bower или NuGet), вы думаете в правильном направлении :)
  • Разделите проекты на стороне сервера (ASP.NET Core) и на стороне клиента (например, Angular 2, Ember, React) на отдельные папки (в противном случае ваш проект ASP.NET может содержать много шума - модульные тесты для код на стороне клиента, папка node_modules, артефакты сборки и т. д.). Разработчики front-end, работающие в одной команде с вами, будут вам благодарны :)
  • Восстановите модули npm на уровне решения (аналогично тому, как вы восстанавливаете пакеты через NuGet, а не в папку проекта), таким образом, вы можете иметь модульные и интеграционные тесты в отдельной папке (в отличие от клиентских JavaScript-тестов внутри вашего Проект ASP.NET Core).
  • Для использования может не потребоваться FileServer, а StaticFiles должно быть достаточно для обслуживания статических файлов (.js, изображений и т.д.)
  • Используйте Webpack для объединения кода на стороне клиента в один или несколько кусков (связок)
  • вам может не понадобиться Gulp/Grunt если вы используете пакетный модуль, такой как Webpack
  • Написание сценариев автоматизации сборки на ES2015 + JavaScript (в отличие от Bash или PowerShell), они будут работать кроссплатформенно и станут более доступными для различных веб-разработчиков (сегодня все говорят на JavaScript)
  • Переименуйте wwwroot в public, в противном случае структура папок в Azure Web Apps будет сбивать с толку (D:\Home\site\wwwroot\wwwroot vs D:\Home\site\wwwroot\public)
  • Публикуйте только скомпилированные выходные данные в веб-приложениях Azure (никогда не передавайте node_modules на сервер веб-хостинга). Смотрите tools/deploy.js в качестве примера.

Посетите ASP.NET Core Starter Kit на GitHub (отказ от ответственности: я автор)

40
Konstantin Tarkus

Установите Bundler и Minifier в расширения Visual Studio

Затем вы создаете bundleconfig.json и вводите следующее, например:

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

Таким образом, пакет и минификатор (на основе gulp) имеет доступ к исходным файлам (которые должны быть исключены из Visual Studio, а также исключены из GIT) и помещает их в wwwroot, как указано

только побочный эффект каждый раз, когда вы сохраняете, он будет запускаться (или вы можете установить его или запустить его вручную)

24
Piotr Kula

Я даю вам два ответа. npm в сочетании с другими инструментами является мощным, но требует определенной работы для установки Если вы просто хотите загрузить некоторые библиотеки, вы можете использовать менеджер библиотек вместо этого (выпущен в Visual Studio 15.8).

NPM (продвинутый уровень)

Сначала добавьте package.json в корневой каталог вашего проекта. Добавьте следующий контент:

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

Это заставит NPM загрузить Bootstrap, JQuery и другие библиотеки, которые используются в новом базовом проекте asp.net, в папку с именем node_modules. Следующим шагом является копирование файлов в соответствующее место. Для этого мы будем использовать gulp, который также был загружен NPM. Затем добавьте новый файл в корневой каталог вашего проекта с именем gulpfile.js . Добавьте следующий контент:

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

Этот файл содержит код JavaScript, который выполняется при сборке и очистке проекта. Он скопирует все необходимые файлы в lib2 (, а не в lib - вы можете легко изменить это ). Я использовал ту же структуру, что и в новом проекте, но файлы легко изменить в другое место. Если вы перемещаете файлы, убедитесь, что вы также обновили _ Layout.cshtml . Обратите внимание, что все файлы в каталоге lib2 будут удалены при очистке проекта.

Если щелкнуть правой кнопкой мыши gulpfile.js , вы можете выбрать Task Runner Explorer . Отсюда вы можете запустить gulp вручную для копирования или очистки файлов.

Gulp также может быть полезен для других задач, таких как минимизация JavaScript и CSS-файлов:

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

Диспетчер библиотек (простой)

Щелкните правой кнопкой мыши по вашему проекту и выберите Управление клиентскими библиотеками . Файл libman.json теперь открыт. В этом файле вы указываете, какую библиотеку и файлы использовать и где они должны храниться локально. Действительно просто! Следующий файл копирует библиотеки по умолчанию, которые используются при создании нового проекта 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"
    }
  ]
}

Если вы перемещаете файлы, убедитесь, что вы также обновили _ Layout.cshtml .

14
PEK

Вместо того, чтобы пытаться обслуживать папку узловых модулей, вы также можете использовать Gulp для копирования того, что вам нужно для wwwroot.

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

Это тоже может помочь

Visual Studio 2015 ASP.NET 5, задача Gulp не копирует файлы из node_modules

7
Dave_750

Каков правильный подход для этого?

Есть много "правильных" подходов, вы просто должны решить, какой из них лучше всего соответствует вашим потребностям. Похоже, вы неправильно понимаете, как использовать node_modules...

Если вы знакомы с NuGet , вы должны думать о npm как о его клиентский аналог. Где каталог node_modules похож на каталог bin для NuGet . Идея состоит в том, что этот каталог является обычным местом для хранения пакетов, на мой взгляд, лучше взять dependency для пакетов, которые вам нужны, как вы это сделали в package.json. Затем используйте средство запуска задач, например Gulp , например, чтобы скопировать нужные файлы в желаемое местоположение wwwroot.

Я написал сообщение в блоге об этом еще в январе, что детали npm , Gulp и целый ряд других деталей, которые все еще актуальны сегодня. Кроме того, кто-то обратил внимание на мой SO вопрос, который я задал, и в конечном итоге ответил сам здесь , что, вероятно, полезно.

Я создал Gist , который показывает gulpfile.js в качестве примера.

В вашем Startup.cs по-прежнему важно использовать статические файлы:

app.UseStaticFiles();

Это обеспечит доступ вашего приложения к тому, что ему нужно.

5
David Pine

У Шона Вильдермута есть хорошее руководство: https://wildermuth.com/2017/11/19/ASP-NET-Core-2-0-and-the-End-of-Bower

Статья ссылается на gulpfile на GitHub, где он реализовал стратегию в этой статье. Вы можете просто скопировать и вставить большую часть содержимого gulpfile в свой файл, но обязательно добавьте соответствующие пакеты в package.json в devDependencies: gulp gulp-uglify gulp-concat rimraf merge-stream

1
Andrew Boza

Я нашел лучший способ управления пакетами JS в моем проекте с помощью обработчиков задач NPM Gulp/Grunt. Мне не нравится идея иметь NPM с другим слоем библиотеки javascript для обработки "автоматизации", и мое требование номер один - просто запустить обновление npm, не беспокоясь о том, нужно ли мне запускать gulp вещи, если он успешно все скопировал и наоборот.

NPM способ:

  • Минификатор JS уже включен в ядро ​​ASP.net, ищите bundleconfig.json, так что это не проблема для меня (не компилируя что-то нестандартное)
  • Преимущество NPM в том, что у него хорошая файловая структура, поэтому я всегда могу найти предварительно скомпилированные/минимизированные версии зависимостей в файле node_modules/module/dist
  • Я использую сценарий NPM node_modules/.hooks/{eventname}, который обрабатывает копирование/обновление/удаление файлов Project/wwwroot/lib/module/dist/. Js, вы можно найти документацию здесь https://docs.npmjs.com/misc/scripts (я обновлю скрипт, который я использую для git, как только он будет более отшлифован). Мне не нужны дополнительные исполнители задач (. JS инструменты, которые мне не нравятся), что делает мой проект чистым и простым.

python путь:

https://pypi.python.org/pyp ... но в этом случае вам нужно поддерживать источники вручную

1
Peter Húbek

Пожалуйста, извините за длину этого поста.

Это рабочий пример использования ASP.NET Core версии 2.5.

Следует отметить, что project.json устарел ( см. Здесь ) в пользу . Csproj . Проблема с . Csproj . Файл - это большое количество функций и тот факт, что для его документации нет центрального расположения ( см. здесь ).

Еще одна вещь, этот пример - запуск ядра ASP.NET в контейнере Docker Linux (Alpine 3.9); поэтому пути будут отражать это. Он также использует gulp ^ 4.0. Однако с некоторыми изменениями он должен работать с более старыми версиями ASP.NET Core, Gulp, NodeJS, а также без Docker.

Но вот ответ:

gulpfile.js см. настоящий рабочий пример здесь

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

Добавьте Target в . Csproj файл. Обратите внимание, что мы также добавили Watch для просмотра и исключения, если мы воспользуемся командой 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>

Теперь, когда dotnet run build запущен, он также установит и соберет модули узлов.

0
b01