ruby-on-rails - 使用带有 react-rails 预渲染的嵌套文件夹
问题描述
我正在尝试react-rails
为我的应用程序(https://github.com/reactjs/react-rails)进行设置。
最初设置它没有问题,但我预计会有很多不同的单独组件,所以我想/javascript/components
整齐地组织我的文件夹。
所以我有这样的东西
components
character
avatar-selector
AvatarSelector.tsx
HomeLogo.tsx
AvatarSelector.tsx
默认导出组件。
我有
const componentRequireContext = require.context("components", true);
const ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);
在两者packs/application.js
中packs/server-rendering.js
当我渲染HomeLogo
组件时,无论有没有预渲染,一切都很好。当我然后去渲染组件时,react_component('character/avatar-selector/AvatarSelector', avatar_props, prerender: false)
它也可以正常工作。
但是当我切换到prerender: true
它时会出错。
ExecJS::ProgramError: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.>" when prerendering character/avatar-selector/AvatarSelector
我已经尝试过直接添加
const AvatarSelector = require('../components/character/avatar-selector/AvatarSelector')
到我的包并尝试将组件渲染为AvatarSelector
但我仍然遇到相同的错误。
解决方案
Regarding Encountered error <ExecJS::ProgramError: Invariant Violation: Element type is invalid: ...:
我认为核心问题之一是模块查找使用 try...catch。虽然错误被记录到控制台 shim 中,但这通常无济于事,因为以后的错误(例如不变违规)将导致致命错误(触发 500)。如果可以根据环境将其重构为更加有意(而不是仅仅根据异常做出反应,或者至少,如果捕获的异常不是很具体,则抛出)
EDIT: Here's something you can do to help with the Invariant Violation bug:
In app/javascripts/packs/server_rendering.js, replace ReactRailsUJS.useContext('require.context('components', true)); with
// So that we don't fall back to the global namespace (which leads to hard to
// parse errors).
function fromRequireContext(reqctx) {
return function(className) {
const parts = className.split('.');
const filename = parts.shift();
const keys = parts;
// Load the module:
let component = reqctx('./' + filename);
// Then access each key:
keys.forEach((k) => {
component = component[k];
});
// support `export default`
if (component.__esModule) {
component = component.default;
}
return component;
};
}
ReactRailsUJS.getConstructor = fromRequireContext(require.context('components', true));
推荐阅读
- c# - 动态调用子类的重载方法
- airflow - 气流 DAG 'start_date' 未注册
- mysql - 从不同的表中检索总和
- outlook - 找出谁在收件箱中打开,在 Outlook 中
- docusignapi - 调用函数getDocument时无法下载文档
- powershell - 在 PowerShell 中使用 NLog ${callsite} 和 ${callsite-linenumber}
- flutter - 如何使用 Navigator.push 更改页面,使正文和页眉动画不同,而页脚保持不变
- python - 单个预测图像不需要重新缩放?
- java - ClassCastException:使用带有标题标题的 ContextMenu 时,无法在 Android 中将 HeaderViewListAdapter 强制转换为 MenuAdapter
- python - 如何确定 Airflow PostgresOperator 中身份验证失败的原因?