将反应构建输出合并到单个 js 文件中 [英] combine react build output into single js file

查看:20
本文介绍了将反应构建输出合并到单个 js 文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这类似于这个问题两个答案都不能解决问题.

运行 npm run build 后,结果 index.html 看起来类似于:

<script src="/static/js/2.3f294f32.chunk.js"></script><script src="/static/js/main.7b9daa35.chunk.js"></script>

这可行,但我想将所有 3 个文件合并为一个文件

我试过 filesmerge.com 来合并 JS 文件,但这会导致引用单个文件时出错:

output.min.js:1 Uncaught TypeError: (intermediate value)(...) is not a function在 output.min.js:1

然后我尝试使用 jscompress.com 进行组合,虽然这不会产生任何错误,但不会呈现反应根元素

我也尝试过这个解决方案建议在 create-react-app 存储库上不起作用.没有产生错误但没有呈现反应元素(页面保持空白)

解决方案

Brief

简而言之:这是可能的,但不是很实用.为什么?随着单个捆绑文件的增长,您的应用程序将不再具有性能.单个大请求,而不是较小的请求,将不可避免地导致 Web 性能下降并可能浪费带宽.

同样,我强烈建议不要将 CRA 用于您的单捆绑应用.虽然 CRA 是一个很棒的样板,它面向 DX 友好的 React with Webpack 方法,但它确实包含许多可能不必要地与您的应用捆绑在一起的依赖项.

因此,我强烈推荐构建您自己的 Webpack 配置(借助 Webpack 文档 结合 CRA Webpack 说明)或考虑替代方案,例如 rollup, gulp, microbundlebrowserify 仅举几例.>

随着 CRA 的更新,以下程序不可避免地会过时.因此,请自行承担使用这些说明的风险.

程序

CRA 版本:v4.0.3

您首先要弹出:yarn ejectnpm run eject -- 您可能可以使用一些 3rd 方包来覆盖而不弹出,但我会让你自己去弄清楚.

然后,您需要转到 config/webpack.config.js 文件并更改以下内容:

  • 从顶级导入中移除 InlineChunkHtmlPlugin 导入,并在 plugins 下移除 isEnvProduction &&shouldInlineRuntimeChunk &&new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]) 因为它在构建时在 index.html 文件中创建了一个块文件列表
  • plugins 下,通过将 filename 更改为 filename: "static/将 MiniCssExtractPlugin 选项更改为仅输出单个 css 文件css/bundle.min.css" 并删除 chunkFileName 选项.
  • 输出下,将文件名更改为文件名:static/js/bundle.min.js"以输出到单个文件名用于生产.
  • output 下,删除 chunkFilename 属性,因为您不再分块 JS 文件
  • 优化下,删除splitChunks属性,因为您不再拆分JS块
  • 优化下,将runtimeChunk设置为runtimeChunk:false以避免创建runtime.chunk.js文件
  • 优化下,在TerserPlugin之后,添加new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) 以限制输出块为1

演示

CRA 版本:v4.0.3(演示更新至 2021 年 5 月 25 日)

工作仓库:https://github.com/mattcarlotta/cra-single-bundle

注意事项

随着开发世界采用 Webpack 5,此配置将不可避免地过时

This is similar to this question however neither of the answers solves the problem.

After running npm run build the resultant index.html looks similar to:

<script>!function (i) { function e(e) { for //rest omitted
<script src="/static/js/2.3f294f32.chunk.js"></script>
<script src="/static/js/main.7b9daa35.chunk.js"></script>

The first <script> element is inlined javascript that i have extracted to a file called loader.js

<script src="/loader.js"></script>
<script src="/static/js/2.3f294f32.chunk.js"></script>
<script src="/static/js/main.7b9daa35.chunk.js"></script>

this works but I would like to combine all 3 files into a single file

I've tried filesmerge.com to combine the JS files but this results in an error when referencing the single file:

output.min.js:1 Uncaught TypeError: (intermediate value)(...) is not a function
at output.min.js:1

I then tried combining using jscompress.com and whilst this does not produce any errors the react root element is not rendered

I've also tried this solution suggested on the create-react-app repo which does not work. No error is produced but no react element is rendered (page remains blank)

解决方案

Brief

In short: It's possible, but not very practical. Why? Your application will no longer be performant as your single bundle file grows. A single large request, instead of smaller requests, will inevitably lead to slower web performance and potentially wasted bandwidth.

On that same note, I'd highly advise against using the CRA for your single-bundled application. While the CRA is a great boilerplate geared toward a DX friendly approach to React with Webpack, it does contain a lot of dependencies that may be unnecessarily bundled with your app.

As such, I'd highly recommend building your own Webpack configuration (it's relatively simple with the help of the Webpack documentation combined with the CRA Webpack notes) or consider alternatives like rollup, gulp, microbundle, or browserify to name a few.

The following procedure below will inevitably become outdated as the CRA gets updated. Therefore, use these instructions at your own risk.

Procedure

CRA Version: v4.0.3

You'll first want to eject: yarn eject or npm run eject -- you can probably use some 3rd party packages to override without ejecting, but I'll leave that up to you to figure out.

Then, you'll need to go to the config/webpack.config.js file and change the following:

  • Remove the InlineChunkHtmlPlugin import from top imports and under plugins, remove isEnvProduction && shouldInlineRuntimeChunk && new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]) as it creates a chunk file list inside the index.html file when building
  • Under plugins, change MiniCssExtractPlugin options to only output a single css file by changing filename to filename: "static/css/bundle.min.css" and removing the chunkFileName option.
  • Under output, change filename to filename: "static/js/bundle.min.js" to output to a single filename for production.
  • Under output, remove the chunkFilename property as you're no longer chunking JS files
  • Under optimization, remove splitChunks property as you're no longer splitting JS chunks
  • Under optimization, set runtimeChunk to runtimeChunk: false to avoid creating a runtime.chunk.js file
  • Under optimization, after the TerserPlugin, add new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) to limit outputted chunks to 1

Demo

CRA Version: v4.0.3 (demo updated as May 25th, 2021)

Working repo: https://github.com/mattcarlotta/cra-single-bundle

Notes

This configuration will inevitably become outdated as the dev world adopts Webpack 5

这篇关于将反应构建输出合并到单个 js 文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆