【问题标题】:Using nested folders with react-rails prerender使用带有 react-rails 预渲染的嵌套文件夹
【发布时间】:2020-05-18 09:25:17
【问题描述】:

我正在尝试为我的应用设置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.jspacks/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,但我仍然遇到同样的错误。

【问题讨论】:

    标签: ruby-on-rails reactjs react-rails execjs server-rendering


    【解决方案1】:
     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));
    

    参考 - https://github.com/reactjs/react-rails/issues/264

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多