ℹ️ 请在提 issue 之前确保 issue 是关于项目代码,而不是 我要怎么配置 Webpack。(配置相关的问题可以在 Stack Overflow 或者 Spectrum 上提问)。
- 🚨 2.0版本移除了rewire helper 功能
此工具可以在不 'eject' 也不创建额外 react-scripts 的情况下修改 create-react-app 内置的 webpack 配置,然后你将拥有 create-react-app 的一切特性,且可以根据你的需要去配置 webpack 的 plugins, loaders 等。
从 Create React App 2.0开始,这个仓库主要由社区“轻度”维护。
使用了 react-app-rewired 之后,等于你得到了项目的配置权,但这表示你的项目将无法得到 CRA 提供的配置“保证”,希望你知道自己要做什么。
"Stuff can break" — Dan Abramov https://twitter.com/dan_abramov/status/1045809734069170176
注意: 我个人使用next.js 或者 Razzle 都支持开箱即用的自定义 Webpack。
您可以尝试使用 customize-cra 来获得一组 CRA 2.0兼容的 rewirers,或任何旨在支持2.0的替代项目和分支:
- Rescripts,用于扩展 CRA 配置的替代框架(支持2.0+)
- react-scripts-rewired 为该项目的一个分支,旨在支持 CRA 2.0
- craco
使用 create-react-app 创建您的应用,然后 rewire
$ npm install react-app-rewired --save-dev
$ npm install [email protected] --save-dev
/* config-overrides.js */
module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}
+-- your-project
| +-- config-overrides.js
| +-- node_modules
| +-- package.json
| +-- public
| +-- README.md
| +-- src
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom",
"eject": "react-scripts eject"
}
注意:不用替换 eject
部分。工具中没有针对 eject
的配置替换,执行了 eject 命令会让工具失去作用(能找到这个插件我也相信你知道 eject 是干嘛的)。
$ npm start
$ npm run build
您可以为其设置自定义路径 config-overrides.js
如果您想要使用在 node_modules
中的第三方 config-overrides.js,您可以将以下内容添加到您的package.json
:
"config-overrides-path": "node_modules/some-preconfigured-rewire"
默认情况下,该 config-overrides.js
文件导出单个函数,以便在开发或生产模式下自定义 webpack 配置, 方便编译您的 react 应用程序。可以从该文件中导出一个包含最多三个字段的对象,每个字段都是一个函数。这种替代形式允许您自定义用于 Jest(在测试中)和 Webpack Dev Server 本身的配置。
此示例实现用于演示使用每个对象需要的函数。在此示例中,展示的功能是:
- 根据
.env
变量有条件地运行一些测试 - 设置用于 Development Server 的 https 证书,
.env
文件变量中指定的文件名。
module.exports = {
// The Webpack config to use when compiling your react app for development or production.
webpack: function(config, env) {
// ...add your webpack config
return config;
},
// The Jest config to use when running your jest tests - note that the normal rewires do not
// work here.
jest: function(config) {
// ...add your jest config customisation...
// Example: enable/disable some tests based on environment variables in the .env file.
if (!config.testPathIgnorePatterns) {
config.testPathIgnorePatterns = [];
}
if (!process.env.RUN_COMPONENT_TESTS) {
config.testPathIgnorePatterns.push('<rootDir>/src/components/**/*.test.js');
}
if (!process.env.RUN_REDUCER_TESTS) {
config.testPathIgnorePatterns.push('<rootDir>/src/reducers/**/*.test.js');
}
return config;
},
// The function to use to create a webpack dev server configuration when running the development
// server with 'npm run start' or 'yarn start'.
// Example: set the dev server to use a specific certificate in https.
devServer: function(configFunction) {
// Return the replacement function for create-react-app to use to generate the Webpack
// Development Server config. "configFunction" is the function that would normally have
// been used to generate the Webpack Development server config - you can use it to create
// a starting configuration to then modify instead of having to create a config from scratch.
return function(proxy, allowedHost) {
// Create the default config by calling configFunction with the proxy/allowedHost parameters
const config = configFunction(proxy, allowedHost);
// Change the https certificate options to match your certificate, using the .env file to
// set the file paths & passphrase.
const fs = require('fs');
config.https = {
key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'),
cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'),
ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'),
passphrase: process.env.REACT_HTTPS_PASS
};
// Return your customised Webpack Development Server config.
return config;
};
},
// The paths config to use when compiling your react app for development or production.
paths: function(paths, env) {
// ...add your paths config
return paths;
},
}
该 webpack
字段用于提供与 config-overrides.js 导出的单个函数的等效项。这是使用所有常用 rewire 的地方。它无法在测试模式下配置编译,因为测试模式根本无法通过 Webpack 运行(它在 Jest 中运行)。它也不能用于自定义用于在开发模式下提供页面的 Webpack Dev Server,因为 create-react-app 生成一个单独的 Webpack 配置,以便与使用不同函数和默认配置的 dev 服务器一起使用。
Webpack 不用于在测试模式下编译应用程序 - 而是使用 Jest。这意味着您的 webpack 配置自定义函数中指定的任何重连接都不会在测试模式下应用于您的项目。
React-app-rewired 自动允许您在文件的某个 jest
部分自定义 Jest 配置 package.json
,包括允许您设置在 create-react-app 通常会阻止您进行设置的配置字段。它还会自动设置 Jest,以便在运行测试之前使用 Babel 编译项目。Jest 的配置选项在 Jest 网站上单独记录。注意:配置数组和对象是合并的,而不是被覆盖。有关详细信息,请参阅#240和#241
如果想要将 Jest 插件或预设添加到 Babel 配置中,则需要在 package.json
文件内部里的babel
定义关于这些插件/预设。或者是在 .babelrc
中去定义。React-app-rewired 改变了 Jest 配置,以便在 Jest 编译您的 react 应用程序时使用这些定义文件来指定 Babel 选项。在 Babel 网站上单独记录了在 package.json
的 Babel 部分中或 .babelrc
使用的格式。
jest
在 module.exports 对象中的字段 config-overrides.js
用于指定可以调用的函数,以便以 package.json 文件的 jest 部分中不能的方式自定义 Jest 测试配置。例如,它允许您根据环境变量更改某些配置选项。此函数作为参数传递默认的 create-react-app Jest 配置,并且需要返回要使用的已修改的Jest配置。很多时候你只需要使用 package.json 文件的 jest 部分和 .babelrc
文件(或 package.json
中的 babel 部分)的组合就可以进行配置更改,而不需要提供这个 jest 函数 config-overrides.js
在开发模式下运行时,create-react-app 不会为 Development Server(提供应用程序页面的服务器)使用常用 Webpack 配置。这意味着您无法使用服务器的常规 webpack
在config-overrides.js
中的部分来更改 Development Server 设置,因为这些更改将不会应用。
与此相反,create-react-app 期望能够在需要时调用函数来生成 webpack dev 服务器。此函数提供了在 webpack dev 服务器中使用的 proxy 和 allowedHost 设置的参数(create-react-app 从package.json 文件中检索这些参数的值)。
React-app-rewired 提供了通过使用在 config-overrides.js
文件里 module.exports 出的对象 devServer
来覆盖此函数。它为 devServer 函数提供了一个包含默认 create-react-app 函数的参数,该函数通常用于生成 dev server 配置(它不能提供生成的配置版本,因为 react-scripts 直接调用生成函数)。React-app-rewired 需要接收 create-react-app 的替换函数作为返回值,然后用于生成 Development Server 配置(即返回值应该是一个新函数,它接受 proxy 和 allowedHost 的两个参数和本身作为参数,并返回 Webpack Development Server 配置)。原始的 react-scripts 函数被传递给config-overrides.js
中 devServer 函数,以便您可以自己轻松调用此方法,根据 create-react-app 使用的默认值生成初始 devServer 配置。
该 paths
字段用于为 create-react-app
传递到 webpack 和 jest 的路径提供覆盖。
一些第三方工具,比如 react-cosmos 依赖于你的 webpack 配置。您可以创建 webpack.config.js
文件,通过下列代码导出 rewired 配置:
const { paths } = require('react-app-rewired');
// require normalized overrides
const overrides = require('react-app-rewired/config-overrides');
const config = require(paths.scriptVersion + '/config/webpack.config.dev');
module.exports = overrides.webpack(config, process.env.NODE_ENV);
然后在工具配置中指向此文件。
此时,由于 create-react-app 包含该文件的方式,很难从默认文件 src/index.js
更改入口点。几个 create-react-app 脚本绕过了正常的 rewiring 过程。
这里有三种解决方法:
- 只需要从 src / index.js 文件中输入/导入所需的文件,例如:
require('./index.tsx');
- 使用自定义版本的 react-scripts 包来更改脚本本身内部的入口点 (例如. react-scripts-ts 对于typescript项目 - 请参阅下面有关如何使用 react-app-rewired 的自定义脚本版本).
- 重写
react-dev-utils/checkRequiredFiles
函数以始终返回 true(导致 create-react-app 不再尝试强制条目文件必须存在)
react-scripts
通过在命令行选项中指定脚本包的名称 --scripts-version
或 REACT_SCRIPTS_VERSION=<...>
通过环境进行设置,可以使用自定义版本的包和react-app-rewired。
使用脚本版本选项的工作示例是:
{
"scripts": {
"start": "react-app-rewired start --scripts-version react-scripts-ts",
"build": "react-app-rewired build --scripts-version react-scripts-ts",
"test": "react-app-rewired test --scripts-version react-scripts-ts --env=jsdom",
"eject": "react-scripts eject"
}
}
- config/env.js
- config/webpack.config.js
- config/webpackDevServer.config.js
- scripts/build.js
- scripts/start.js
- scripts/test.js
- scripts/utils/createJestConfig.js
- config/env.js
- config/webpack.config.dev.js
- config/webpack.config.prod.js
- config/webpackDevServer.config.js
- scripts/build.js
- scripts/start.js
- scripts/test.js
- scripts/utils/createJestConfig.js
React-app-rewired 会导入您的 config-overrides.js 文件而不使用 “.js” 扩展名。这意味着您可以选择创建一个名为 config-overrides
的目录在你的根目录中,并从该 index.js
目录中的默认文件中导出覆盖。
如果使用目录有多个自定义覆盖,则允许您将每个覆盖放在单独的文件中。演示这一点的示例模板可以在 Github 的 Guria / rewired-ts-boilerplate 中找到。
如果需要更改 config-overrides.js 的位置,可以将命令行选项 --config-overrides 给 react-app-rewired 脚本。
- react-app-rewire-emotion by @osdevisnot
- react-app-rewire-lodash by @osdevisnot
- react-app-rewire-styled-components by @mxstbr
- react-app-rewire-polished by @rawrmonstar
- react-app-rewire-idx by @viktorivarsson
- react-app-rewire-glamorous-displayname by @CarlRosell
- react-app-rewire-import by @brianveltman
- react-app-rewire-inline-import-graphql-ast by @detrohutt
- react-app-rewire-react-intl by @clemencov
- react-app-rewire-lingui by @andreyco
- react-app-rewire-date-fns by @stk-dmitry
- react-app-rewired-esbuild by @fupengl
- react-app-rewire-appcache-plugin by @jtheis85
- react-app-rewire-build-dev by @raodurgesh
- react-app-rewire-define-plugin by @jtheis85
- react-app-rewire-favicons-plugin by @rickycook
- react-app-rewire-imagemin-plugin by @jtheis85
- react-app-rewire-modernizr by @ctrlplusb
- react-app-rewire-preload-plugin by @jtheis85
- react-app-rewire-provide-plugin by @jtheis85
- react-app-rewire-inline-source by @marcopeg
- react-app-rewire-webpack-bundle-analyzer by @byzyk
- react-app-rewire-unplug by @sigged
- react-app-rewire-compression-plugin by @ArVan
- react-app-rewire-postcss
- react-app-rewire-nearley by @jtheis85
- react-app-rewire-coffeescript by @stevefan1999
- react-app-rewire-typescript by @jtheis85
- react-app-rewire-typescript-babel-preset by @strothj
- react-app-rewire-css-modules by @lnhrdt
- react-app-rewire-css-modules-extensionless by @moxystudio
- react-app-rewire-less-modules by @andriijas
- react-app-rewire-stylus-modules by @marcopeg
- react-app-rewire-svg-react-loader by @lnhrdt
- react-app-rewire-bem-i18n-loader by @maxvipon
- react-app-rewire-babel-loader by @dashed
- react-app-rewire-svgr by @gitim
- react-app-rewire-yaml by @hsz
- react-app-rewire-scss by @aze3ma
- react-app-rewire-external-svg-loader by @moxystudio
- react-app-rewire-typings-for-css-module by @rainx
- react-app-rewire-create-react-library by @osdevisnot
- react-app-rewire-react-library by @osdevisnot
- react-app-rewire-vendor-splitting by @andriijas
- react-app-rewired with Inferno
- react-app-rewired with react-styleguideist
- react-app-rewired with react-hot-loader by @cdharris
- react-app-rewire-alias by @oklas
- react-app-rewire-aliases by @aze3ma
- react-app-rewire-blockstack by @harrysolovay
- ideal-rewires by @harrysolovay
- react-app-rewire-yarn-workspaces by @viewstools
- react-app-rewired-single-spa by @fupengl
在开发此项目时,请确保已安装 yarn
要运行测试应用程序,请进入到该目录并运行:
yarn setup
yarn start
( 当你结束时,可以通过运行 yarn teardown 清理 )
以下列出了可帮助您进行开发的所有可用命令
yarn setup
- installs dependences and linkstest/react-app
yarn start
- starts the react appyarn build
- builds the react appyarn test
- tests the react appyarn teardown
- unlinkstest/react-app
and removes dependencies