React 开发环境设置与 Webpack 入门教学

前言

俗话说工欲善其事,必先利其器。写程式也是一样,搭建好开发环境后可以让自己在后续开发上更加顺利。因此本章接下来将讨论 React 开发环境的两种主要方式:CDN-based、 webpack(这边我们就先不讨论 TypeScript 的开发方式)。至于 browserify 搭配 Gulp 的方法则会放在补充资料中,让读者阅读完本章后可以开始 React 开发之旅!

JavaScript 模组化

随着网站开发的复杂度提升,许多现代化的网站已不是单纯的网站而已,更像是个富有互动性的网页应用程式(Web App)。为了应付现代化网页应用程式开发的需求,解决一些像是全域变数污染、低维护性等问题,JavaScript 在模组化上也有长足的发展。过去一段时间读者们或许听过像是 Webpack、Browserify、module bundlers、AMDCommonJS、UMDES6 Module 等有关 JavaScript 模组化开发的专有名词或工具,在前面一个章节我们也简单介绍了关于 JavaScript 模组化的简单观念和规范介绍。若是读者对于 JavaScript 模组化开发尚不熟悉的话推荐可以参考 这篇文章这篇文章 当作入门。

总的来说,使用模组化开发 JavaScript 应用程式主要有以下三种好处:

  1. 提升维护性(Maintainability)
  2. 命名空间(Namespacing)
  3. 提供可重用性(Reusability)

而在 React 应用程式开发上更推荐使用像是 Webpack 这样的 module bundlers 来组织我们的应用程式,但对于一般读者来说 Webpack 强大而完整的功能相对复杂。为了让读者先熟悉 React 核心观念(我们假设读者已经有使用 JavaScriptjQuery 的基本经验),我们将从使用 CDN 引入 <script> 的方式开始介绍:

以下是 React 官方首页的范例,以下使用 React v15.2.1

  1. 理解 ReactComponent 导向的应用程式设计
  2. 引入 react.js、react-dom.js(react 0.14 后将 react-dom 从 react 核心分离,更符合 react 跨平台抽象化的定位)以及 babel-standalone 版 script(可以想成 babel 是翻译机,翻译浏览器看不懂的 JSXES6+ 语法成为浏览器看的懂得的 JavaScript。为了提升效率,通常我们都会在伺服器端做转译,这点在 production 环境尤为重要)
  3. <body> 撰写 React Component 要插入(mount)指定节点的地方:<div id="example"></div>
  4. 透过 babel 进行语言翻译 React JSX 语法,babel 会将其转为浏览器看的懂得 JavaScript。其代表意义是:ReactDOM.render(欲 render 的 Component 或 HTML 元素, 欲插入的位置)。所以我们可以在浏览器上打开我们的 hello.html,就可以看到 Hello, world! 。That's it,我们第一个 React 应用程式就算完成了!
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <!-- 以下引入 react.js, react-dom.js(react 0.14 后将 react-dom 从 react 核心分离,更符合 react 跨平台抽象化的定位)以及 babel-core browser 版 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.1/babel.min.js"></script>
  </head>
  <body>
    <!-- 这边的 id="example" 的 <div> 为 React Component 要插入的地方 -->
    <div id="example"></div>
    <!-- 以下就是包在 babel(透过进行语言翻译)中的 React JSX 语法,babel 会将其转为浏览器看的懂得 JavaScript -->
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

在浏览器浏览最后成果:

Webpack

上面我们先简单介绍了 CDN-based 的开发方式让大家先对于 React 有个基本印象,但由于 CDN-based 的开发方式有不少缺点。所以接下来的 Webpack 将会是我们接下来范例的主要使用的开发工具。

Webpack 是一个模组打包工具(module bundler),以下列出 Webpack 的几项主要功能:

  • 将 CSS、图片与其他资源打包
  • 打包之前预处理(Less、CoffeeScript、JSX、ES6 等)档案
  • 依 entry 文件不同,把 .js 分拆为多个 .js 档案
  • 整合丰富的 Loader 可以使用(Webpack 本身仅能处理 JavaScript 模组,其余档案如:CSS、Image 需要载入不同 Loader 进行处理)

接下来我们一样透过 Hello World 实例来介绍如何用 Webpack 设置 React 开发环境:

  1. 依据你的作业系统安装 NodeNPM(目前版本的 Node 都会内建 NPM)

  2. 透过 NPM 安装 Webpack(可以 global 或 local project 安装,这边我们使用 local)、webpack loader、webpack-dev-server

    Webpack 中的 loader 类似于 browserify 内的 transforms,但 Webpack 在使用上比较多元,除了 JavaScript loader 外也有 CSS Style 和图片的 loader。此外,webpack-dev-server 则可以启动开发用 server,方便我们测试

    // 按指示初始化 NPM 设定档 package.json
    $ npm init 
    // --save-dev 是可以让你将安装套件的名称和版本资讯存放到 package.json,方便日后使用
    $ npm install --save-dev babel-core babel-eslint babel-loader babel-preset-es2015 babel-preset-react html-webpack-plugin webpack webpack-dev-server
    
    
  3. 在根目录设定 webpack.config.js

    事实上,webpack.config.js 有点类似于 gulp 中的 gulpfile.js 功用,主要是设定 webpack 的相关设定

    // 这边使用 HtmlWebpackPlugin,将 bundle 好的 <script> 插入到 body。${__dirname} 为 ES6 语法对应到 __dirname  
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
      template: `${__dirname}/app/index.html`,
      filename: 'index.html',
      inject: 'body',
    });
    
    module.exports = {
      // 档案起始点从 entry 进入,因为是阵列所以也可以是多个档案
      entry: [
        './app/index.js',
      ],
      // output 是放入产生出来的结果的相关参数
      output: {
        path: `${__dirname}/dist`,
        filename: 'index_bundle.js',
      },
      module: {
        // loaders 则是放欲使用的 loaders,在这边是使用 babel-loader 将所有 .js(这边用到正则式)相关档案(排除了 npm 安装的套件位置 node_modules)转译成浏览器可以阅读的 JavaScript。preset 则是使用的 babel 转译规则,这边使用 react、es2015。若是已经单独使用 .babelrc 作为 presets 设定的话,则可以省略 query
        loaders: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
              presets: ['es2015', 'react'],
            },
          },
        ],
      },
      // devServer 则是 webpack-dev-server 设定
      devServer: {
        inline: true,
        port: 8008,
      },
      // plugins 放置所使用的外挂
      plugins: [HTMLWebpackPluginConfig],
    };
    
  4. 在根目录设定 .babelrc

    {
      "presets": [
        "es2015",
        "react",
      ],
      "plugins": []
    }
    
  5. 安装 react 和 react-dom

    $ npm install --save react react-dom
    
    
  6. 撰写 Component(记得把 index.html 以及 index.js 放到 app 资料夹底下喔!) index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>React Setup</title>
        <link rel="stylesheet" type="text/css" >
    </head>
    <body>
        <!-- 欲插入 React Component 的位置 -->
        <div id="app"></div>
    </body>
    </html>
    

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
        };
      }
      render() {
        return (
          <div>
            <h1>Hello, World!</h1>
          </div>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'));
    
  7. 在终端机使用 webpack 进行成果展示,webpack 相关指令:

    • webpack:会在开发模式下开始一次性的建置
    • webpack -p:会建置 production 的程式码
    • webpack --watch:会监听程式码的修改,当储存时有异动时会更新档案
    • webpack -d:加入 source maps 档案
    • webpack --progress --colors:加上处理进度与颜色

    如果不想每次都打一长串的指令码的话可以使用 package.json 中的 scripts 设定

    "scripts": {
      "dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"
    }
    

    然后在终端机执行:

    $ npm run dev
    
    

当我们此时我们可以打开浏览器输入 http://localhost:8008 ,就可以看到 Hello, world! 了!

总结

以上就是 React 开发环境设置与 Webpack 入门教学,看到这边的读者不妨自己动手设定开发环境,体验一下 React 开发环境的感觉,毕竟若是只有阅读文字的话很容易就会忘记喔!若你不想在环境设定上花太多时间的话,不妨参考 Facebook 开发社群推出的 create-react-app,可以快速上手,使用 Webpack、Babel、ESLint 开发 React 应用程式。接下来的章节我们将持续延伸 React/JSX/Component 的介绍。

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

推荐阅读更多精彩内容