使用create-react-app的多个入口点

时间:2018-11-26 11:23:17

标签: reactjs jsx create-react-app entry-point

我有一个页面,其中包含20%的React组件和80%的常规html内容。有必要在页面的不同位置放置几个反应组件,因此我在index.html中需要多个入口点。我想使用create-react-app,但是我不想使用redux,因为页面很小。有什么方法可以相对容易地在index.html中创建2个入口点,以便页面上的所有React组件都可以访问单亲的道具? ..还是可以将全局变量与事件侦听器一起使用,以进行更改,从而触发更新不同入口点中的react组件? ..请告诉我执行此类任务的最佳做法,因为我不想从单个入口使用jsx来开发整个页面。

3 个答案:

答案 0 :(得分:1)

我知道这是一个延迟的答案,但是为了以后的搜索,步骤是:

  1. 弹出(yarn eject
  2. 编辑path.js并在appHtml条目下添加第二个入口点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)
},
  1. 将生成的输出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. 更新ManifestPlugin configuration to include the new entry point (also inside webpack.config.js`):
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' },
  ]
},

由于Prod服务器的设置可能大不相同,因此我会让您弄清楚。

This post详细介绍了所有内容。

答案 1 :(得分:0)

为避免弹出,您可能需要检查rescripts,可以像下面这样添加要添加到index.html的入口点:

在项目主目录中创建.rescriptsrc.js文件:

module.exports = [
  config => {
      config.entry = {
         app: ["./src/index.js"],
         content: ["./src/content.js"],
      };
  }
];

答案 2 :(得分:0)

添加多个入口点需要修改默认的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" />