create-react-app创建的项目配置多入口MPA模式。报Cannot read property ‘filter’ of undefined

create-react-app创建的项目配置多入口MPA模式。报Cannot read property ‘filter’ of undefined

多入口配置
一.首先eject项目
执行npx create-react-app train-ticket,安装react项目。这时候package.json中react-srcipt已经集成了所有的逻辑,此时需要个性化的配置,需要执行npm run eject,将webpack配置文件拉出,并执行npm install安装依赖。执行完上述命令之后,文件树如图所示
在这里插入图片描述
二.配置webpack文件
①在config/webpack.config首先找到配置文件入口entry处,这里只配置一个入口文件,要将这里改成多入口的模式,因此应该将这里改成对象的形式。

    entry:[
	     paths.appIndexJs, 
	     isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient')
 		].filter(Boolean),

给每一个不同的入口起不同的名字

   entry:{
      index: [paths.appIndexJs, isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient')].filter(Boolean),
      query: [paths.appQueryJs, isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient')].filter(Boolean),
      ticket: [paths.appTicketJs, isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient')].filter(Boolean),
      order: [paths.appOrderJs, isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient')].filter(Boolean),
    },

②这里的入口文件的路径写在paths文件中,因此到config/paths中添加这几个变量。在项目中这几个文件被放在新建的单独的文件夹中,分别放在index,order,ticket,query中的index.js中。
在这里插入图片描述
在path中添加如下变量

appIndexJs: resolveModule(resolveApp, 'src/index/index'),
appQueryJs: resolveModule(resolveApp, 'src/query/index'),
appTicketJs: resolveModule(resolveApp, 'src/ticket/index'),
appOrderJs: resolveModule(resolveApp, 'src/order/index'),

③最后修改HtmlWebpackPlugin,生成四个不同的html引入这些入口打包后的文件。生成几个页面,就要配置几个HtmlWebpackPlugin,filename为最后的html名称,chunkwei所引用的打包文件。

      new HtmlWebpackPlugin(
        Object.assign(
          {},
          {
            inject: true,
            template: paths.appHtml,
            filename: 'index.html',
            chunk: ['index'],
          },
          isEnvProduction
            ? {
                minify: {
                  removeComments: true,
                  collapseWhitespace: true,
                  removeRedundantAttributes: true,
                  useShortDoctype: true,
                  removeEmptyAttributes: true,
                  removeStyleLinkTypeAttributes: true,
                  keepClosingSlash: true,
                  minifyJS: true,
                  minifyCSS: true,
                  minifyURLs: true,
                },
              }
            : undefined
        )
      ),
      new HtmlWebpackPlugin(
        Object.assign(
          {},
          {
            inject: true,
            template: paths.appHtml,
            filename: 'query.html',
            chunk: ['query'],
          },
          isEnvProduction
            ? {
                minify: {
                  removeComments: true,
                  collapseWhitespace: true,
                  removeRedundantAttributes: true,
                  useShortDoctype: true,
                  removeEmptyAttributes: true,
                  removeStyleLinkTypeAttributes: true,
                  keepClosingSlash: true,
                  minifyJS: true,
                  minifyCSS: true,
                  minifyURLs: true,
                },
              }
            : undefined
        )
      ),

在这里同样需要四个html模板,在public目录下创建,并在config/paths文件中指定路径。

  appHtml: resolveApp('public/index.html'),
  appQuery: resolveApp('public/query.html'),
  appTicket: resolveApp('public/ticket.html'),
  appOrder: resolveApp('public/iorder.html'),

三.运行打包命令
当配置完之后,运行打包命令,控制台报错,Cannot read property ‘filter’ of undefined,起初以为是entry里面的filter报错,后来发现entry里面就算不写filter也是会报错,最后定位到错误原因在ManifestPlugin
在这里插入图片描述
ManifestPlugin这个插件的作用是生成一份.json的文件,通过该文件的映射关系可以让我们知道webpack是如何追踪所有模块并映射到输出bundle中的。我们先来看原始的配置,这里fileName设置了输出文件名asset-manifest.json,publicPath设置了输出路径,最终要的是最后一个generate参数,自定义了输出的内容,里面有一段是取entrypoints.main,这是针对单一入口的配置,因为单一入口不指定name的情况默认name为main,当改成多入口的方式了之后这里面在entrypoints中自然是读取不到main这个值的,因此就报错,这里将generate这个参数去掉,恢复其默认值即可,或者将entrypoints这个key去掉。

 new ManifestPlugin({
    fileName: 'asset-manifest.json',
    publicPath: publicPath,
    generate: (seed, files, entrypoints) => {
      const manifestFiles = files.reduce((manifest, file) => {
        manifest[file.name] = file.path;
        return manifest;
      }, seed);
      const entrypointFiles = entrypoints.main.filter(
        fileName => !fileName.endsWith('.map')
      );
      return {
        files: manifestFiles,
        entrypoints: entrypointFiles,
      };
    },
  }),

如图所示为单入口的entrypoints对象
在这里插入图片描述
如图所示为打印出修改多入口后的的entrypoints对象
在这里插入图片描述

发布了38 篇原创文章 · 获赞 6 · 访问量 8569

猜你喜欢

转载自blog.csdn.net/qq_36400206/article/details/103074375