React+webpack+es6的環境配置及demo改寫

Jrain發表於2018-12-10

寫於 2016.05.14

前言

專案地址:jrainlau/react-es6

git clone https://github.com/jrainlau/react-learning
cd react-learning && npm install
npm run dev

然後瀏覽器開啟localhost:8080即可
複製程式碼

最近在家閒得無聊,所以打算折騰一下react。在此之前,我是一個vue的重度使用使用者,但是看到react確實非常火爆,所以也就趁此機會去了解一下react,增長一下見識。

學習react的參考資料,很大一部分來自 @阮一峰 的React入門例項教程。但是阮大神是用傳統的script標籤以及es5的寫法,所以我針對教程,通過配置webpack,最終使用es6的寫法來改寫教程的demo,結合元件化的思想,完成最終的demo的改寫。

環境配置

環境配置參照了@minooo 的文章:webpack-es6-react (為系統學習React佈一個良好的開局)。這裡引用一些關鍵包的說明:

package.json 中的 包/庫 部分說明

  • babel-core babel6 的基礎模組
  • babel-eslint ESLint 是前端JS程式碼檢測利器。而 babel-eslint 則允許你檢測所有的 Babel 程式碼。
  • babel-loader 這個包允許你使用 Babel 和 webpack 轉譯(Transpiling) JavaScript 檔案。
  • babel-plugin-react-transform 這個外掛通過任意轉換的方式去封裝 React 元件。換句話說,你可以隨心所欲的擺弄你的元件了。
  • babel-plugin-transform-runtime 在 Babel 轉換過程中,詳細的展示引用的相關輔助工具和內建命令,並自動的聚合填充你的程式碼而不會汙染全域性。
  • babel-preset-es2015 此預設包含了所有的 es2015 外掛。
  • babel-preset-react 此預設包含了所有的 React 外掛。
  • babel-preset-stage-0 此預設包含了 stage 0 中的所有外掛。
  • eslint JavaScript 語法檢測利器:分析出你程式碼潛在的錯誤和非標準用法。
  • eslint-plugin-react ESLint 中關於 React 語法檢測的外掛。
  • react-transform-hmr 一個 React 轉換裝置,該裝置通過引用 Hot Module Replacement API 使熱過載 React 的類成為可能。
  • react-transform-catch-errors 呈現你 React 元件的錯誤資訊。
  • webpack-dev-server 為 wepack app 提供一個伺服器,如果你的程式碼有任何變化,瀏覽器將自動重新整理顯示,極大的方便前期開發。
  • babel-runtime Babel 自帶的執行環境。

另外,我增加了style-loadercss-loaderlessless-loader這四個包用於載入.less檔案模組。(注意,less-loaderless必須同時存在才能正常工作。)

根目錄下檔案部分說明

  • .babelrc : 什麼是 .babelrc 檔案呢?熟悉 linux 的同學一定知道,rc 結尾的檔案通常代表執行時自動載入的檔案,配置等。同樣在這裡也是有同樣作用的。裡面的 env 欄位,可以對 BABEL_ENV 或 NODE_ENV 指定不同的環境變數,進行不同編譯。
  • eslintignore 通知 eslint 忽略那些不應該被檢測的檔案。
  • eslintrc eslint 配置檔案,使 JavaScript 程式碼規範化,標準化書寫。

使用es6改寫demo

首先可以參考這篇文章React on ES6+,裡面提及了關於如何使用es6進行react開發的方法。

使用React.Component代替React.createClass

// The ES5 way
var Photo = React.createClass({
  handleDoubleTap: function(e) { … },
  render: function() { … },
});

// The ES6+ way
class Photo extends React.Component {
  handleDoubleTap(e) { … }
  render() { … }
}
複製程式碼

使用static關鍵字完成屬性初始化工作(這是es7的內容,注意state可以直接通過state = { key: value }來定義)

// The ES5 way
var Video = React.createClass({
  getDefaultProps: function() {
    return {
      autoPlay: false,
      maxLoops: 10,
    };
  },
  getInitialState: function() {
    return {
      loopsRemaining: this.props.maxLoops,
    };
  },
  propTypes: {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  },
});

// The ES6+ way
class Video extends React.Component {
  static defaultProps = {
    autoPlay: false,
    maxLoops: 10,
  }
  static propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}
複製程式碼

constractor中定義state

// The ES5 way
var Video = React.createClass({
  getInitialState: function() {
    return {
      loopsRemaining: ...
    };
  }
});

//The ES6 way
class Video extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            loopsRemaining: ...
        }
    }
}
複製程式碼

元件化思路

通過es6的模組功能,可以很方便地利用webpack實現頁面元件化。

我們總共有7個小的demo,我把它們作為不同的元件,最終載入到根元件中:

// app.js

import React, { Component } from 'react'
import Component1 from './demo1.js'
import Component2 from './demo2.js'
import Component3 from './demo3.js'
import Component4 from './demo4.js'
import Component5 from './demo5.js'
import Component6 from './demo6.js'
import Component7 from './demo7.js'

export default class Demo extends Component {
  render() {
    return (
      <div>
        <Component1></Component1>
        <Component2></Component2>
        <Component3 title='Props example'></Component3>
        <Component4>
            <span>Hello</span>
            <span>React</span>
        </Component4>
        <Component5 content='This is the content'></Component5>
        <Component6></Component6>
        <Component7></Component7>
      </div>
    )
  }
}
複製程式碼

具體請進入我的專案檢視程式碼。

可以看到,通過es6的改寫,在react中實現元件化是非常清晰簡單的,只需要把需要的元件import進來即可。

另外,由於我非常討厭行內樣式,並且是不寫less會死星人,所以並沒有按照官方推薦的樣子去定義一個style object,而是通過less-loader在需要定義樣式的地方直接把樣式require進來,像這樣:

// demo7.js

render() {
    let word = this.state.words
    require('../less/test.less')
    return (
        <div>
            <h3 className='test-h1'>DEMO 7, state</h3>
            <p>{ word }</p>
            <input type="text" onChange={ this.stateFn }/>
            <hr/>
        </div>
    )
}
複製程式碼

結語

這個demo僅僅作為入門學習使用,react更多深層次的內容可能會在後續慢慢更新,比如加上react-router,redux什麼的……如果這篇文章能夠對你有所啟發是最好不過,如果有任何錯漏也歡迎拍磚指出,謝謝大家~

相關文章