Лучший способ интегрировать сборки веб-пакетов с ASP.NET Core 3.0?

Я обновляю свое приложение ASP.NET Core до версии V3 и использую Visual Studio 2019 для разработки / отладки. Процесс прошел гладко, за исключением этого:

public void Configure(…..
                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
                {
                    HotModuleReplacement = false,
                    ReactHotModuleReplacement = false
                });

UseWebpackDevMiddleware больше нет: https://github.com/aspnet/AspNetCore/issues/12890.

Теперь я хочу понять, как лучше всего заставить VS запускать веб-пакет каждый раз, когда я отлаживаю, в идеале только для измененного JS-кода. Это была ценность, которую я получал от UseWebpackDevMiddleware. Мое приложение - это приложение React, и кажется, что для него есть какая-то новая замена, если ваше приложение было запущено из CreateReactApp, а мое - нет. (Я считаю, что приложения, указанные в этом документе, но затем отделенные, называются «извлеченными».) Могу ли я каким-то образом по-прежнему пользоваться преимуществами этого средства, даже если мое приложение не использует CreateReactApp? Кроме того, какова роль CreateReactApp после загрузки вашего нового приложения React? Я предполагал, что он будет использоваться только для надувания кода шаблона с первого раза.

Какую роль во всем этом играет Microsoft.AspNetCore.SpaServices.Extensions?

Мне не нужна горячая замена модуля; Мне не нужен предварительный рендеринг на стороне сервера. Я действительно просто пытаюсь понять, как заставить мой JS прозрачно строить (через Webpack) как часть моего процесса отладки. Могу ли я для этого подключиться к MSBuild? Я полагаю, что другие столкнутся с тем же вопросом при обновлении.

Спасибо за любые предложения.


person BenjiFB    schedule 24.09.2019    source источник


Ответы (4)


Вы упомянули VS. Мое решение подходит для Visual Studio, но не для VS Code.

Я использую средство запуска задач WebPack: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebPackTaskRunner

Это добавляет задачи webpack.config.js в «Task Runner Explorer» в Visual Studio, и затем вы можете привязать эти задачи к таким событиям, как «Before Build» или «After Build».

person Jamie F    schedule 24.09.2019
comment
Спасибо за ваш комментарий. Но будет ли редактирование файла JavaScript (или, в моем случае, Typescript) запускать сборку в VS после отладки? - person BenjiFB; 24.09.2019
comment
Двойной щелчок по задаче в Task Runner Explorer запустит ее. Таким образом, вы можете пропустить привязку к сборке, а затем просто дважды щелкнуть по Watch - Development, чтобы запустить webpack is watching the files.... Он будет продолжать работать. - person Jamie F; 24.09.2019
comment
Однако при этом не производится замена горячего модуля, а это главное, что предлагает UseWebpackDevMiddleware. - person Kram; 06.10.2019
comment
@JamieF Ссылка на расширение не работает, поскольку оно включает закрывающую квадратную скобку как часть параметра запроса. Это должно работать: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebPackTaskRunner - person Manfred; 05.01.2020
comment
Смотрите - разработка в Task Runner работает отлично - person Muaddib878; 10.06.2020

Итак, я использовал UseWebpackDevMiddleware для HMR для более плавного процесса разработки - в конце концов я вернулся к использованию webpack-dev-server

Шаги:

1) Добавить пакет в package.json: "webpack-dev-server": "3.8.2", 2) Добавить webpack.development.js

const merge = require('webpack-merge');
const common = require('./webpack.config.js');
const ExtractCssPlugin = require('mini-css-extract-plugin');

const webpackDevServerPort = 8083;
const proxyTarget = "http://localhost:8492";

module.exports = merge(common(), {
    output: {
        filename: "[name].js",
        publicPath: '/dist/'
    },
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        compress: true,
        proxy: {
            '*': {
                target: proxyTarget
            }
        },
        port: webpackDevServerPort
    },
    plugins: [
        new ExtractCssPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        })
    ]
});

Обратите внимание, что настройка прокси-сервера здесь будет использоваться для прокси-сервера в ядро ​​ASP.Net для вызовов API

Измените launchSettings.json так, чтобы он указывал на webpack-dev-server:

"profiles": {
    "VisualStudio: Connect to HotDev proxy": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "http://localhost:8083/",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:8492/"
    }
  }

(также у меня возникла проблема с настройкой правильных местоположений в веб-пакете, и я обнаружил это полезно

Также потребуется запустить webpack-dev-server, что можно сделать с помощью скрипта npm:

  "scripts": {
    "build:hotdev": "webpack-dev-server --config webpack.development.js --hot --inline",

И тогда это загружается

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "build:hotdev");
                }
            });

(или вы можете установить расширение npm task runner и:

  "-vs-binding": {
    "ProjectOpened": [
      "build:hotdev"
    ]
  }

В качестве альтернативы я понимаю, что вы можете прокси-сервером другим способом, используя следующее - таким образом любой запрос в разделе "dist" будет проталкиваться через прокси webpack-dev-server

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "dist";

                if (env.IsDevelopment())
                {
                    // Ensure that you start webpack-dev-server - run "build:hotdev" npm script
                    // Also if you install the npm task runner extension then the webpack-dev-server script will run when the solution loads
                    spa.UseProxyToSpaDevelopmentServer("http://localhost:8083");
                }
            });

И тогда вам больше не нужно прокси-сервер, хотя оттуда, и вы можете просто обслуживать / dist / content - как горячую, так и предварительно скомпилированную поставщиком, используя как web.config.js, например:

module.exports = merge(common(), {
    output: {
        filename: "[name].js",
        publicPath: '/dist/',
    },
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        compress: true,
        port: 8083,
        contentBase: path.resolve(__dirname,"wwwroot"),
    },

    plugins: [
        new ExtractCssPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        })
    ]
});
person Kram    schedule 08.10.2019
comment
Для меня это должно было быть реальным ответом, поскольку это позволяет вам сохранить HMR, где в качестве исполнителя задач вы должны вручную запускать его. - person Hano Johannes Rossouw; 05.11.2019
comment
Не могли бы вы объяснить, почему мы используем wwwroot в contentBase, а не dist? - person FoxPro; 07.01.2020
comment
wwwroot - это общедоступный путь по умолчанию для приложений .NET. - person Dzulqarnain Nasir; 15.01.2020
comment
UseSpa больше не доступен в версии 3.1. Ядро asp.net не является стабильной платформой, это еще одно критическое изменение. - person Wayne; 28.03.2020
comment
Кажется правильным, что UseSpa отсутствует в версиях 3.1 и 5.0 согласно документации. @Kram, у вас есть какие-нибудь мысли о новом подходе, который не полагается на этот метод? Если да, сможете ли вы обновить свой ответ? Спасибо... - person BenjiFB; 07.05.2020
comment
Хано Йоханнес Россоу: На самом деле, решение Джейми гораздо более лаконично ... если вы запустите Watch - Development на Task Runner, как он предлагает: изменения кода автоматически переносятся так же, как HMR - person Muaddib878; 10.06.2020
comment
Уэйн, BenjiFB: все еще существует в версии 3.1, перемещен в SpaServices.Extensions github.com/dotnet/aspnetcore/blob/v3.1.5/src/Middleware/ - person Vočko; 18.06.2020
comment
Есть ли репо на GitHub для этого? - person Maxcom; 11.05.2021
comment
Я выполнил эти шаги, но это не работает для меня, как ожидалось. Вот содержание моего проекта. stackoverflow.com/questions/67516646/ - person Maxcom; 13.05.2021

На мой взгляд, ответ Крама следует отметить как принятый, поскольку он действительно дает то, что нужно. Недавно я потратил некоторое время на настройку проекта .NET Core / React / Webpack, и мне не удалось заставить spa.UseReactDevelopmentServer работать, но spa.UseProxyToSpaDevelopmentServer работает как шарм. Спасибо, Крам!

Вот несколько моих ошибок, которые могут кому-то помочь:

webpack.config.js (отрывок):

const path = require('path');
const webpack = require('webpack');

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.[hash].js',
},

devServer: {
    contentBase: path.resolve(__dirname, 'public'),
    publicPath: '/dist',
    open: false,
    hot: true
},

plugins: [
    new webpack.HotModuleReplacementPlugin()
]
  1. DevServer устанавливает свой корень свойством publicPath и полностью игнорирует свойство output.path в корне. Таким образом, даже если ваши выходные файлы (для prod) будут попадать в папку dist, на сервере webpack они по умолчанию будут обслуживаться под корнем. Если вы хотите сохранить тот же URL-адрес, вам нужно установить publicPath: '/dist'. Это означает, что ваша страница по умолчанию будет находиться по адресу http: // localhost: 8083 / dist. Я не мог придумать способ разместить активы в подпапке, сохранив индекс в корне (кроме жесткого кодирования пути для активов).

  2. Вам понадобится HotModuleReplacementPlugin для того, чтобы режим просмотра работал, а также hot: true параметр в конфигурации devServer (или передать его как параметр при запуске).

  3. Если вы (как и я) скопируете некоторую конфигурацию сервера разработки с open: true (по умолчанию false), вы закончите с двумя браузерами, открытыми при запуске приложения, поскольку другой открывается с помощью launchSettings "launchBrowser": true. Поначалу это было немного неожиданно.

Кроме того, вам нужно будет включить CORS для вашего проекта, иначе ваши внутренние вызовы будут заблокированы:

Startup.cs (отрывок):

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => 
    {
        options.AddPolicy(name: "developOrigins",
            builder =>
            {
                builder.WithOrigins("http://localhost:8083");
            });
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
        app.UseCors("developOrigins");
}

Если что-то еще придет мне в голову, я обновлю ответ, надеюсь, это кому-то поможет.

Обновление Webpack 5

webpack-dev-server команда больше не работает. Использовать:

"build:hotdev": webpack serve --config webpack.config.development.js

Вам также может потребоваться добавить target: 'web' к вашему webpack.config.js в Webpack 5, чтобы разрешить перезагрузку горячего модуля:

module.exports = {
    target: 'web'
}

В качестве альтернативы вам может потребоваться создать файл списка браузера. Надеюсь, эта проблема скоро будет исправлена.

person Vočko    schedule 22.06.2020
comment
Эй, чувак, ты просто добавляешь HotModuleReplacementPlugin, и я думаю, ты добавлял параметр hot в свой скрипт веб-пакета, и горячая перезагрузка работала? Я следил за Крамом и добавил некоторые из ваших редактирования, но я не могу заставить работать горячую перезагрузку. Мне все еще приходится перестраивать решение каждый раз, когда я меняю css или js -.- - person Giorgia Sambrotta; 08.09.2020
comment
У меня есть hot: true в настройках devServer (я отредактировал свой ответ, чтобы добавить его туда). Затем у меня есть сценарий npm "start": "webpack-dev-server --config webpack.config.development.js", и я просто запускаю сервер с помощью yarn start. - person Vočko; 09.09.2020
comment
большое спасибо за ваш повтор! Я уверен, что новичок в .Net, поэтому чувствую себя очень потерянным. Думаю, моя главная проблема в том, что в этом проекте используются страницы Razor. Так что у меня нет файла inde.html для создания моей папки dist /. Или, по крайней мере, я еще не понял, как это сделать. Если у вас есть предложения по работе с webpack и razor ... добро пожаловать! - person Giorgia Sambrotta; 09.09.2020
comment
Webpack не требует «бритвенных» страниц, он предоставляет собственный index.html, вам нужно только указать серверной части .NET, где искать страницу. Попробуйте посмотреть несколько блогов, например codeburst.io/. Это должно дать вам больше понимания всей концепции. - person Vočko; 10.09.2020
comment
спасибо за ссылку !! Так сложно найти документацию по этому поводу в Интернете, возможно, ваша ссылка мне поможет - person Giorgia Sambrotta; 11.09.2020