使用 create-react-app 的多个入口点
Posted
技术标签:
【中文标题】使用 create-react-app 的多个入口点【英文标题】:multiple entry points by using create-react-app 【发布时间】:2019-04-28 00:52:24 【问题描述】:我有一个包含 20% 的 React 组件和 80% 的普通 html 内容的页面。需要在页面的不同点放置多个 React 组件,因此我需要 index.html 中的多个入口点。我想使用 create-react-app,但我不想使用 redux,因为页面很小。有没有相对容易的方法在 index.html 中创建 2 个入口点,以便页面上的所有反应组件都可以访问单亲的道具? .. 或者是否可以将全局变量与事件侦听器一起使用来进行更改,从而触发更新不同入口点中的反应组件? .. 请告诉我此类任务的最佳实践,因为我不想从单个入口点使用 jsx 开发整个页面。
【问题讨论】:
【参考方案1】:添加多个入口点需要修改默认的react-scripts
配置。弹出(即从react-scripts
提取所有配置并自行管理)是一种方法。
弹出允许您自定义任何内容,但从那时起,您必须自己维护配置和脚本。如果您有许多类似的项目,这可能会令人生畏。在这种情况下,我们建议不要退出,而是 fork 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" />
【讨论】:
【参考方案2】:我知道这是一个延迟的答案,但只是为了将来的搜索,步骤是:
-
弹出 (
yarn eject
)
编辑paths.js,在appHtml的入口下添加第二个入口点html文件
appAdminHtml: resolveApp('public/admin.html'),
-
更新
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)
,
-
将生成的输出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',
,
-
更新插件以使用注入的 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
)
),
-
更新
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,
;
,
),
-
更新您的服务器(开发和生产)以重写路径。
对于开发服务器,您需要更新
webpackDevServer.config.js
。
historyApiFallback:
disableDotRule: true,
verbose: true,
rewrites: [
from: /^\/admin/, to: '/admin.html' ,
]
,
由于 Prod 服务器设置可能完全不同,我会让你弄清楚。
This post 更详细地描述了所有内容。
【讨论】:
【参考方案3】:为避免弹出您可能需要检查rescripts,您可以像这样添加要添加到 index.html 的入口点:
在项目主目录中创建 .rescriptsrc.js 文件:
module.exports = [
config =>
config.entry =
app: ["./src/index.js"],
content: ["./src/content.js"],
;
];
【讨论】:
我有一些问题没有在条目中定义main
,rescripts 给了我一个错误,但是将它定义为 dummy/stub 并稍微操纵了 webpack 配置,我设法得到了我正在寻找的结果为。
@Alex 可能想在他们的 github 上创建一个问题,开发人员非常有帮助
我要求提供一些使用多个条目的示例,但他们建议我在此处发布。我认为问题更多在于 CRA 基础架构,支持多个条目存在一个未解决的问题,但这需要时间。以上是关于使用 create-react-app 的多个入口点的主要内容,如果未能解决你的问题,请参考以下文章