将 webpack 构建与 ASP.NET Core 3.0 集成的最佳方式?

Posted

技术标签:

【中文标题】将 webpack 构建与 ASP.NET Core 3.0 集成的最佳方式?【英文标题】:Best way to integrate webpack builds with ASP.NET Core 3.0? 【发布时间】:2020-01-24 18:25:09 【问题描述】:

我正在将我的 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 运行 webpack 的最佳方法,理想情况下仅在已更改的 JS 代码上运行。这是我从UseWebpackDevMiddleware 获得的价值。我的应用程序是一个 React 应用程序,如果您的应用程序是从 CreateReactApp 启动的,那么似乎有一些新的替代品,但我的不是。 (我相信从这里声明但随后分离的应用程序被称为“弹出”。)即使我的应用程序不利用 CreateReactApp,我是否仍有可能利用该设施?此外,在引导您的新 React 应用程序之后,CreateReactApp 的作用是什么?我以为它只会用于一开始就膨胀模板代码。

Microsoft.AspNetCore.SpaServices.Extensions 在这一切中的作用是什么?

我不需要热更换模块;我不需要服务器端预渲染。作为调试过程的一部分,我真的只是想了解如何让我的 JS 透明地构建(通过 Webpack)。这是我可以连接到 MSBuild 的东西吗?我想其他人在升级时也会面临同样的问题。

感谢您的任何建议。

【问题讨论】:

【参考方案1】:

扩展在这里:AspNetCore.SpaServices.Extensions

您可以在此处找到示例:https://github.com/RimuTec/AspNetCore.SpaServices.Extensions

使用核心 3.1 或 5.0 与 webpack 反应

使用:spaBuilder.UseWebpackDevelopmentServer(npmScriptName: "start");

【讨论】:

【参考方案2】:

在我看来,Kram 的答案应该被标记为接受,因为它确实提供了所需的内容。我最近花了一些时间设置一个 .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()
]

    DevServer 通过publicPath 属性设置其根,并完全忽略根中的output.path 属性。因此,即使您的输出文件(用于 prod)将转到 dist 文件夹,在 webpack 服务器下,默认情况下它们将在根目录下提供。如果要保留相同的 url,则必须设置 publicPath: '/dist'。 这意味着您的默认页面将位于 http://localhost:8083/dist 下。我想不出一种方法将资产放在子文件夹下,同时将索引保留在根目录中(除了硬编码资产的路径)。

    您需要HotModuleReplacementPlugin 才能让观看模式工作,还需要在 devServer 配置中设置hot: true(或在启动时将其作为参数传递)。

    如果您(像我一样)使用 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

您可能还需要在 Webpack 5 中将 target: 'web' 添加到您的 webpack.config.js 以启用热模块重新加载:

module.exports = 
    target: 'web'

或者,您可能需要创建一个浏览器列表文件。希望这个问题尽快得到解决。

【讨论】:

嘿伙计,所以您只需添加HotModuleReplacementPlugin,我猜您将选项hot 添加到您的webpack 脚本并且热重载工作了吗?我跟着 Kram's 添加了一些你的编辑,但我无法进行热重载工作。每次我对 css 或 js 进行更改时,我仍然必须重建解决方案 -.- 我在 devServer 设置中有hot: true(我已经编辑了我的答案以将其添加到那里)。然后我有一个 npm 脚本"start": "webpack-dev-server --config webpack.config.development.js",我只是使用yarn start 启动服务器。 非常感谢您的重播!我确定是.Net 的新手,所以我感到非常迷茫。我认为我的主要问题是在这个项目中他们使用 Razor 页面。所以我没有为我的 dist/ 文件夹生成 inde.html。或者至少我还没有弄清楚该怎么做。如果您对如何使用 webpack 和 razor 有任何建议.. 非常欢迎! Webpack 不需要剃须刀页面,它提供自己的 index.html,您只需要告诉 .NET 后端在哪里查找页面。尝试查看一些博客,即codeburst.io/…。这应该让您对整个概念有更多的了解。 感谢您的链接!!很难在网上找到有关此的文档,也许您的链接会对我有所帮助【参考方案3】:

你提到了 VS。我的解决方案适用于 Visual Studio,但不适用于 VS Code。

我使用 WebPack 任务运行器:https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebPackTaskRunner

这会将 webpack.config.js 任务添加到 Visual Studio 中的“Task Runner Explorer”中,然后您可以将这些任务绑定到“Before Build”或“After Build”等事件

【讨论】:

感谢您的评论。但是编辑 javascript(或者,在我的例子中是 Typescript)文件会在调试时触发 VS 中的构建吗? 在Task Runner Explorer 中双击一个任务将启动它。所以你可以跳过绑定来构建,然后只需双击 Watch - Development 启动 webpack is watching the files... 它将继续运行。 这并没有做热模块更换,这是UseWebpackDevMiddleware提供的主要功能 @JamieF 指向扩展的链接已损坏,因为它包含作为查询参数的一部分的右方括号。这应该工作:https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebPackTaskRunner Task Runner 上的“Watch - Development”完美运行【参考方案4】:

所以,我在 HMR 中使用 UseWebpackDevMiddleware 以获得更顺畅的开发流程 - 最后我恢复使用 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 中配置正确位置时也遇到了一些问题,发现 this 很有用

另外,需要启动 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 任务运行器扩展,并且:

  "-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/ 内容 - 像这样使用 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"
        )
    ]
);

【讨论】:

这对我来说应该是真正的答案,因为这允许您保留 HMR 作为任务运行器,您必须手动触发它。 您能否解释一下,为什么我们在 contentBase 中使用“wwwroot”,而不是“dist”? UseSpa 在 3.1 中不再可用。 asp.net core 不是一个稳定的平台,另一个重大变化。 根据文档,UseSpa 从 3.1 和 5.0 开始消失,这似乎是正确的。 @Kram,您对不依赖此方法的新方法有什么想法吗?如果是这样,你能更新你的答案吗?谢谢... Wayne, BenjiFB:在 3.1 中仍然存在,移至 SpaServices.Extensions github.com/dotnet/aspnetcore/blob/v3.1.5/src/Middleware/…

以上是关于将 webpack 构建与 ASP.NET Core 3.0 集成的最佳方式?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 中的 Jwt 令牌身份验证

将NuGet构建工具包与ASP.NET Core一起使用

ASP.Net Core:在VS2017中搭建React.js + webpack + babel

将 ASP.NET Web Api 构建到不同的输出目录

asp.net core prerender webpack 错误:TypeError:无法读取属性“过滤器”

Asp.Net Core 中 webpack 上的 sass-loader