使用create-react-app实现多个入口点

3
我有一个页面,其中20%是React组件,80%是普通的HTML内容。需要在页面的不同位置放置几个React组件,因此我需要在index.html中设置几个入口点。我想使用create-react-app,但是由于页面相对较小,不想使用redux。有没有相对容易的方法在index.html中创建2个入口点,以便页面上的所有React组件都可以访问单个父项的props?或者是否可以使用全局变量和事件监听器来触发不同入口点的React组件更新其变化?请告诉我这些任务的最佳做法,因为我不想通过从单个入口点使用JSX来开发整个页面。
3个回答

1
我知道我的回答有点晚了,但是为了以后的搜索,这是步骤:
  1. 弹出 (yarn eject)
  2. 编辑 paths.js 并在 appHtml 的入口下添加第二个入口 html 文件
请保留 HTML 标签。
appAdminHtml: resolveApp('public/admin.html'),
  1. webpack.config.js 中更新条目,每个入口点包含一个条目。
entry: {
  index: [
    isEnvDevelopment &&
    require.resolve('react-dev-utils/webpackHotDevClient'),
    paths.appIndexJs,
  ].filter(Boolean),
  admin: [
    isEnvDevelopment &&
    require.resolve('react-dev-utils/webpackHotDevClient'),
    paths.appSrc + '/admin/index.js',
  ].filter(Boolean)
},

4. 将生成的输出JS文件更改为入口文件的名称(在webpack.config.js内)。
output: {
  path: isEnvProduction ? paths.appBuild : undefined,
  pathinfo: isEnvDevelopment,
  // This is the important entry
  filename: isEnvProduction
    ? 'static/js/[name].[contenthash:8].js'
    : isEnvDevelopment && 'static/js/[name].bundle.js',
  futureEmitAssets: true,
  chunkFilename: isEnvProduction
    ? 'static/js/[name].[contenthash:8].chunk.js'
    : isEnvDevelopment && 'static/js/[name].chunk.js',
  publicPath: publicPath,
  devtoolModuleFilenameTemplate: isEnvProduction
    ? info =>
        path
          .relative(paths.appSrc, info.absoluteResourcePath)
          .replace(/\\/g, '/')
    : isEnvDevelopment &&
      (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
  jsonpFunction: `webpackJsonp${appPackageJson.name}`,
  globalObject: 'this',
},
  1. 更新插件以生成注入js脚本的第二个文件(也在webpack.config.js中)。
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
  Object.assign(
    {},
    {
      inject: true,
      chunks: ['index'],
      template: paths.appHtml,
      filename: 'index.html'
    },
    isEnvProduction
      ? {
          minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeRedundantAttributes: true,
            useShortDoctype: true,
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true,
            minifyJS: true,
            minifyCSS: true,
            minifyURLs: true,
          },
        }
      : undefined
  )
),
// Generates an `admin.html` file with the <script> injected.
new HtmlWebpackPlugin(
  Object.assign(
    {},
    {
      inject: true,
      chunks: ['admin'],
      template: paths.appAdminHtml,
      filename: 'admin.html',
    },
    isEnvProduction
      ? {
          minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeRedundantAttributes: true,
            useShortDoctype: true,
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true,
            minifyJS: true,
            minifyCSS: true,
            minifyURLs: true,
          },
        }
      : undefined
  )
),
  1. 更新`webpack.config.js`中的`ManifestPlugin`配置,包括新的入口点:
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);
    let entrypointFiles = [];
    for (let [entryFile, fileName] of Object.entries(entrypoints)) {
      let notMapFiles = fileName.filter(fileName => !fileName.endsWith('.map'));
      entrypointFiles = entrypointFiles.concat(notMapFiles);
    };
    return {
      files: manifestFiles,
      entrypoints: entrypointFiles,
    };
  },
}),
  1. 将您的服务器(开发和生产)更新以重写路径。
    • 对于开发服务器,您需要更新webpackDevServer.config.js
historyApiFallback: {
  disableDotRule: true,
  verbose: true,
  rewrites: [
    { from: /^\/admin/, to: '/admin.html' },
  ]
},

由于生产服务器设置可能会有很大的不同,我会让你自己解决。

这篇文章更详细地描述了一切。


1
为了避免弹出,您可能希望查看rescripts,您可以添加入口点以添加到index.html中,如下所示:
在项目的主目录中创建.rescriptsrc.js文件:
module.exports = [
  config => {
      config.entry = {
         app: ["./src/index.js"],
         content: ["./src/content.js"],
      };
  }
];

1
我在条目中没有定义main遇到了一些问题,rescripts给了我一个错误提示,但是我将其定义为虚拟/存根,并稍微调整了webpack配置,最终达到了我想要的结果。 - Alex
@Alex 可能想在他们的 Github 上创建一个问题,开发者非常乐于帮助。 - K41F4r
我曾要求提供一些使用多个条目的示例,但他们建议我在这里发布。我认为问题更多地出现在 CRA 基础设施中,有一个开放问题需要支持多个条目,但这需要时间。 - Alex

0

添加多个入口点需要修改默认的react-scripts配置。弹出(即从react-scripts中提取所有配置并自行管理)是一种方法。

弹出允许您自定义任何内容,但从那时起,您必须自行维护配置和脚本。如果您有许多类似的项目,则在这种情况下,我们建议分叉react-scripts和您需要的任何其他软件包。

请访问https://create-react-app.dev/docs/alternatives-to-ejecting了解详情。

当我遇到这个问题时,我创建了一个脚本分支,并在https://www.npmjs.com/package/@linsight/react-scripts上提供了它。请尝试一下。

请记得更新react-app-env.d.ts文件为:

/// <reference types="@linsight/react-scripts" />


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接