使用 create-react-app 时使用自定义构建输出文件夹

Posted

技术标签:

【中文标题】使用 create-react-app 时使用自定义构建输出文件夹【英文标题】:Use custom build output folder when using create-react-app 【发布时间】:2017-05-20 14:57:44 【问题描述】:

Facebook 提供了一个 create-react-app command 来构建 React 应用程序。当我们运行npm run build 时,我们会在/build 文件夹中看到输出。

npm 运行构建

将用于生产的应用程序构建到 build 文件夹。它正确 在生产模式下捆绑 React 并优化构建以获得最佳效果 性能。

构建被缩小,文件名包含哈希。你的应用 已准备好部署!

我们如何使用自定义文件夹而不是/build 进行输出?谢谢。

【问题讨论】:

查看question 并尝试将“build”更改为“whatever”。没试过。 现在官方支持了,向下滚动到***.com/a/62378644/214446 【参考方案1】:

编辑:支持可配置的 BUILD_PATH 刚刚登陆 v4.0.2。见t_dom93's answer。

您无法使用当前配置选项更改构建输出文件夹名称。

此外,您不应该这样做。这是the philosophy behind create-react-app 的一部分:他们说Convention over Configuration

如果您确实需要重命名文件夹,我看到两个选项:

    在构建过程完成后,编写一个命令,将构建文件夹内容复制到您想要的另一个文件夹。例如,您可以try the copyfiles npm package,或任何类似的东西。

    您可以尝试eject create-react-app 并调整配置。

如果您对构建工具和配置选择不满意,您可以随时弹出。此命令将从您的项目中删除单个构建依赖项。

相反,它会将所有配置文件和传递依赖项(Webpack、Babel、ESLint 等)直接复制到您的项目中,以便您完全控制它们。除弹出之外的所有命令仍然有效,但它们将指向复制的脚本,以便您可以调整它们。此时,您只能靠自己了。

但是,需要注意的是,这是一种单向操作。一旦弹出,就无法返回!您将丢失所有未来的更新。

因此,如果可能,我建议您不要使用自定义文件夹命名。尝试使用默认命名。如果不是一个选项,请尝试#1。如果它仍然不适用于您的特定用例并且您真的没有选择 - 探索#2。祝你好运!

【讨论】:

复制文件比重命名文件夹有什么优势? 我主要担心的是,如果任何其他react-create-app 命令使用/build 文件夹进行输入,它可能会导致麻烦。 (例如:在部署过程中)。所以复制是我看到的最安全的选择。 PS:如果没有计划使用默认的/build 文件夹进行输入,我同意你的看法 - 只需重命名它就可以达到同样的效果。 约定优于配置的问题是如果您有多个冲突约定。 IE 我们在 Angular 应用程序中使用 react。所以只有最终的构建应该进入构建并且反应只创建中间文件。 这已登陆版本v4.0.2。工作示例:***.com/a/66036117/6774916 “约定优于配置”并不意味着不灵活。【参考方案2】:

您可以在根目录下通过一些小技巧来更新配置:

    npm 运行弹出 config/webpack.config.prod.js - 第 61 行 - 将路径更改为:__dirname + './../--您选择的目录--' config/paths.js - 第 68 行 - 更新为 resolveApp('./--your directory of choice--')

用你想要构建的文件夹目录替换--你选择的目录

请注意,我提供的路径可能有点脏,但这就是您修改配置所需要做的一切。

【讨论】:

【参考方案3】:

编辑你的 package.json:

"build": "react-scripts build && mv build webapp"

【讨论】:

我必须把它设为"build": "react-scripts build && rm -rf docs && mv build docs" 否则在第一次运行后它会将构建移动到 docs 文件夹而不是覆盖它。 Windows rm -rf webapp = DEL /S /Q webappmv build webapp = move build webapp 的等效命令 如果您不想移动构建文件夹,只需复制其文件即可。等效于 Windows 的命令:mv build webapp = xcopy /E /H /C /I build webapp 如果你想在 webapp 而不是 webapp/build 上移动,Windows 的命令是 "build": "react-scripts build && RMDIR /S /Q webapp && move build webapp" 要让它跨平台(包括 Windows)运行,首先使用 npm i --save-dev cross-env 安装一个名为 cross-env 的 npm 包。然后,在你的 package.json 中:"build": "cross-env react-scripts build && mv build webapp"【参考方案4】:

Félix 的回答是正确的,并且得到了Dan Abramov himself 的支持。

但是对于那些想要更改输出本身结构的人(在build 文件夹内),可以在postbuild 的帮助下运行构建后命令,它会在build 脚本之后自动运行在package.json 文件中定义。

以下示例将其从static/ 更改为user/static/,移动文件并更新相关文件上的文件引用 (full gist here):

package.json


  "name": "your-project",
  "version": "0.0.1",
  [...]
  "scripts": 
    "build": "react-scripts build",
    "postbuild": "./postbuild.sh",
    [...]
  ,

postbuild.sh

#!/bin/bash

# The purpose of this script is to do things with files generated by
# 'create-react-app' after 'build' is run.
# 1. Move files to a new directory called 'user'
#    The resulting structure is 'build/user/static/<etc>'
# 2. Update reference on generated files from
#    static/<etc>
#     to
#    user/static/<etc>
#
# More details on: https://github.com/facebook/create-react-app/issues/3824

# Browse into './build/' directory
cd build
# Create './user/' directory
echo '1/4 Create "user" directory'
mkdir user
# Find all files, excluding (through 'grep'):
# - '.',
# - the newly created directory './user/'
# - all content for the directory'./static/'
# Move all matches to the directory './user/'
echo '2/4 Move relevant files'
find . | grep -Ev '^.$|^.\/user$|^.\/static\/.+' | xargs -I mv -v  user
# Browse into './user/' directory
cd user
# Find all files within the folder (not subfolders)
# Replace string 'static/' with 'user/static/' on all files that match the 'find'
# ('sed' requires one to create backup files on OSX, so we do that)
echo '3/4 Replace file references'
find . -type f -maxdepth 1 | LC_ALL=C xargs -I sed -i.backup -e 's,static/,user/static/,g' 
# Delete '*.backup' files created in the last process
echo '4/4 Clean up'
find . -name '*.backup' -type f -delete
# Done

【讨论】:

"postbuild": "postbuild.sh" (没有 ./) 对我有用,至少在 Windows 中是这样 耻辱你必须践踏build然后移动/重命名它。【参考方案5】:

我有这样的场景,比如想要重命名文件夹并更改构建输出位置,并使用最新版本的 package.json 中的以下代码

"build": "react-scripts build && mv build ../my_bundles"

【讨论】:

这在将build 的内容复制到docs 目录中以使用github 页面托管时非常有用,最终使用"build-docs": "react-scripts build &amp;&amp; cp -r build/** docs"【参考方案6】:

Create-react-app 版本 2+ 答案

对于 create-react-app 的最新 (> v2) 版本(以及可能更旧的版本),将以下行添加到您的 package.json,然后重新构建。

"homepage": "./"

您现在应该看到 build/index.html 将具有相对链接 ./static/... 而不是指向服务器根目录的链接:/static/...

【讨论】:

谢谢。这应该是公认的答案。如果您不使用绝对 URL,VS Code 会警告您,但构建也适用于相对 URL。 这正是我想要的。谢谢【参考方案7】:

Windows Powershell 脚本

//package.json
"scripts": 
    "postbuildNamingScript": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./powerShellPostBuildScript.ps1",


// powerShellPostBuildScript.ps1
move build/static/js build/new-folder-name 
(Get-Content build/index.html).replace('static/js', 'new-folder-name') | Set-Content 
build/index.html
"Finished Running BuildScript"

在 powershell 中运行 npm run postbuildNamingScript 会将 JS 文件移动到 build/new-folder-name 并从 index.html 指向新位置。

【讨论】:

【参考方案8】:

根据Ben Carp 和Wallace Sidhrée 的回答:

这是我用来将整个构建文件夹复制到我的 wamp 公用文件夹的内容。

package.json


  "name": "[your project name]",
  "homepage": "http://localhost/[your project name]/",
  "version": "0.0.1",
  [...]
  "scripts": 
    "build": "react-scripts build",
    "postbuild": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./post_build.ps1",
    [...]
  ,

post_build.ps1

Copy-Item "./build/*" -Destination "C:/wamp64/www/[your project name]" -Recurse -force

仅当您要部署到服务器上的子文件夹时才需要主页行(参见另一个问题中的This answer)。

【讨论】:

【参考方案9】:

在应用程序的源代码中打开命令提示符。 运行命令

npm 运行弹出

打开您的 scripts/build.js 文件并将其添加到文件开头的“use strict”行之后

'use strict';
....
process.env.PUBLIC_URL = './' 
// Provide the current path
.....

打开您的 config/paths.js 并将导出对象中的 buildApp 属性修改为您的目标文件夹。 (这里,我提供 'react-app-scss' 作为目标文件夹)

module.exports = 
.....
appBuild: resolveApp('build/react-app-scss'),
.....

运行

npm 运行构建

注意:不建议运行依赖于平台的脚本

【讨论】:

【参考方案10】:

webpack =>

重命名为build to dist

output: 
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
    ,

【讨论】:

【参考方案11】:

快速兼容性构建脚本(也适用于 Windows):

"build": "react-scripts build && rm -rf docs && mv build docs"

【讨论】:

【参考方案12】:

对于仍在寻找适用于 Linux 和 Windows 的答案的任何人:

将此添加到package.json 中的scripts 部分

"build": "react-scripts build && mv build ../docs || move build ../docs",

../docs 是您要将构建文件夹移动到的相对文件夹

【讨论】:

【参考方案13】:

使用react-scripts &gt;= 4.0.2,这是officially supported:

默认情况下,Create React App 会将编译后的资产输出到与/src 相邻的/build 目录。您可以使用此变量为 Create React App 指定输出资产的新路径。 BUILD_PATH 应指定为相对于项目根目录的路径。

// package.json
  "scripts": 
    "build": "BUILD_PATH='./dist' react-scripts build",
    // ...
  ,

或将 .env 文件添加到项目的根目录:

# .env
BUILD_PATH='./dist'

注意BUILD_PATH 中指定的路径将被毫不留情地清除。仔细检查您的环境变量是否指定正确,尤其是在使用持续集成时。

【讨论】:

我希望它进入!他们拒绝支持,这真是太烦人了。 此配置今天发布,版本为 4.0.2,位于高级配置文档和变更日志中。 这个解决方案很棒! 重要警告 在编写 BUILD_PATH 时,请确保您编写的路径不存在,或者您不介意被删除。做BUILD_PATH='..' 对我在项目上取得的进展造成了严重损害。 (它也删除了 git。)【参考方案14】:

BUILD_PATH 的支持刚刚登陆v4.0.2。

BUILD_PATH 变量添加到.env 文件并运行build 脚本命令:

// .env file
BUILD_PATH=foo 

这应该将所有构建文件放入foo 文件夹中。

【讨论】:

太棒了。使用 BUILD_PATH=../dist 按预期工作【参考方案15】:

Windows 的移动命令对我不起作用。因为它不复制“静态”文件夹和子文件夹。所以我能够使用“ROBOCOPY”解决这个问题。

"build": "react-scripts build && ROBOCOPY build ../my-relative-path/react-app /E",

【讨论】:

【参考方案16】:

这是我的解决方案: 在根目录下创建 .env,然后添加这一行。

BUILD_PATH=$npm_package_name-$npm_package_version

构建路径将是“name_of_app”-“version”

这些值可以在 package.json 中设置


  "name": "my-app",
  "version": "0.1.2",
...

【讨论】:

【参考方案17】:

使用 cross-env 是解决方案。

安装跨环境:

npm install cross-env

你应该更新到:

"scripts": 
  "build": "cross-env BUILD_PATH='../yourCustomBuildFolder' react-scripts build",

【讨论】:

我收到了 BUILD_PATH notrecognized 错误,但在应用了你所说的之后,我的问题就解决了。

以上是关于使用 create-react-app 时使用自定义构建输出文件夹的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用来自另一个 URL 的图像时使用 create-react-app 的 CORS 问题

使用 create-react-app 时使用自定义构建输出文件夹

使用 create-react-app 时,代码拆分会增加入口包大小

使用 typescript 模板将 create-react-app 更新到 4.0 时出错

在开发模式下使用 create-react-app 时如何将应用程序放在子文件夹中?

在 React 中导入 Framer Motion v5 时出错(使用 create-react-app)