react 过去以难以开始创建应用程序而闻名,因为您确实必须了解如何手动配置构建工具。这甚至在你编写一行 React 代码之前。
create-react-app 工具极大地帮助解决了这个问题,因为它允许任何人创建一个完整的 React 应用程序,而无需任何关于如何配置构建工具的知识。现实情况是 create-react-app 对于大多数应用程序来说都很好,特别是如果你是 React 新手。
随着您获得更多 React 经验,您可能对需要自定义配置文件的应用程序有某些要求。在这种情况下,您需要能够手动设置 React 构建工具,因为 create-react-app 默认情况下会隐藏这些工具。
在本教程中,我将向您展示如何通过手动配置构建工具来设置 React 应用程序。这有望让您有信心继续并尝试更复杂的设置。
虽然一开始可能看起来有点令人生畏,但您将享受完全控制每一个配置设置的所有好处。您可以准确地决定哪些工具会包含在您的应用程序中,这可能因项目而异。这种方法还允许您在新的构建工具出现时轻松地合并它们(它们经常这样做)。
你准备好从头开始创建你的第一个 React 应用了吗?我们开始做吧。
创建应用程序文件结构
为了演示如何通过手动配置构建工具来设置 React 应用程序,我们将构建与本系列先前教程中相同的、非常简单的 React 应用程序。
首先创建一个名为 的文件夹my-first-components-build
,然后打开一个指向该文件夹的命令行窗口。
键入npm init
以创建package.json
文件。此文件将包含有关用于构建应用程序的工具的所有信息,以及相关设置。接受所有默认设置,然后继续按 Enter(大约十次)直到完成。
如果您接受所有默认值, package.json
将如下所示:
{ "name": "my-first-components-build", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
我们现在需要将 React 和 React dom脚本添加到我们的项目中。我们将通过node .js 的包管理器 npm 来执行此操作。
在同一命令行目录中,输入:
npm install --save react react-dom
这将安装 React 和 ReactDom,以及这两个模块所需的任何依赖项。您会注意到我们现在有一个新node_modules
目录,其中添加了模块。
如果您查看该package.json
文件,则会dependencies
添加一个新属性,其中包含有关我们安装的节点模块的信息。
"dependencies": { "react": "^15.6.1", "react-dom": "^15.6.1" }
发生这种情况是因为我们在 命令中指定了--save
选项。npm install
这通知 npm 我们想要跟踪我们安装的项目依赖项。如果我们想分享我们的项目,这很重要。
通常,由于node_modules
文件夹太大,您不想尝试直接共享它。相反,您在没有node_modules
文件夹的情况下共享您的项目。然后,当有人下载您的项目时,他们所要做的就是npm install
直接从package.json
.
注意:在 npm 5.x 中,已安装的模块会自动保存到package.json
. 您不再需要手动指定--save
选项。
在my-first-components-build
文件夹中,创建一个新src
文件夹,然后向其中添加一个index.js
文件。一旦我们配置了项目设置文件,我们稍后会在开始创建我们的 React 应用程序时回到这一点。
使用以下代码在同一文件夹中添加 index.html 文件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Creating a React App Manually, Using Build Tools</title> </head> <body> <div id="app"></div> </body> </html>
我们希望能够将我们的应用程序编译为单个javascript文件,并使用jsx和 ES6 类和模块。为此,我们需要通过 npm 安装webpack和 Babel 模块。
我们先安装 Babel。在命令行窗口中键入以下内容:
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react
这将安装 Babel 将 ES6 和 JSX 代码编译为标准 JavaScript 所需的所有模块。
现在,让我们再次通过命令行安装webp ack:
npm install --save-dev html-webpack-plugin webpack webpack-dev-server
这将安装 Webpack(本地 Web 服务器)所需的所有模块,并使我们能够指导 Webpack 根据我们添加到文件夹index.html
中的文件在文件夹中创建一个动态文件 。每次构建应用程序时,我们还可以在 HTML 文件中添加对捆绑的 javaScript 文件的动态引用。public
src
安装这些新模块后,您的package.json
文件现在将如下所示:
"dependencies": { "react": "^15.6.1", "react-dom": "^15.6.1" }, "devDependencies": { "babel-core": "^6.25.0", "babel-loader": "^7.1.0", "babel-preset-env": "^1.5.2", "babel-preset-react": "^6.24.1", "html-webpack-plugin": "^2.28.0", "webpack": "^3.0.0", "webpack-dev-server": "^2.5.0" }
不过,这一次,Webpack 和 Babel 依赖项被保存package.json
为 dev 依赖项。
这意味着在应用程序的开发(即构建)阶段需要这些特定模块。另一方面,在运行时需要依赖项(例如 React 和 ReactDOM),因此将直接包含在我们的自定义应用程序代码中。
Webpack 配置
为了让 Webpack 构建我们的应用程序并将其捆绑到一个文件中,我们需要配置设置。在你的根应用文件夹中, create webpack.config.js
,它用于存储 Webpack 特定的构建设置。
我们需要 Webpack 做三件事:
将 ES6/JSX 代码编译为 JavaScript(通过 Babel)。
构建我们的应用程序,并捆绑到一个 JavaScript 文件中。
创建一个 index.html 文件,并在其中添加对我们捆绑的 JavaScript 文件的引用。
在里面webpack.config.js
,添加:
var path = require('path'); var HtmlWebpackPlugin = require( 'html-webpack-plugin' ); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'public'), filename: 'build.js' }, module: { rules: [ { test: /\.(js)$/, use: 'babel-loader' } ] }, plugins: [new HtmlWebpackPlugin({ template: 'src/index.html' })] }
不要太担心这里使用的语法;只需了解正在发生的事情的概述。
我们所做的只是导出一个具有某些属性的 JavaScript 对象,这些属性控制 Webpack 如何构建我们的应用程序。该entry
属性指定了我们的 React 应用程序的起点,即index.js
. 接下来,该output
属性定义捆绑的 JavaScript 文件的输出路径和文件名。
至于构建过程本身,我们希望 Webpack 将所有 JavaScript 文件通过 Babel 编译器将JSX/ES6 转换为标准 JavaScript。我们通过module
属性来做到这一点。它只是指定了一个只为 JavaScript 文件运行 Babel 转换的正则表达式。
要完成 Babel 设置,我们需要在package.json
文件中添加一个条目,以指定我们要对 JavaScript 文件执行哪些 Babel 转换。打开package.json
并添加一个babel
属性:
"babel": { "presets": [ "env", "react" ] },
这将对我们项目中的每个 JavaScript 文件运行两次转换。env
转换会将 ES6 JavaScript 转换为与所有浏览器兼容的标准 JavaScript 。并且react
转换会将 JSX 代码编译为createElement()
函数调用,这是完全有效的 JavaScript。
现在,回到我们的webpack.config.js
文件。
我们拥有的最后一个属性是plugins
,它包含我们想要在构建过程中执行的任何特殊操作。在我们的例子中,我们需要 Webpack 创建一个index.html
包含对捆绑的 JavaScript 文件的引用的文件。我们还指定了一个现有index.html
文件(我们之前创建的那个)用作创建最终捆绑index.html
文件的模板。
构建和测试
现在让我们添加一个script
属性到package.json
. 顺便说一句,您可以添加任意数量的脚本来执行各种任务。现在,我们只希望能够运行 Webpack,因此package.json
删除"test"
脚本并将其替换为:
"scripts": { "build": "webpack", },
在我们测试构建过程之前,让我们添加一个 React 组件,index.js
以便我们可以渲染一些东西。
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { render() { return ( <div> <h2>Hello World!</h2> </div> ) } } ReactDOM.render( <App />, document.queryselector( '#app' ) );
如果您已按照本系列前面的教程进行操作,那么现在这应该看起来非常熟悉。
从命令行运行:
npm run build
片刻之后,您应该会看到public
在内部创建了一个新文件夹my-first-components-build
,其中包含index.html
和index.js
。打开index.html
以查看我们的测试 React 应用程序的输出。
注意已经为我们添加了捆绑的 JavaScript 文件,并且测试组件被渲染到正确的 DOM 元素。
自动化编译过程
一旦开始对应用程序进行多项更改,您很快就会发现必须手动编辑文件、保存文件、运行构建命令,然后重新加载浏览器窗口以查看更改是相当乏味的。
幸运的是,我们可以使用之前安装的 Webpack mini 服务器来自动化这个过程。添加第二个脚本,package.json
使“脚本”属性如下所示:
"scripts": { "build": "webpack", "dev": "webpack-dev-server --open" },
现在运行:
npm run dev
几秒钟后,您将看到一个新的浏览器选项卡打开,您的网络应用正在运行。URL 现在指向本地服务器,而不是指向特定的本地文件。index.js
对文件夹进行细微更改src
并保存。请注意,您的应用几乎会立即在浏览器中自动更新以反映新的更改。
Webpack 现在将监视您的应用程序中的文件以进行更改。当进行任何更改并保存时,Webpack 将重新编译您的应用程序并使用新的更新自动重新加载浏览器窗口。
注意:Webpack 服务器不会重建您的应用程序,而是将更改存储在缓存中,这就是它可以如此快速地更新浏览器的原因。这意味着您不会看到public
文件夹中反映的更新。事实上,你可以在使用 Webpack 服务器时完全删除这个文件夹。
当您需要构建您的应用程序时,您可以简单地运行npm run build
以再次创建public
文件夹(如果需要)并输出您的应用程序文件,准备分发。
完成我们的应用程序
为了完整起见,让我们添加我们在之前的教程中使用过的两个简单组件。
在名为的根项目文件夹MyFirstComponent.js
和MySecondComponent.js
主应用程序文件夹中添加两个新文件。在MyFirstComponent.js
中,添加以下代码:
import React, { Component } from 'react'; class MyFirstComponent extends Component { render() { return ( <p>{this.props.number}: Hello from React!</p> ) } } export default MyFirstComponent;
在 中MySecondComponent.js
,添加:
import React, { Component } from 'react'; class MySecondComponent extends Component { render() { return ( <p>{this.props.number}: My Second React Component.</p> ) } } export default MySecondComponent;
要在我们的应用程序中使用这些组件,请更新index.js
到以下内容:
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import MyFirstComponent from './MyFirstComponent'; import MySecondComponent from './MySecondComponent'; class App extends Component { render() { return ( <div> <h2>My First React Components!</h2> <MyFirstComponent number="1st" /> <MySecondComponent number="2nd" /> </div> ) } } ReactDOM.render( <App />, document.querySelector( '#app' ) );
这会产生与我们之前看到的相同的输出,除了这次是通过 100% 手动设置 React 应用程序。
可重用的 React 设置模板
一旦您完成了一次手动设置并创建了配置设置文件,这是您唯一需要完全从头开始执行此操作的时间。对于未来的项目,您可以重用一个或多个现有设置文件,从而更快地设置后续 React 项目。
你甚至可以创建一组专门构建的 React 入门模板,并将它们托管在 GitHub 上。然后,这将是一个简单的案例,即克隆一个启动项目并运行npm init
以安装所需的 Node.js 模块。
下载并安装项目
本教程的 React 项目可供下载,因此您可以使用它或将其用作新项目的模板。
单击右侧边栏中的下载附件 链接以访问项目 .zip 文件。下载后,解压缩并打开命令行窗口。确保您在my-first-components-build
目录中。
输入以下命令来安装和编译 React 应用程序。
npm install npm run dev
第一个命令将下载项目所需的所有 Node.js 模块,这需要一两分钟。第二个命令将编译 React 应用程序并运行迷你 Web 服务器,将其显示在浏览器中。
尝试对您的 React 应用程序进行一些更改。每次保存更改时,都会重新编译您的应用程序,并且浏览器窗口会自动更新以反映您的应用程序的新版本。
当您要构建项目以进行分发时,只需运行以下命令。
npm run build
结论
在本教程系列中,我们研究了几种设置 React 应用程序的方法,每一种方法都逐渐需要更多的设置任务。但长期的好处是,您对项目的具体设置方式拥有更多的控制权和灵活性。
一旦你掌握了 React 的设置,我想你会发现开发应用程序很有趣。我很想听听你的意见。让我知道你接下来打算用 React 构建什么!