在 Webpack 和 React.js 中设置代码拆分

Posted

技术标签:

【中文标题】在 Webpack 和 React.js 中设置代码拆分【英文标题】:Setting up code splitting in Webpack and React.js 【发布时间】:2016-08-27 14:29:40 【问题描述】:

我正在尝试在我的应用程序中设置代码拆分/分块 - 通过路由,使用 require.ensure。所以这是我的路线:

<Route path="profile" 
       getComponent=(location, cb) => 
         require.ensure(
            [], 
            (require) =>  cb(null, require('attendee/containers/Profile/').default) , 
            'attendee') />

以下是我的 webpack 配置中的相关行:

const PATHS = 
  app: path.join(__dirname, '../src'),
  build: path.join(__dirname, '../dist'),
;

const common = 
  entry: [
    PATHS.app,
  ],

  output: 
    path: PATHS.build,
    publicPath: PATHS.build + '/',
    filename: '[name].js',
    chunkFilename: '[name].js',
    sourceMapFilename: '[name].js.map'
  ,

  target: 'web',

devtool: 'cheap-module-eval-source-map',
entry: [
  'bootstrap-loader',
  'webpack-hot-middleware/client',
  './src/index',
],
output: 
  publicPath: '/dist/',
,


plugins: [
  new webpack.DefinePlugin(
    'process.env': 
      NODE_ENV: '"development"',
    ,
    __DEVELOPMENT__: true,
  ),
  new ExtractTextPlugin('main.css'),
  new webpack.optimize.OccurenceOrderPlugin(),
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NoErrorsPlugin(),
  new webpack.ProvidePlugin(
    jQuery: 'jquery',
  ),
],

当我导航到路由中的页面时,我在日志中看到确实下载了所需的块。但是该页面无法加载。

我在控制台中看到以下堆栈跟踪:

Uncaught TypeError: Cannot read property 'call' of undefined
t                     @ main.js:10
(anonymous function)  @ main.js:44637
window.webpackJsonp   @ main.js:40
(anonymous function)  @ attendee.js:1

它抱怨的那一行是这样的:

return e[n].call(o.exports, o, o.exports, t)

第二行((匿名函数)@main.js:44637)本质上是这样的:

require('attendee/containers/Profile/').default

注意,如果我执行console.log(require('./attendee/containers/Profile/').default),我会得到一个函数作为输出,所以我不确定为什么它是未定义的。当然,当我这样做时,代码可以工作,但不再有分块。

所以我对require 做错了。知道它是什么吗?

顺便说一句,我在这个项目中使用了哈希历史 - 这可能是罪魁祸首吗?

更新:

还尝试了 this answer 中的 bundle-loader。结果一样。

【问题讨论】:

感谢标签建议。文档确实提到了第三个可选参数,即块名称。它不会被忽略,块的文件名是参加者.js - webpack 确实使用它。你可以使用它来获取一些路由来捆绑到同一个命名的块中。 尝试删除第三个参数 - 除了块文件的名称没有变化 - 现在是 2.js。 很抱歉,我没有任何其他建议可以解决您的问题。 【参考方案1】:

你快到了!试试这个:您需要提前在require.ensure 的第一个参数中指定模块依赖数组,而不是[] 将其显式设置为['attendee/containers/Profile']

(location, cb) => 
  require.ensure(['attendee/containers/Profile'], (require) => 
    cb(null, require('attendee/containers/Profile').default) 
  ) 

【讨论】:

我确实试过了——结果一样 我们有机会看到attendee/containers/Profile 的样子吗? Profile 导入一大堆东西。我是否必须将所有这些都放入数组中?从我读到的 webpack 应该跑来跑去为我找到所有依赖项......

以上是关于在 Webpack 和 React.js 中设置代码拆分的主要内容,如果未能解决你的问题,请参考以下文章

使用 Webpack 4 和 react js 在 scss 中导入字体或图像文件时出错

在 React.js 中设置和重置状态

Node SASS 的 React JS Webpack 失败

react js上的样式导入(使用webpack)

Webpack / React.js 中的语法错误 React 中的意外令牌 =

Webpack / Babel / React 构建错误:“未知选项:foo/node_modules/react/react.js.Children”