代码之家  ›  专栏  ›  技术社区  ›  Dimitri Kopriwa

我们能动态地将一个React组件转换成一个React可加载组件吗?

  •  0
  • Dimitri Kopriwa  · 技术社区  · 6 年前

    我们使用react和 react-loadable .

    在应用程序初始化期间,我们正在验证 component.preload 每个方法都存在 <Route /> 我们定义。

    我们使用webpack 4,有没有一种方法可以自动包装组件,所以我们不必手动包装?

    组件的外观如下:

    /** MyComponent.js: page component */
    export default () => <div>Hello world</div>;
    

    这是封装在可反应加载组件中的同一组件:

    /**
     * preconfigured react-loadable 
     * See https://github.com/jamiebuilds/react-loadable#how-do-i-avoid-repetition)
     */
    import MyLoadable from '@scopped/react-loadable';
    
    /** loadable component */
    export default MyLoadable({
      loader: () => import('./MyComponent'), /** import page component */
    });
    
    1. 我们的 <路线/> node_modules 从不同的包裹里。
    2. 可以用 <Resource /> react-admin )而不是 <
    3. 它们不是以ESM格式分发的,只是 中日韩
    0 回复  |  直到 6 年前
        1
  •  3
  •   Saraband    6 年前

    我不确定这是正确的方法,但也许你可以写一些网页包加载器来预处理你的文件,找到 <Route />

    这有点老套,但它应该可以工作(仅适用于导入,但您可以根据需要进行调整):

    网页包配置:

    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: [
          "babel-loader", // Rest of your loaders
          path.resolve(__dirname, 'path/to/your/loader.js')
        ]
      }
    }
    

    加载程序.js:

    module.exports = function (source) {
      const routeRegex = new RegExp(/<Route.*component={(.*)}.*\/>/g);
      let matches;
      let components = [];
    
      while (matches = routeRegex.exec(source)) {
        components.push(matches[1]); // Get all the component import names
      }
    
      // Replace all import lines by a MyLoadable lines
      components.forEach((component) => {
        const importRegex = new RegExp(`import ${component} from '(.*)'`);
        const path = importRegex.exec(source)[1];
    
        source = source.replace(importRegex, `
          const ${component} = MyLoadable({
            loader: () => import('${path}')
          });
        `);
      });
    
      source = `
        import MyLoadable from './MyLoadable';
        ${source}
      `;
    
      return source;
    };
    

    这绝对是老生常谈,但如果你坚持惯例,这可以工作。它转换这种文件:

    import Page1 from './Page1';
    import Page2 from './Page2';
    
    export default () => (
      <Switch>
        <Route path='/page1' component={Page1} />
        <Route path='/page2' component={Page2} />
      </Switch>
    );
    

    进入此文件:

    import MyLoadable from './MyLoadable;
    
    const Page1 = MyLoadable({
      loader: () => import('./Page1')
    });
    
    const Page2 = MyLoadable({
      loader: () => import('./Page2')
    });
    
    export default () => (
      <Switch>
        <Route path='/page1' component={Page1} />
        <Route path='/page2' component={Page2} />
      </Switch>
    );
    

    MyLoadable