Facebook的一幫子工程師在忙碌之餘開發除了一套前段UI框架React
。這個框架最大的有點就在於讓UI的開發都基於組件
,這樣View都是根據props和state變化的。javascript
項目地址:https://github.com/future-challenger/petshop/tree/master/clienthtml
雖然學React
比起來其餘的前端框架要容易很多,可是其生態的各類工具(Babel, Webpack)卻着實讓人費一番功夫。事實上,這些工具不僅適用於React
。可是爲了發揮ES2015
和JSX
的威力須要它們。這裏,咱們主要討論如何創建React
的開發環境,工具的事不作主要討論。前端
建立一個目錄react-demo的目錄,並在裏面初始化npm項目。java
mkdir react-demo cd react-demo npm init
按照要求填寫npm init
命令須要的輸入內容就能夠。node
Webpack
是一個模塊打包工具,能夠把模塊以及其依賴項一塊兒打包成靜態資源的工具。因爲對加載器的支持,webpack和React完美契合。本文的後面會詳細討論。react
使用npm安裝webpack。webpack
npm install webpack --save-dev
Webpack須要某些配置才能完成給他的工做。因此咱們須要建立一個webpack.config.js
的配置文件。c++
touch webpack.config.js
在該文件中添加以下的代碼。git
var webpack = require('webpack'); var path = require('path'); var BUILD_DIR = path.resolve(__dirname, 'src/client/public'); var APP_DIR = path.resolve(__dirname, 'src/client/app'); var config = { entry: APP_DIR + '/index.jsx', output: { path: BUILD_DIR, filename: 'bundle.js' } }; module.exports = config;
Webpack的配置最少須要兩項,一個是入口屬性,一個是輸出屬性。APP_DIR
指向React項目的代碼所在目錄,BUILD_DIR
指向打包後文件的輸出目錄。github
就如同配置項名稱所表達的同樣。entry是打包所須要的入口文件。若是你對靜態語言,好比c/c++之類的熟悉的話。這個入口文件就是c/c++包含main方法的文件。Webpack支持多個入口文件。這裏目錄src/client/app裏的index.jsx文件就是整個應用的入口文件。
output指明webpack在打包完成後須要作什麼。這裏,使用src/client/public目錄存放打包後生成的文件bundle.js。
在src/client/app目錄下建立文件index.jsx。並添加以下代碼。
console.log('Hello World!');
在terminal裏輸入下面的命令。
$ ./node_modules/.bin/webpack -d
命令會調用webpack,生成開發環境下的bundle.js文件以及關聯的map文件bundle.js.map。這兩個文件都在配置文件制定的目錄src/client/public下。
可是目前只看到了編譯以後的js文件,不夠直觀。在目錄src/client下建立一個index.html文件。這樣js文件是否加載成功都能看到了。
<html> <head> <meta charset="utf-8"> <title>React.js using NPM, Babel6 and Webpack</title> </head> <body> <div id="app" /> <script src="public/bundle.js" type="text/javascript"></script> <span style="float:center">Yo!</span> </body> </html>
如今打開瀏覽器,你就會看到「Yo」了。
注意:
有一個webpack的加載器`html-loader`能夠自動建立html文件。裏面會把編譯之後的js文件的路徑添加好。
就如前文所說,使用JSX和ES2015咱們的開發效率會更高。可是JSX語法和ES2015在某些瀏覽器裏是不兼容的。
所以,若是咱們要使用React代碼,咱們就須要使用一個工具把JSX和ES2015翻譯成瀏覽器都支持的語法。Babel
就是幹這個用的。
在安裝webpack的時候咱們就接觸到了一個概念加載器,Webpack就是用這個加載器來翻譯指定的文件的。
使用npm安裝babel-loader。
npm install babel-loader babel-preset-es2015 babel-preset-react --save-dev
babel-preset-es2015和babel-preset-react是babel-loader
使用的插件。專門用來翻譯JSX和ES2015語法。安裝以後還須要配置一下才能使用。
建立一個.babelrc的文件,並添加一下內容。
touch .babelrc
{ "presets": ["es2015", "react"] }
下一步就是告訴webpack使用babel-loader
來打包文件。
打開webpack.config.js並添加以下內容。
var webpack = require('webpack'); var path = require('path'); var BUILD_DIR = path.resolve(__dirname, 'src/client/public'); var APP_DIR = path.resolve(__dirname, 'src/client/app'); var config = { entry: APP_DIR + '/index.jsx', output: { path: BUILD_DIR, filename: 'bundle.js' }, module: { rules: [ { test: /\.jsx$/, use: [ 'babel-loader', ], include: [ // path.resolve(__dirname, "app") APP_DIR ], }, }; module.exports = config;
loaders
屬性對應的值是一個數組。不過咱們只是用babel-loader
。每個加載器都須要經過test
屬性指定能夠處理的文件的後綴。咱們的babel-loader
用來處理.js和.jsx文件。include
屬性指定處理哪一個目錄下的文件。loader
屬性就是加載器的名稱。
如今環境配置就都完成了。下面寫幾行代碼體驗一下。
使用npm安裝react和react-dom。
npm install react react-dom --save
把index.jsx文件裏的console.log(...)
替換成下面的代碼。
import React from 'react'; import {render} from 'react-dom'; class App extends React.Component { render() { return <p> Yo, React </p> } } render(<App />, document.getElementById('app'));
執行咱們上面說的命令。
./node_modules/.bin/webpack -d
如今你就能夠在瀏覽器裏看到Yo React了。
每次修改了文件以後還要中止-啓動一次webpack的命令實在是太麻煩了。咱們能夠簡單的修改一下命令。
./node_modules/.bin/webpack -d --watch
如今webpack就在監視模式下運行了,每次文件修改發生以後都會自動打包。要看到實際效果,能夠把Yo React修改爲任何其餘的字符串。以後在瀏覽器裏刷新一下就會看到結果。
若是你連刷新瀏覽器都懶得可使用react-hot-loader。
命令./node_modules/.bin/webpack
能夠簡化一下。
在packages.json文件裏修改。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack -d --watch", "build": "webpack -p" },
如今使用命令npm run build
就可讓webpack在產品模式下運行了。在這個模式下會自動壓縮打包好的文件。命令npm run dev
會在監視模式下運行webpack。
在示例中,咱們只有一個叫作App
的組件。咱們來添加更多組件。
建立一個新的文件叫作AwesomeComponent.jsx,並添加以下代碼。
import React from 'react'; class AwesomeComponent extends React.Component { constructor(props) { super(props); this.state = {likesCount: 0}; this.onLike = this.onLike.bind(this); } onLike() { let newLikesCount = this.state.likesCount + 1; this.setState({likesCount: newLikesCount}); } render() { return ( <div> Likes: <span>{this.state.likesCount}</span> <div><button onClick={this.onLike}>Like Me</button></div> </div> ); } } export default AwesomeComponent;
在index.jsx文件中引入。
import React from 'react'; import {render} from 'react-dom'; import AwesomeComponent from './AwesomeComponent.js'; class App extends React.Component { render() { return ( <div> <p> Yo, React </p> <AwesomeComponent /> </div> ) } } render(<App />, document.getElementById('app'));
若是webpack已經運行在監視模式下了,那麼直接刷新一下瀏覽器就能夠看到AwesomeComponent
的運行結果了。
本文能夠用來指導你配置React的開發環境。