react脚手架从SPA到MPA改造过程中 Cannot read property 'filter' of undefined 的问题

1,755 阅读1分钟

问题描述

在实战react项目的过程中,项目是MPA的,所以我也动手将原来的SPA改造成MPA。

在改造完成后,yarn build时出现了Cannot read property 'filter' of undefined 的问题。

在网上查询了一番未果之后,终于在官方github的issues里面找到了解决方法。特写文章来跟各位探讨。

解决过程

写好debug代码

    script/build.js
    //找到这里
    if (messages.errors.length) {
    // Only keep the first error. Others are often indicative
    // of the same problem, but confuse the reader with noise.
    if (messages.errors.length > 1) {
      messages.errors.length = 1
    }
    //添加这一个判断
    if (err) {
      messages.errors.push(err.stack)
    }
    return reject(new Error(messages.errors.join('\n\n')))
  }

这样,我们再次yarn build的时候就不会只报一个Cannot read property 'filter' of undefined的错误了 我遇到的错误是这样的:

遇到的具体错误

找到bug的具体位置

// config/webpack.config.js
 new ManifestPlugin({
        fileName: 'asset-manifest.json',
        publicPath: paths.publicUrlOrPath,
        generate: (seed, files, entrypoints) => {
          const manifestFiles = files.reduce((manifest, file) => {
            manifest[file.name] = file.path
            return manifest
          }, seed)
          console.log('------------------', entrypoints)
          // 就是这里的filter
          const entrypointFiles = entrypoints.main.filter(fileName => !fileName.endsWith('.map')
          )

          return {
            files: manifestFiles,
            entrypoints: entrypointFiles
          }
        }
      }),

当我们log这个entrypoints的时候会发现,根本就没有main,而是我们自己写的那几个entry!

PS:这里的main其实是单文件入口时entry只有一个数组,默认他是main。因为我们把原来的数组改成了对象所有就没有main了。

解决

我这里解决比较粗暴哈,直接遍历他们。

// config/webpack.config.js
 new ManifestPlugin({
        fileName: 'asset-manifest.json',
        publicPath: paths.publicUrlOrPath,
        generate: (seed, files, entrypoints) => {
          const manifestFiles = files.reduce((manifest, file) => {
            manifest[file.name] = file.path
            return manifest
          }, seed)
          // ----- new ------
          const entrypointFiles = []
          for (let entrypoint of Object.keys(entrypoints)) {
            entrypointFiles.push(
              entrypoints[entrypoint].filter(
                fileName => !fileName.endsWith('.map')
              )
            )
          }
          return {
            files: manifestFiles,
            entrypoints: entrypointFiles
          }
        }
      }),

PS:至于要不要扁平化,我两个都试了一下,没看出build的文件有什么具体差异。

总结

以上就是解决 Cannot read property 'filter' of undefined 的措施。重点是debug代码那一步,才让我定位到了bug所在。

如有问题,欢迎指正、交流!