@0xaio/react-dev-utils 中文文档教程
react-dev-utils
此软件包包含 Create React App 使用的一些实用程序。
请参阅其文档:
- Getting Started – How to create a new app.
- User Guide – How to develop apps bootstrapped with Create React App.
Usage in Create React App Projects
这些实用程序默认随 Create React App 一起提供,默认包含它。 您不需要在 Create React App 项目中单独安装它。
Usage Outside of Create React App
如果您不使用 Create React App,或者如果您 ejected,您可以继续使用这些实用程序。 他们的开发将与 Create React App 保持一致,因此这些实用程序的主要版本可能会相对频繁地出现。 如果您想更好地控制它们,或者随意使用旧版本,请随意将它们分叉或复制并粘贴到您的项目中。 并非所有这些都是特定于 React 的,但我们可能会在未来使它们中的一些更特定于 React。
Entry Points
没有单一的入口点。 您只能导入单个顶级模块。
new InterpolateHtmlPlugin(replacements: {[key:string]: string})
这个 Webpack 插件让我们可以将自定义变量插入到 index.html
中。
它通过其 事件。
var path = require('path');
var HtmlWebpackPlugin = require('html-dev-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
// Webpack config
var publicUrl = '/my-custom-url';
module.exports = {
output: {
// ...
publicPath: publicUrl + '/'
},
// ...
plugins: [
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
// You can pass any key-value pairs, this was just an example.
// WHATEVER: 42 will replace %WHATEVER% with 42 in index.html.
}),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: path.resolve('public/index.html'),
}),
// ...
],
// ...
}
new ModuleScopePlugin(appSrc: string, allowedFiles?: string[])
这个 Webpack 插件确保从应用程序源目录的相对导入不会到达它之外。
var path = require('path');
var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
module.exports = {
// ...
resolve: {
// ...
plugins: [
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
// ...
],
// ...
},
// ...
}
new WatchMissingNodeModulesPlugin(nodeModulesPath: string)
这个 Webpack 插件确保 npm install
强制重建项目。
我们不确定为什么这不是 Webpack 的默认行为。
有关详细信息,请参阅 #186。
var path = require('path');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
// Webpack config
module.exports = {
// ...
plugins: [
// ...
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
new WatchMissingNodeModulesPlugin(path.resolve('node_modules'))
],
// ...
}
checkRequiredFiles(files: Array<string>): boolean
确保所有传递的文件都存在。
文件名应该是绝对的。
如果未找到文件,则打印一条警告消息并返回 false
。
var path = require('path');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
if (!checkRequiredFiles([
path.resolve('public/index.html'),
path.resolve('src/index.js')
])) {
process.exit(1);
}
clearConsole(): void
清除控制台,希望以跨平台的方式。
var clearConsole = require('react-dev-utils/clearConsole');
clearConsole();
console.log('Just cleared the screen!');
eslintFormatter(results: Object): string
这是我们的自定义 ESLint 格式化程序,可以很好地与 Create React App 控制台输出集成。
如果您愿意,可以使用默认值。
const eslintFormatter = require('react-dev-utils/eslintFormatter');
// In your webpack config:
// ...
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
options: {
// Pass the formatter:
formatter: eslintFormatter,
},
},
],
}
]
}
FileSizeReporter
measureFileSizesBeforeBuild(buildFolder: string): Promise<OpaqueFileSizes>
捕获传递的 buildFolder
中的 JS 和 CSS 资产大小。 保存结果值以便在构建后进行比较。
printFileSizesAfterBuild(webpackStats: WebpackStats, previousFileSizes: OpaqueFileSizes, buildFolder: string, maxBundleGzipSize?: number, maxChunkGzipSize?: number)
在构建后打印 JS 和 CSS 资产大小,并包括与之前使用 measureFileSizesBeforeBuild()
捕获的 previousFileSizes
的大小比较。 maxBundleGzipSize
和 maxChunkGzipSizemay
可以选择指定以在主包或块超过指定大小时(以字节为单位)时显示警告。
var {
measureFileSizesBeforeBuild,
printFileSizesAfterBuild,
} = require('react-dev-utils/FileSizeReporter');
measureFileSizesBeforeBuild(buildFolder).then(previousFileSizes => {
return cleanAndRebuild().then(webpackStats => {
printFileSizesAfterBuild(webpackStats, previousFileSizes, buildFolder);
});
});
formatWebpackMessages({errors: Array<string>, warnings: Array<string>}): {errors: Array<string>, warnings: Array<string>}
从 webpack stats 对象中提取并美化警告和错误消息。
var webpack = require('webpack');
var config = require('../config/webpack.config.dev');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var compiler = webpack(config);
compiler.plugin('invalid', function() {
console.log('Compiling...');
});
compiler.plugin('done', function(stats) {
var rawMessages = stats.toJson({}, true);
var messages = formatWebpackMessages(rawMessages);
if (!messages.errors.length && !messages.warnings.length) {
console.log('Compiled successfully!');
}
if (messages.errors.length) {
console.log('Failed to compile.');
messages.errors.forEach(e => console.log(e));
return;
}
if (messages.warnings.length) {
console.log('Compiled with warnings.');
messages.warnings.forEach(w => console.log(w));
}
});
printBuildError(error: Object): void
美化一些已知的构建错误。 传递错误对象以在控制台中记录美化的错误消息。
const printBuildError = require('react-dev-utils/printBuildError')
try {
build()
} catch(e) {
printBuildError(e) // logs prettified message
}
getProcessForPort(port: number): string
在 port
上查找当前正在运行的进程。 返回包含名称和目录的字符串,例如,
create-react-app
in /Users/developer/create-react-app
var getProcessForPort = require('react-dev-utils/getProcessForPort');
getProcessForPort(3000);
launchEditor(fileName: string, lineNumber: number): void
在 macOS 上,尝试查找已知的正在运行的编辑器进程并在其中打开文件。 它也可以通过 REACT_EDITOR
、VISUAL
或 EDITOR
环境变量显式配置。 例如,您可以将 REACT_EDITOR=atom
放入您的 .env.local
文件中,Create React App 将遵守这一点。
noopServiceWorkerMiddleware(): ExpressMiddleware
返回服务于 /service-worker.js
的 Express 中间件,该中间件重置任何先前设置的服务工作者配置。 对开发有用。
openBrowser(url: string): boolean
尝试使用给定的 URL 打开浏览器。
在 Mac OS X 上,尝试通过 AppleScript 重用现有的 Chrome 选项卡。
否则,回退到 opn 行为。
var path = require('path');
var openBrowser = require('react-dev-utils/openBrowser');
if (openBrowser('http://localhost:3000')) {
console.log('The browser tab has been opened!');
}
printHostingInstructions(appPackage: Object, publicUrl: string, publicPath: string, buildFolder: string, useYarn: boolean): void
构建项目后打印托管说明。
将已解析的 package.json
对象作为 appPackage
传递,将计划托管应用程序的 URL 作为 publicUrl
,output.publicPath
来自您的 Webpack 配置作为 publicPath
,buildFolder
名称,以及是否在说明中使用 useYarn
。
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrl;
const publicPath = config.output.publicPath;
printHostingInstructions(appPackage, publicUrl, publicPath, 'build', true);
WebpackDevServerUtils
choosePort(host: string, defaultPort: number): Promise<number | null>
如果用户确认可以这样做,则返回解析为 defaultPort
或下一个可用端口的 Promise。 如果端口被占用并且用户拒绝使用另一个端口,或者如果终端不是交互式的并且不能向用户提供选择,则解析为 null
。
createCompiler(webpack: Function, config: Object, appName: string, urls: Object, useYarn: boolean): WebpackCompiler
使用内置的有用消息为 WebpackDevServer 创建一个 Webpack 编译器实例。 将 require('webpack')
入口点作为第一个参数。 要提供 urls
参数,请使用如下所述的 prepareUrls()
。
prepareProxy(proxySetting: string, appPublicFolder: string): Object
从 package.json
中的 proxy
设置创建一个 WebpackDevServer proxy
配置对象。
prepareUrls(protocol: string, host: string, port: number): Object
返回具有开发服务器的本地和远程 URL 的对象。 将此对象传递给上述 createCompiler()
。
webpackHotDevClient
这是 WebpackDevServer 的替代客户端,显示语法错误覆盖。
它目前仅支持 Webpack 3.x。
// Webpack development config
module.exports = {
// ...
entry: [
// You can replace the line below with these two lines if you prefer the
// stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
'react-dev-utils/webpackHotDevClient',
'src/index'
],
// ...
}
react-dev-utils
This package includes some utilities used by Create React App.
Please refer to its documentation:
- Getting Started – How to create a new app.
- User Guide – How to develop apps bootstrapped with Create React App.
Usage in Create React App Projects
These utilities come by default with Create React App, which includes it by default. You don’t need to install it separately in Create React App projects.
Usage Outside of Create React App
If you don’t use Create React App, or if you ejected, you may keep using these utilities. Their development will be aligned with Create React App, so major versions of these utilities may come out relatively often. Feel free to fork or copy and paste them into your projects if you’d like to have more control over them, or feel free to use the old versions. Not all of them are React-specific, but we might make some of them more React-specific in the future.
Entry Points
There is no single entry point. You can only import individual top-level modules.
new InterpolateHtmlPlugin(replacements: {[key:string]: string})
This Webpack plugin lets us interpolate custom variables into index.html
.
It works in tandem with HtmlWebpackPlugin 2.x via its events.
var path = require('path');
var HtmlWebpackPlugin = require('html-dev-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
// Webpack config
var publicUrl = '/my-custom-url';
module.exports = {
output: {
// ...
publicPath: publicUrl + '/'
},
// ...
plugins: [
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
// You can pass any key-value pairs, this was just an example.
// WHATEVER: 42 will replace %WHATEVER% with 42 in index.html.
}),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: path.resolve('public/index.html'),
}),
// ...
],
// ...
}
new ModuleScopePlugin(appSrc: string, allowedFiles?: string[])
This Webpack plugin ensures that relative imports from app's source directory don't reach outside of it.
var path = require('path');
var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
module.exports = {
// ...
resolve: {
// ...
plugins: [
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
// ...
],
// ...
},
// ...
}
new WatchMissingNodeModulesPlugin(nodeModulesPath: string)
This Webpack plugin ensures npm install <library>
forces a project rebuild.
We’re not sure why this isn't Webpack's default behavior.
See #186 for details.
var path = require('path');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
// Webpack config
module.exports = {
// ...
plugins: [
// ...
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
new WatchMissingNodeModulesPlugin(path.resolve('node_modules'))
],
// ...
}
checkRequiredFiles(files: Array<string>): boolean
Makes sure that all passed files exist.
Filenames are expected to be absolute.
If a file is not found, prints a warning message and returns false
.
var path = require('path');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
if (!checkRequiredFiles([
path.resolve('public/index.html'),
path.resolve('src/index.js')
])) {
process.exit(1);
}
clearConsole(): void
Clears the console, hopefully in a cross-platform way.
var clearConsole = require('react-dev-utils/clearConsole');
clearConsole();
console.log('Just cleared the screen!');
eslintFormatter(results: Object): string
This is our custom ESLint formatter that integrates well with Create React App console output.
You can use the default one instead if you prefer so.
const eslintFormatter = require('react-dev-utils/eslintFormatter');
// In your webpack config:
// ...
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
options: {
// Pass the formatter:
formatter: eslintFormatter,
},
},
],
}
]
}
FileSizeReporter
measureFileSizesBeforeBuild(buildFolder: string): Promise<OpaqueFileSizes>
Captures JS and CSS asset sizes inside the passed buildFolder
. Save the result value to compare it after the build.
printFileSizesAfterBuild(webpackStats: WebpackStats, previousFileSizes: OpaqueFileSizes, buildFolder: string, maxBundleGzipSize?: number, maxChunkGzipSize?: number)
Prints the JS and CSS asset sizes after the build, and includes a size comparison with previousFileSizes
that were captured earlier using measureFileSizesBeforeBuild()
. maxBundleGzipSize
and maxChunkGzipSizemay
may optionally be specified to display a warning when the main bundle or a chunk exceeds the specified size (in bytes).
var {
measureFileSizesBeforeBuild,
printFileSizesAfterBuild,
} = require('react-dev-utils/FileSizeReporter');
measureFileSizesBeforeBuild(buildFolder).then(previousFileSizes => {
return cleanAndRebuild().then(webpackStats => {
printFileSizesAfterBuild(webpackStats, previousFileSizes, buildFolder);
});
});
formatWebpackMessages({errors: Array<string>, warnings: Array<string>}): {errors: Array<string>, warnings: Array<string>}
Extracts and prettifies warning and error messages from webpack stats object.
var webpack = require('webpack');
var config = require('../config/webpack.config.dev');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var compiler = webpack(config);
compiler.plugin('invalid', function() {
console.log('Compiling...');
});
compiler.plugin('done', function(stats) {
var rawMessages = stats.toJson({}, true);
var messages = formatWebpackMessages(rawMessages);
if (!messages.errors.length && !messages.warnings.length) {
console.log('Compiled successfully!');
}
if (messages.errors.length) {
console.log('Failed to compile.');
messages.errors.forEach(e => console.log(e));
return;
}
if (messages.warnings.length) {
console.log('Compiled with warnings.');
messages.warnings.forEach(w => console.log(w));
}
});
printBuildError(error: Object): void
Prettify some known build errors. Pass an Error object to log a prettified error message in the console.
const printBuildError = require('react-dev-utils/printBuildError')
try {
build()
} catch(e) {
printBuildError(e) // logs prettified message
}
getProcessForPort(port: number): string
Finds the currently running process on port
. Returns a string containing the name and directory, e.g.,
create-react-app
in /Users/developer/create-react-app
var getProcessForPort = require('react-dev-utils/getProcessForPort');
getProcessForPort(3000);
launchEditor(fileName: string, lineNumber: number): void
On macOS, tries to find a known running editor process and opens the file in it. It can also be explicitly configured by REACT_EDITOR
, VISUAL
, or EDITOR
environment variables. For example, you can put REACT_EDITOR=atom
in your .env.local
file, and Create React App will respect that.
noopServiceWorkerMiddleware(): ExpressMiddleware
Returns Express middleware that serves a /service-worker.js
that resets any previously set service worker configuration. Useful for development.
openBrowser(url: string): boolean
Attempts to open the browser with a given URL.
On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.
Otherwise, falls back to opn behavior.
var path = require('path');
var openBrowser = require('react-dev-utils/openBrowser');
if (openBrowser('http://localhost:3000')) {
console.log('The browser tab has been opened!');
}
printHostingInstructions(appPackage: Object, publicUrl: string, publicPath: string, buildFolder: string, useYarn: boolean): void
Prints hosting instructions after the project is built.
Pass your parsed package.json
object as appPackage
, your the URL where you plan to host the app as publicUrl
, output.publicPath
from your Webpack configuration as publicPath
, the buildFolder
name, and whether to useYarn
in instructions.
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrl;
const publicPath = config.output.publicPath;
printHostingInstructions(appPackage, publicUrl, publicPath, 'build', true);
WebpackDevServerUtils
choosePort(host: string, defaultPort: number): Promise<number | null>
Returns a Promise resolving to either defaultPort
or next available port if the user confirms it is okay to do. If the port is taken and the user has refused to use another port, or if the terminal is not interactive and can’t present user with the choice, resolves to null
.
createCompiler(webpack: Function, config: Object, appName: string, urls: Object, useYarn: boolean): WebpackCompiler
Creates a Webpack compiler instance for WebpackDevServer with built-in helpful messages. Takes the require('webpack')
entry point as the first argument. To provide the urls
argument, use prepareUrls()
described below.
prepareProxy(proxySetting: string, appPublicFolder: string): Object
Creates a WebpackDevServer proxy
configuration object from the proxy
setting in package.json
.
prepareUrls(protocol: string, host: string, port: number): Object
Returns an object with local and remote URLs for the development server. Pass this object to createCompiler()
described above.
webpackHotDevClient
This is an alternative client for WebpackDevServer that shows a syntax error overlay.
It currently supports only Webpack 3.x.
// Webpack development config
module.exports = {
// ...
entry: [
// You can replace the line below with these two lines if you prefer the
// stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
'react-dev-utils/webpackHotDevClient',
'src/index'
],
// ...
}