首页 > 解决方案 > .NET Core 2.X MVC、React、Typescript、Webpack 配置

问题描述

我正在努力改进我的 .NET Core 应用程序,但不确定我需要采取哪种方式。这是一个较旧的网站,最初是使用 Asp.NET 和 Razor 页面构建的,现在我正在尝试加快速度并更新 UI 以符合新的库和方法(React、Angular 等)。

由于重新编程整个 UI 不在允许的时间内,React 似乎是一个不错的选择。所以我创建了一个新的 React 应用程序使用

create-react-app client-app --scripts-version=react-scripts-ts

在 MVC 区域文件夹下(每个区域都必须有自己的应用程序),我可以通过 Power Shell 服务和构建客户端,一切都很好。

我遇到的问题是将生成的脚本的输出目录移动到 wwwroot 文件夹。我需要能够从 wwwroot 加载脚本,因为由于现有项目的路由、过滤器和其他问题,我无法使用 SPA 服务。

这是我第一次尝试使用 React,所以我认为更改文件的输出很容易,但我似乎无法弄清楚如何。

我更新tsconfig.json以使用更改输出目录

"outDir": "../../../wwwroot/areas",

这似乎没有任何作用,我能够得到任何结果的唯一方法是使用弹出 React 项目npm run eject,我得到一堆文件,包括 webpack.config.prod.ts 和 webpack.config。 dev.ts 文件。当我这样做时,我注意到该目录以wepack.config.ts.

在网上寻找答案后,我注意到一些文章建议使用 webpack-cli 而不是npm指定配置文件。但是当我这样做时,我得到了各种错误,说配置文件不在根目录中,所以我尝试将它移动到./src目录中,然后我得到另一个错误,即找不到入口模块,因为它无法解决./src目录,但我找不到它从哪里引用 src。

我能找到的大部分信息要么已经过时,要么根本不起作用。甚至 Typescript.org 网站仍在引用 .NET Core 1.X。

我确实找到了这个ReactJS.NET,但它看起来不是很最新,而且他们的示例无法加载,产生了大量错误。

有没有一种简单的方法可以为这个网站配置 React,或者我是否被迫依赖像 AngularJS 或 KnockOut 这样的旧库?是否可以将 React 设置为像这样提供服务并补充 UI,让我仍然可以使用 Razor 页面?

标签: reactjstypescriptwebpackbabeljs

解决方案


我能够按照我需要的方式进行设置,包括 Webpack 热模块替换。

为了控制所需的配置,我需要react-client-app通过运行来弹出:

`npm run eject`

这将在您的应用根目录下创建一些目录和文件,其中包含用于生产和调试的 webpack 配置。

对于我的项目,我不需要static/文件夹,为了更改文件的输出,webpack.config 中有几个区域可以控制这些,例如:

webpack.config.js

output: {
  ...
  filename: 'js/[name].js',
  chunkFilename: 'js/[name].chunk.js',
  ...
},

....

// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
   test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.svg$/],
   loader: require.resolve('url-loader'),
   options: {
      limit: 10000,
      name: 'media/[name].[ext]',
   },
},

...

出于某种原因,默认的 React TS 模板 ( create-react-app <name> --typescript) 没有引用tsconfig.json. 实现这一目标的关键之一是安装tsconfig-paths-webpack-plugin. 这使用中定义的路径tsconfig.json来解析别名和路径,这使您可以从自定义路径中包含模块,而不是使用相对路径,例如:

import <name> from 'core/common/<name>';

下一项业务是在 中添加一个homepage条目package.json

{
   "name": "<AppName>",
   "homepage": "/<AreaName>",
   "version": "0.1.0",
   ...
}

这会将homepage值附加到路径并将其指向正确的区域。我最初认为我必须手动构建客户端而不是使用 Javascript 服务 (Spa),但事实并非如此。在不同的区域使用 Spa 确实可以让事情变得整洁,没有理由输出到wwwroot文件夹,因为SpaStaticFiles可以设置为任何根和路径。下一步是更新 Startup.cs 以添加 Javascript 服务。

启动.cs

  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
     // In production, the Angular files will be served from this directory
     services.AddSpaStaticFiles(configuration =>
     {
        // Adds the path to the React files
        configuration.RootPath = "Areas/<AreaName>/ClientApp/build";
     });

     return services.ConfigureApplicationServices(Configuration);
  }

  application.UseSpaStaticFiles(new StaticFileOptions
  {
     // This is the key to getting things working, this is the path of the Area
     RequestPath = "/<AreaName>",
  });

  application.UseSpa(spa =>
  {
     spa.Options.SourcePath = "Areas/<AreaName>/ClientApp";

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

React 应用程序现在由 Area 提供服务。无需将文件复制到 wwwroot,因为 Javascript Servies 会处理此问题,只需引用根目录中的任何文件,该homepage值将附加到路径中。

最后,为了加载应用程序,我通过标准控制器/视图启动了应用程序,并使用编译后的 index.html 获取所需的导入以返回。

看法

@{
   Layout = null;
}
<!doctype html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <link rel="shortcut icon" href="/<AreaName>/favicon.ico" />
   <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
   <meta name="theme-color" content="#000000" />
   <link rel="manifest" href="/<AreaName>/manifest.json" />
   <title>React App</title>

   <!-- Webpack Styles -->
   <link href="/<AreaName>/css/vendors~main.chunk.css" rel="stylesheet">
   <link href="/<AreaName>/css/main.css" rel="stylesheet">
</head>
<body>
   <noscript>You need to enable JavaScript to run this app.</noscript>

   <div id="root"></div>

   <!-- Webpack Scripts -->
   <script src="/<AreaName>/js/vendors~main.chunk.js"></script>
   <script src="/<AreaName>/js/main.js"></script>
</body>
</html>

为了让react-router-domMVC 及其路由正常运行,您需要HashRouter使用BrowserRouter.

注意:如果您npm run build在启动开发会话之前使用生产构建文件,而不是调试编译文件。这将导致一些混乱,因为没有任何更新。要在进行更改时更新所有内容,只需删除./build目录并重新启动即可。

我希望我包括所有内容,如果不只是发表评论,我会添加我错过的内容。


推荐阅读