我可以关闭 create-react-app 分块机制吗?

Posted

技术标签:

【中文标题】我可以关闭 create-react-app 分块机制吗?【英文标题】:Can I turn off create-react-app chunking mechanism? 【发布时间】:2019-09-18 10:20:42 【问题描述】:

我正在使用 create-react-app 设置我的 React 应用项目。

我想知道是否有办法关闭内置于反应脚本中的分块机制。问题是我需要修复在构建中创建的包的名称。

【问题讨论】:

为什么一定要改名? 我正在开发 VS Code 扩展,我需要导入 bundle。所以,我需要知道它的名字。 【参考方案1】:

这可以通过使用react-app-rewired 包扩展你的 CRA 来完成,它允许你修改 webpack 配置。

删除构建文件名中的哈希所需的更改。

    安装 react-app-rewired

npm install react-app-rewired --save-dev

    在根文件夹(package.json 所在的位置)中创建 config-overrides.js 文件

    将以下代码放入config-overrides.js 文件中。它保留所有 CRA 设置,仅从文件名中删除哈希部分。

module.exports = 功能覆盖(配置,环境) 配置输出 = ...config.output, // 复制所有设置 文件名:“静态/js/[名称].js”, chunkFilename: "static/js/[name].chunk.js", ; 返回配置; ;
    使用新配置。在 scripts 部分的 package.json 文件中,将 "build": "react-scripts build", 替换为 "build": "react-app-rewired build",

除非您要更改更多配置,否则仅在build 中使用react-app-rewired 就足够了。否则在除eject以外的其他脚本中将react-scripts替换为react-app-rewired

【讨论】:

知道如何更改 CSS 资产吗? 同样的问题,如何更改 CSS 资源? 在下面查看我的答案以获取同时处理 css 和媒体文件的建议版本【参考方案2】:

我发现你可以通过设置splitChunks webpack 配置来禁用分块。更多详情请查看https://github.com/facebook/create-react-app/issues/5306#issuecomment-431431877

但是,这不会从包名称中删除 contenthash 部分,您仍然会在名称中包含该随机字符串。

要删除它,请转到您的 webpack.config 并编辑捆绑包名称

'static/js/[name].[contenthash:8].js' => 'static/js/[name].js'

【讨论】:

谢谢,您可能为我们节省了在项目中使用嵌入式 React 应用程序的能力。对于与在 iframe 中嵌入 React 应用程序相关的问题,它就像一个魅力。【参考方案3】:

这是 Darko 答案的扩展和改进版本。我创建它的主要目的是为那些对this comment 中提到的解决方案不完全满意并且没有耐心挖掘this comment 以更好的方式解决问题的人节省时间。

这种“hacky”方法的主要思想是动态重写标准react-scriptswebpack 配置并将其注入到原始脚本中。

为此,您需要从npmjs.org 安装rewire 包,如下所示:

npm install rewire --save-dev

然后您创建单独的构建脚本,该脚本将“包装”原始 react build 脚本并确保它会解除更正的 webpack 配置。常规方法是将此文件保存在./scripts 文件夹中。所以我们称之为./scripts/build.js。内容:

const rewire = require('rewire');
const path = require('path');

// Pointing to file which we want to re-wire — this is original build script
const defaults = rewire('react-scripts/scripts/build.js');

// Getting configuration from original build script
let config = defaults.__get__('config');

// If we want to move build result into a different folder, we can do that!
// Please note: that should be an absolute path!
config.output.path = path.join(path.dirname(__dirname), 'custom/target/folder');

// If we want to rename resulting bundle file to not have hashes, we can do that!
config.output.filename = 'custom-bundle-name.js';

// And the last thing: disabling splitting
config.optimization.splitChunks = 
    cacheGroups: 
        default: false,
    ,
;
config.optimization.runtimeChunk = false;

然后,我们应该在packages.json 中使用这个构建脚本而不是标准脚本,如下所示:

...
  "scripts": 
    "start": "react-scripts start",
    "build": "node ./scripts/build.js",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  ,
...

【讨论】:

【参考方案4】:

我不知道如何关闭分块,但你可以尝试实现你的目标

更新到最新的 react 和 react-dom ,运​​行 'yarn react@next react-dom@next'(或 npm 命令来做同样的事情)

您现在应该拥有最新的 React 版本 - 因此您可以使用 React.lazy/React.Suspense 进行代码拆分,使用钩子等等。

所以现在您可以使用(下面的组件或依赖项示例)命名您的块

 const MyComp = lazy(() =>   import(/* webpackChunkName: 'MyChunkNmame'
*/ './MyComp'), );

const myLib= await import(/* webpackChunkName: "myLib" */ 'myLib');

如果您在使用导入语法时遇到错误问题,您需要使用 babel-plugin-syntax-dynamic-import 插件。将“babel”字段放入你的包 json 中。

现在您可以命名您的块并实现代码拆分的最新方法 - 希望对您有所帮助。这是 React.lazy React.Suspense 的链接 - https://reactjs.org/blog/2018/10/23/react-v-16-6.html

【讨论】:

这不是我要找的,但是,谢谢。在某些情况下,命名块肯定会派上用场。实际上,我在 GitHub 上发现了一些类似问题的讨论。我会尽快写一个答案。【参考方案5】:

有一个hack不需要弹出

    yarn add --dev rewire

    在根目录下创建文件并命名为build-non-split.js

    用下面的代码填写:

    const rewire = require('rewire');
    const defaults = rewire('react-scripts/scripts/build.js');
    let config = defaults.__get__('config');
    
    config.optimization.splitChunks = 
        cacheGroups: 
            default: false,
        ,
    ;
    
    config.optimization.runtimeChunk = false;
    

    package.json 中的构建脚本更改为:

    "build": "node ./scripts/build-non-split.js",
    

    yarn build

【讨论】:

此解决方案的可能来源:github.com/facebook/create-react-app/issues/…【参考方案6】:

正如其他人指出的那样,您可以尝试使用react-app-rewired 而不是弹出。这是一个同时处理 css 和媒体文件的版本:

安装npm install react-app-rewired --save-dev后,我创建了一个config-overrides.js,内容如下:

module.exports = function override(config, env) 
    if (env !== "production") 
        return config;
    

    // Get rid of hash for js files
    config.output.filename = "static/js/[name].js"
    config.output.chunkFilename = "static/js/[name].chunk.js"

    // Get rid of hash for css files
    const miniCssExtractPlugin = config.plugins.find(element => element.constructor.name === "MiniCssExtractPlugin");
    miniCssExtractPlugin.options.filename = "static/css/[name].css"
    miniCssExtractPlugin.options.chunkFilename = "static/css/[name].css"

    // Get rid of hash for media files
    config.module.rules[1].oneOf.forEach(oneOf => 
        if (!oneOf.options ||  oneOf.options.name !== "static/media/[name].[hash:8].[ext]") 
            return;
        
        oneOf.options.name = "static/media/[name].[ext]"
    );

    return config;
;

【讨论】:

以上是关于我可以关闭 create-react-app 分块机制吗?的主要内容,如果未能解决你的问题,请参考以下文章

npx create-react-app 不工作“必须使用导入来加载 ES 模块:” [关闭]

使用 create-react-app 部署 github 页面时出现 React-router 问题 [关闭]

分块编码(Transfer-Encoding: chunked)

HTTP中分块编码(Transfer-Encoding: chunked)

分块读取csv文件进行处理

create-react-app 可以与 TypeScript 一起使用吗