动态导入组件错误-未捕获(承诺)错误:找不到模块

时间:2019-09-18 06:26:10

标签: javascript node.js reactjs react-router

我制作了一个反应库,将微服务返回的菜单数据转换为动态路由。

项目结构图如下:
--react-app
---- node_modules
------ ...
------ rb-react --->我的React库
------ ...
---- src
------页
-------- Dashboard.js
-------- Prod.js
-------- User.js
-------- ...

库rb-react无法导入页面,即Dashboard.js

        let rootPath = path.resolve(__dirname, '../src/pages');

        let menuPath = menuCommand.replace('#', '');
        let importObject = asyncComponent(() =>
          import(rootPath + '/' + menuCommand.split('/')[1])
        );
        if (isEmpty(routeResultArray)) {

          routeResultArray.push(
            <Route key={menuKey} exact path='/' component={importObject} />
          );
        }

node --version
v12.6.0
npm --version
6.11.3

这是我的项目的一些代码

动态导入类

export default function asyncComponent(importComponent) {

  class RbImport extends Component {

    constructor(props) {

      super(props);

      this.state = {
        component: null
      };
    }

    async componentDidMount() {

      const { default: component } = await importComponent();

      this.setState({

        component: component
      });
    }

    render() {

      const C = this.state.component;

      return C ? <C {...this.props} /> : <></>;
    }
  }

  return RbImport;
}

动态路线

import React from 'react';
import path from 'path';
import { HashRouter, Route, Switch } from 'react-router-dom';
import ScrollToTop from './ScrollToTop';
import App from '../../App';
import { RbLibraryComponent } from './RbLibraryComponent';
import { RbLocalStorage } from '../util/RbLocalStorage';
import { NotFound } from '../notfound/NotFound';
import { isEmpty } from '../util/RbUtil';
import asyncComponent from '../util/RbImport';

export class RbRoute extends RbLibraryComponent {

  constructor() {
    super();
    this.state = {};

    this.RbLocalStorage = new RbLocalStorage();
    this.composeRoute = this.composeRoute.bind(this);
    this.recursiveComposeRoute = this.recursiveComposeRoute.bind(this);
  }

  composeRoute() {

    let routeResultArray = [];
    let userMenus = this.RbLocalStorage.loadUserMenu();

    this.recursiveComposeRoute(routeResultArray, userMenus, null);
    return routeResultArray;
  }

  recursiveComposeRoute(routeResultArray, menuDataList, prefixKey) {

    if (isEmpty(menuDataList)) {

      return;
    }

    prefixKey = isEmpty(prefixKey) ? '' : prefixKey;

    let userMenuCount = menuDataList.items.length;
    for (let idx = 0; idx < userMenuCount; idx++) {

      let userMenu = menuDataList.items[idx];

      if (isEmpty(userMenu)) {

        continue;
      }

      let menuKey = isEmpty(prefixKey) ? idx : prefixKey + '-' + idx;

      let menuCommand = userMenu.command;
      if (isEmpty(menuCommand)) {
        //nothing
      } else {

        let rootPath = path.resolve(__dirname, '../src/pages');

        let menuPath = menuCommand.replace('#', '');
        let importObject = asyncComponent(() =>
          import(rootPath + '/' + menuCommand.split('/')[1])
        );
        if (isEmpty(routeResultArray)) {

          routeResultArray.push(
            <Route key={menuKey} exact path='/' component={importObject} />
          );
        }

        routeResultArray.push(
          <Route key={menuKey} path={menuPath} component={importObject} />
        );
      }

      if (isEmpty(userMenu.items)) {
        //nothing
      } else {

        this.recursiveComposeRoute(routeResultArray, userMenu, menuKey);
      }
    }
  }

  render() {

    let { menu, productionName, userName } = this.props;

    if (menu === null || menu === undefined) {
      return <></>;
    }

    return (
      <HashRouter>
        <ScrollToTop>
          <App menu={menu} userName={userName}>
            <Switch>
              {this.composeRoute()}
              <Route component={NotFound} />
            </Switch>
          </App>
        </ScrollToTop>
      </HashRouter>
    );
  }
}

export default RbRoute;

Chrome控制台上的异常消息

Uncaught (in promise) Error: Cannot find module '/src/pages/Dashboard'
    at webpackContextResolve (^.*$:29)
    at webpackContext (^.*$:24)
    at RbRoute.js:221 --> (Compiled Source) return _interopRequireWildcard(require("".concat(rootPath + '/' + menuCommand.split('/')[1])));

1 个答案:

答案 0 :(得分:0)

如果您尝试使用异步导入,则需要指定要导入的文件的路径。只有这样,webpack才能为该文件创建一个单独的块。以我的理解,您正在尝试使导入语句动态化。那行不通。您将需要指定所进行的每个异步导入的完整路径。 (此路径必须在构建时可用)

如果您需要将所有模块加载到目录中,是否可以签出require.context。 https://webpack.js.org/guides/dependency-management/