译:使用 Webpack & Babel 搭建 React ES6 开发环境

网上对于 React 的相关教程层出不穷,官方文档也对其中的技术要点做出了充足的解释,只是不那么简洁易懂。但有了这篇译文,我们可以从最简单的组件开始,通过对 Babel、Webpack 的了解与实践,来搭建最简单的 React 开发环境。

ReactJS 从诞生以来,一直引领着前端技术的飞速发展。正如其官网所说,React 作为专注于 MVC 架构中 View 层的前端库,允许我们构建可重用的 UI 组件,并通过抽象 DOM 来维护数据状态的变化。结合前端资源加载/打包工具 Webpack,React 大大简化了构建和维护单页应用程序的过程。

Facebook 做了大量的工作使 React 保持活力,包括及时使它与 ECMAScript 6(ES6)标准(JavaScript 语言的一次重大更新)的新功能兼容。不幸的是,浏览器对 ES6 的支持并不像许多人所希望的那样广泛,因此也就出现了 Babel 这样实用的工具。Babel 允许我们编写符合 ES6 标准的 JavaScript 文件并将其编译为可以运行在旧 JavaScript 环境的标准 ES5 代码。

在这篇文章中,我们将尝试编写两个符合ES6 标准的基本 React 组件。其中需要使用
Babel 将代码编译为 ES5 代码并使用 Webpack 将源代码打包。 这个过程会很有趣的,因为将 React、ES6、Babel 和 Webpack 搭配起来的开发体验真的很棒。

使用构建工具搭建运行环境

在我们正式开始编写代码之前,首先确保我们的电脑上是否已经安装了 NodeJS 和 npm,因为我们将使用这些来安装需要的软件包。

安装完成后打开终端,使用简单的终端命令跳转到我们的新项目目录下并输入如下命令:

npm init

在接下来终端的提示中填写我们觉得合适的内容(译者注:默认一直回车即可),将会生成一个 package.json 文件。这个文件将允许我们记录项目需要的所有 node 模块以供参考。

现在我们来安装 React 和 React DOM:

npm install --save react
npm install --save react-dom

我们还需要安装 webpack 和 webpack-dev-server 来打包并运行打包后的 JavaScript 应用程序。这时可能需要使用“sudo”权限来将 webpack-dev-server 安装到全局环境。

npm install --save-dev webpack
npm install webpack-dev-server -g

现在我们需要的模块已经安装好了,我们需要一个用来解析 ES6 代码的编译器,也就到了 Babel 上场的时刻。我们来安装将用于 Webpack 的 babel-loader 和 babel-core 模块,以及 babel-preset-es2015 和用于加载 React 代码的babel-preset-react 模块。

npm install --save-dev babel-loader
npm install --save-dev babel-core
npm install --save-dev babel-preset-es2015
npm install --save-dev babel-preset-react

创造第一个 React 组件

React 使用组件来封装界面模块。我们可以编写组件来处理数据的外观并自动呈现状态数据更改后的样子。创建组件时,我们需要通过重载 React.Component 的 render 函数来定义每一个组件。

现在编写我们的第一个组件来实践这个概念,这个组件的最终目的是能在浏览器中显示“Hello”这个单词。

通过编辑器在项目中新建一个“hello.jsx”文件并写下如下代码:

import React from 'react';
 
class Hello extends React.Component {
  render () {
    return <h1>Hello</h1>
  }
}

关于以上代码的语法我们有几件事需要注意。首先,我们有 ES6 的 import 语句和类定义语句,这使得我们的代码更简洁,无需调用 React.createClass。第二,在组件定义的 render 函数中有一个时髦的内联 HTML 的东西,这个类似 XML 的语法称为 JSX。JSX 被设计来使 React 组件的构建更容易,其简介、熟悉的语法用于定义具有属性的 DOM 树结构。

这些新的语法或许看起来有点奇怪,但是不必担心,因为我们只需要稍微使用 babel,便能将 ES6 语法和 JSX 语法都转换成可以在浏览器中运行的 ES5 JavaScript。

如果在 React 中不使用 ES6 和 JSX 语法,我们的“Hello” 组件将会是这样的:

var React = require('react');
 
var Hello = React.createClass({displayName: 'Hello',
  render: function() {
    return React.createElement("h1", null, "Hello ");
  }
});

当我们使用 JSX 时,我们可以更简洁地定义我们的虚拟DOM元素,而无需调用 React.createElement 并传递元素应具有的属性。使用 JSX 并不一定能使我们这个简单的“Hello”组件剩去多少代码行数,但在我们构建组件并将它们组合在一起时,JSX会使事情变得更加容易。

现在我们有了一个组件类,我们需要增加一些代码使组件能“mount”到一个 DOM 元素。这将会使我们的 React 组件呈现到 HTML 页面的元素中。为此我们导入 react-dom 模块并调用其 render 函数,传入组件对象以及该组件要绑定的实际DOM元素。

再次打开“hello.jsx”并添加以下行(第二行和后三行):

import React from 'react';
import ReactDOM from 'react-dom';
 
class Hello extends React.Component {
  render() {
    return <h1>Hello</h1>
  }
}
 
ReactDOM.render(
    <Hello/>, 
    document.getElementById('hello')
);

现在我们来创建我们的第二个组件,用来渲染“World”这个单词。在当前项目根目录下创建一个新的“world.jsx”文件并加入填写代码。请注意,它与我们为第一个组件编写的代码非常相似:

import React from 'react';
import ReactDOM from 'react-dom';
 
class World extends React.Component {
  render() {
    return <h1>World</h1>
  }
}
 
ReactDOM.render(
    <World/>,
    document.getElementById('world')
);

现在我们有了俩个 React 组件,但是还没有地方可以使用它们。我们现在来通过编写一个简单的 HTML 页面来解决这个问题,这个 HTML 页面将为我们要渲染到页面上的每个组件分配一个 <div>。创建一个“index.html”文件并编写相应的骨架:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="hello"></div>
    <div id="world"></div>
  </body>
</html>

我们现在创建了能在浏览器中显示“Hello World”的所有 React 组件代码。能让代码最终运行的最终一步需要通过 Webpack 来完成。

译者注:此时的项目目录

使用 Webpack 打包源代码

Webpack 作为模块加载/打包器可以处理很多资源,诸如使 CSS 文件、图像或是 JavaScript 文件等大量依赖关系的资源转换为可以提供给客户端网页的内容。Webpack 通过我们在项目配置文件中指定的装载程序来处理对应的资源。在我们的例子中,我们希望将 JSX 转换为 JavaScript 并将 ES6 代码转换为符合浏览器的 ES5 代码。我们可以通过提供一个 JavaScript 文件作为 Webpack 进行操作的入口点。Webpack 将分析此文件以及代码中使用的所有后续依赖关系,以生成一个包以供最终的 HTML 页面包含。要告诉 Webpack 有关项目中用到的 React 组件,我们需要做的就是导入这些 JavaScript 文件到入口文件中。

在文本编辑器中创建一个“main.js”文件,并添加以下代码来导入我们制作的两个 React 组件:

import Hello from './hello.jsx';
import World from './world.jsx';

接下来我们需要告诉 Webpack 这个文件是我们的入口文件,以便我们在打包时能让 Webpack 定位到。我们这里只用到了 Babel 的加载器,但如果我们有其他的依赖关系,我们还能使用其他加载器来实现如 CoffeeScript 和 SASS 文件的处理。

再次启动我们的文本编辑器,创建一个名为“webpack.config.js”的新文件,并添加以下配置:

var path = require('path');
var webpack = require('webpack');
 
module.exports = {
  entry: './main.js',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015',  'react']
        }
      }
    ]
  },
};

最后,我们需要对我们的 index.html 进行一个小的修改,以包含在运行 Webpack dev服务器时将生成的“bundle.js”文件:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="hello"></div>
    <div id="world"></div>
    <script src="bundle.js"></script>
  </body>
</html>

让我们启动 Webpack dev 服务器,看看我们的页面上的组件是否真的能呈现出来:

webpack-dev-server --progress --colors

当在终端输入命令后成功跑起来时,Webpack 成功打包了我们的组件代码。现在 Webpack dev 服务器正在运行,我们可以浏览浏览器中的 http:// localhost:8080/webpack-dev-server(译者注:译者的电脑上是 http:// localhost:8081,具体情况请看终端),以便在页面上看到我们的“Hello World”React 应用程序。

接下来该干什么?

我们刚刚仅仅通过使用能解析 JSX 和 ES6 的 Babel 构建了两个 React 组件,并使用 Webpack 将它们打包在一起从而得以在浏览器跑起来。这可能看起来并不是很难,但是在构建更大的单页应用程序的道路上是一个坚实的开始。我们现在已经克服了一大堆的障碍使这些新技术能有机的组合在一起,我们终于可以用 React 开始制作出令人敬畏的东西了。

如果您想深入探索并构建实际的 React 应用程序,您可以在博客文章中查看我最近写的关于“使用 React 创建一个基于 Twilio REST API 来监控电话的仪表盘”(译者注:或许之后会再翻译一下这篇文章)。

您可以随时联系我来分享您的经验或提出任何问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容