在 .cshtml razor 视图中对 npm 包内的组件使用 @html.React()

Kar*_*arl 1 c# asp.net razor npm reactjs

我有一个使用 razor 视图的 .NET Core 3.1 ASP.Net 项目。

我在这些 razor 视图中使用 React 组件,方法是将 app.UseReact() 添加到我的startup.cs,然后在 .cshtml 文件中调用 @html.React("myComponent") 。我没有使用 React 作为 SPA。

当我在 Web 项目中的 .tsx 文件中有“myComponent”时,这种方法工作得很好。

我的公司希望将其中一些 React 组件转移到 npm 包中,以便它们可以跨项目重复使用。将“myComponent”的 .tsx 文件移动到 npm 包并引用 package.json 中的包后,运行项目时出现错误“myComponent”未定义。

我已经运行了 npm install,我可以看到“myComponent”的包和 .tsx 文件位于项目的 node_modules 文件夹中,但我猜测 asp.net mvc 不知道在那里查找当我在 .cshtml 文件中调用 @html.React("myComponent") 时,对于组件。

我需要做什么才能让 ASP.NET 找到该组件?我需要以某种方式显式导入它吗?

目前,我已经成功地通过了一个肮脏的黑客手段。我使用预构建脚本将组件的 tsx 文件从 node_modules 文件夹复制到 ClientApp 文件夹中,以便它与项目的其他 React 组件一起放置。但这并不理想,因为其他开发人员可能没有意识到它正在被复制到那里,并且如果他们想要进行更改,则尝试编辑它,而实际上他们应该编辑 npm 包中的文件。

Jac*_*son 6

直接回答

添加 npm 包不会自动使其可供 MVC 使用,因此您必须在开发周期的某个时刻进行某种文件复制。这可以是 npmpostinstall脚本,甚至可以是更复杂的脚本,例如 Grunt/Gulp 任务。如果您选择这样做,您甚至可以通过 npm 脚本触发任务。总而言之,没有“正确”或“标准”的方式来使用 MVC 做出反应,所以你可以自由地做出自己的选择,小心:)

如果他们想要进行更改,实际上他们应该编辑 npm 包中的文件。

是的,他们需要了解 npm 包、克隆其源 git、更新它、发布它,然后将其项目更新到最新的包版本。

我的经历(读痛苦)

我怎么能忘记这种痛苦。将 React 作为非 SPA 是一个错误,因为您本质上使每个主视图都成为独立的 SPA,而这有一些主要缺点。首先,如何在同一页面的 razor 视图和组件之间共享数据?我们的方法是将数据 JSON 字符串化到一个变量中,然后将该变量加载到组件中(您也可以选择对 Web API 端点进行额外的 http 调用)。随着页面随着时间的推移而演变,您已经可以看到火焰的开始。我们遇到的下一个问题是捆绑优化。我们必须编写一堆代码才能捆绑每个页面并将输出保存到wwwroot文件夹中。加入的开发人员经常对它在主要 razor 视图(例如 Views/Home/Index.cshtml)中的作用感到困惑:

<script src="/Home.Index.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

等等,文件在哪里/Home.Index.min.js?这是由该页面的捆绑任务在构建时创建的,并复制到脚本文件夹中。开发人员会问的下一个问题是为什么该页面缺少其“用户界面”,当然他们忘记了为他们创建的新剃刀页面添加附加任务(以及脚本条目)......我可以写几天来,我们讨论了每个剃刀页面一个捆绑包的想法是多么糟糕,以及维护周期几年后代码变得多么混乱,更不用说 JQuery 的神秘回归了!事实上,JS 需要进行 tree-shaking、缩小和优化。ASP.NET 没有这样的东西,nuget 包只是粘合您的 JS 文件并提供一定程度的缩小,这些都无法与 webpack 或 Parcel 等标准捆绑器相匹配。这是让我们的捆绑任务为每个页面运行捆绑器的另一个原因。这还处理了 npm 依赖项和第三方库。

我的建议(意见)

为了拯救自己,只需将它们分开即可。不存在带有 React 的 razor 页面这样的东西,这是为了使 razor 与不断发展的网络技术兼容而编造的黑客行为。其中一些适用于 php,因此它不仅仅是 Microsoft 的事情。

您能做的最好的事情就是创建 SPA 并使用 Web api 作为后端。你可以有 razor,但它们将是独立的页面,例如登录页面可以是 razor 页面,然后将你带到主页,该主页是通过 React 和周围生态系统编写和捆绑的 SPA。SPA 中的交互通过 REST 甚至 GraphQL API 进行。