Webpack:了解块和代码拆分

Webpack: Understanding chunks and code splitting

我最近一直在使用 React,并开始尝试将 Webpack 合并到我的工作流程中。但是,我正在尝试了解有关该工具的更多信息(不幸的是,文档在解释不同方面的含义方面不是很好)。

在高层次上,我了解到 Webpack 允许您创建一个捆绑的 JavaScript 文件,这样您就可以在多个文件中编写代码,但将 1 个文件加载到 HTML 中的脚本标记中. 什么是 webpack 中的块,它与这个打包过程有什么关系?

此外,webpack 被吹捧为能够代码拆分 - 这到底是什么意思,你们能举个例子吗?

"Chunks" 是代码的一部分,从某种意义上说,它们是服务器按需获取的。因此,您可以拥有一个加载网站的主要交付成果,但在用户开始四处浏览时加载其他资源。

实际上,您可以通过定义分割点来做到这一点。这告诉 webpack 将 运行 代码路径所需的代码放在该分割点(即函数)内的代码路径中。然后 Webpack 将分离出该拆分块和主文件共有的模块,并将其放入主文件中以避免重复供应商代码(换句话说,该块可能不会独立)。现在 Webpack 生成两个文件:主文件和一个附加块。当块的代码路径被命中时,主文件将从线路中拉入额外的块。从开发人员的角度来看,这一切都发生在require,这使得推理非常容易。

最常见的用途之一是分块路由器代码。 react-router 文档中有一个 working example,但一般的想法是将初始路由加载到主文件中,所有后续或子路由都可以在它们自己的块中,并且只有在用户点击这些路线,提高性能(潜在)。示例代码是了解其工作原理的好方法,因为您可以看到文件在您访问路由时从网络中取出。

无论如何,代码分块是一个很棒的功能。


综上所述,要非常小心过早优化。它会扼杀生产力。最好的建议是获得 运行 没有任何代码分块的 Webpack,然后在需要性能时添加代码分块(例如,当您注意到站点的某个功能或部分很重但很少使用时)。

PS: 如果您有更具体的问题,我很乐意修改这个答案。不过,如果您好奇,请查看上面的 react-router link。

React Router 和 Webpack 配合得非常好,因为您可以在请求路由时自动拆分代码 + 动态加载块。更好的是,如果您将项目设置为使用 Webpack 2(+ Tree shaking),则可以使用原生 ES6 导入和 System.import.

方法如下:

import App from 'containers/App';
function errorLoading(err) {
  console.error('Dynamic page loading failed', err);
}
function loadRoute(cb) {
  return (module) => cb(null, module.default);
}
export default {
  component: App,
  childRoutes: [
    {
      path: '/',
      getComponent(location, cb) {
        System.import('pages/Home')
          .then(loadRoute(cb))
          .catch(errorLoading);
      }
    },
    {
      path: 'blog',
      getComponent(location, cb) {
        System.import('pages/Blog')
          .then(loadRoute(cb))
          .catch(errorLoading);
      }
    }
  ]
};

您可以在此博客中获取完整指南 post:Automatic Code Splitting for React Router