【问题标题】:Why is webpack code splitting not working for me?为什么 webpack 代码拆分对我不起作用?
【发布时间】:2017-02-07 00:17:03
【问题描述】:

我正在使用 require.ensure 在 react-router 路径上创建分割点。但是,除了vendor.js 之外,我的构建目录仍然只有app.js。我期待我使用的每个路径都有一个单独的 js 文件require.ensure。

我在每条路径上都使用了require.ensure,如下所示:

<Route path= 'auth' getComponent={(nextState, callback) => {
  require.ensure([], (require) => {
    callback(null, require('containers/Authenticate/AuthenticateContainer.js').default)
  }, 'auth')
}}/>

我的构建的 web pack 配置输出如下所示:

output: {
  path: PATHS.build,
  filename: '/[name].[chunkhash].js',
  chunkFilename: '/[chunkhash].js'
}

这里是我的route file 和我的webpack config file 的全部要点。

更新:我知道我做错了什么。我的容器项目结构是这样的:

-app
 -containers
   -containerA.
     -containerA.js
   -containerB
     -containerB.js
   -containerC
     -containerC.js
   -index.js

问题:我仍在导出路由文件中需要的容器,如下所示:export containerB from './containerB/containerB' 删除 index.js 中的导出并直接从 containerB.js 中要求就可以了。

【问题讨论】:

    标签: reactjs webpack lazy-loading react-router code-splitting


    【解决方案1】:

    Ensure 接受你想要的模块的参数数组。您需要为数组提供您希望动态加载的模块名称。在您的情况下,提供 'containers/Authenticate/AuthenticateContainer.js' 以确保像这样:

    require.ensure(['containers/Authenticate/AuthenticateContainer.js'], (require) => {
          callback(null, require('containers/Authenticate/AuthenticateContainer.js').default)
        }, 'auth');
    

    【讨论】:

    • 添加对构建目录没有影响。
    • 我需要在 webpack 配置中添加一些内容才能使其正常工作。
    • 如果你逐字复制,我在最后漏掉了一个引号。不,您不需要配置其他任何东西。
    • @jasan 请告诉我们发生了什么
    • @MitchKarajohn 我还没有解决这个问题。我确实有一个选择是升级到 webpack 2.0 并使用新的 system.imports 但这也需要我在我的配置中进行许多其他更改。因此,我推迟了。
    【解决方案2】:

    我在我的一个项目中遇到了同样的问题:我们使用 Systemjs 并决定切换到 Webpack,所以它破坏了我们的 System.import。我们通过替换来修复它:

    System.import(modulePath)
      .then(module => {
        // Do things
      })
    

    与:

    new Promise((resolve, reject) => {
        resolve(require(modulePath));
    }).then((module) => { 
      // Do things 
    });
    

    希望对你有帮助

    【讨论】:

    • Richard 我没有使用 Webpack 2.0。我正在使用他们最新的稳定版本。
    • 不是系统导入只适用于 webpack 2.0 吗,在 webpack 的早期版本中使用 require.ensure。
    • 是的,它破坏了我们的应用程序。所以我们用 promises 替换它(我评论中的第二个代码)
    • Richard 您能否发布一个要点,并附上一个将其与反应路由器路由一起使用的示例。不清楚。
    【解决方案3】:

    我正在使用 webpack 1.13.1,这是我的配置

    output: {
            path: PATHS.build,
            filename: '[name].[hash].js',
            publicPath:"/"
        },
    

    这里是获取组件的代码

    const lazyLoadSomeComponent = () => {
      return {
          getComponent: (location, callback)=> {
            require.ensure([], require => {
              callback(null, require("./componentpath")["default"]);
            }, 'componentName');
          }
        }
    };
    

    然后在路线中

    <Route path="somepath" {...lazyLoadSomeComponent()} />
    

    但这是怎么回事?

    • 首先我们创建一个函数,它将为我们返回 get 组件方法。
    • 其次,我们在路由中调用该函数并执行它,这样我们就可以在其中获取 get 组件方法,这将使路由易于阅读
    • 最后在 webpack 中指定公共路径,所以这里的“/”从你的服务器的根目录解析,你也可以在这里指定你的域

    为了进一步增强,我们可以使用以下方法一次加载多个组件

    const LazyComponents = (pageName) => {
      return {
          getComponent: (location, callback)=> {
            require.ensure([], require => {
              switch(pageName){
                case 'Component1':
                callback(null, require("./components/component1")["default"]);
                break;
                case 'Component2' :
                    callback(null, require( "./components/component2" )["default"]);
                        break ;
    
            }, "CombinedComponents");
          }
        }
    };
    

    然后在路线中

    <Route path="somepath" {...LazyComponents('Component1')} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 2013-08-06
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多