react項(xiàng)目之初體驗(yàn)

從零開(kāi)始學(xué)習(xí) React 時(shí)按灶,歷經(jīng)一個(gè)月,終于算是有了一些理解筐咧。其中不乏有許多困惑的地方鸯旁,借本文在此梳理,項(xiàng)目地址量蕊。
引用 菜鳥(niǎo)教程的話

React 是一個(gè)用于構(gòu)建用戶界面的 JAVASCRIPT 庫(kù)铺罢。
React主要用于構(gòu)建UI,很多人認(rèn)為 React 是 MVC 中的 V(視圖)危融。
React 起源于 Facebook 的內(nèi)部項(xiàng)目畏铆,用來(lái)架設(shè) Instagram 的網(wǎng)站,并于 2013 年 5 月開(kāi)源吉殃。
React 擁有較高的性能辞居,代碼邏輯非常簡(jiǎn)單楷怒,越來(lái)越多的人已開(kāi)始關(guān)注和使用它。

正由于react主要用于構(gòu)建UI瓦灶,所以要完成一個(gè)完整的項(xiàng)目我們不得不配合使用其他的工具鸠删,如webpack(打包工具)、gulp(自動(dòng)化構(gòu)建工具)贼陶、express(應(yīng)用程序框架)等刃泡。

express

express可以在本地啟動(dòng)一個(gè)服務(wù),當(dāng)你訪問(wèn)對(duì)應(yīng)端口時(shí)碉怔,你可以在服務(wù)里面進(jìn)行處理烘贴,返回文字,圖片撮胧,頁(yè)面等桨踪,是一個(gè)web應(yīng)用的基礎(chǔ)。新建一個(gè)server.js芹啥,里面如下:

var express = require('express');
var app = express();
app.get('/', function (req, res) {
  res.send('Hello World!');
});
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

然后執(zhí)行

npm init  //初始化packag.json
npm install express --save //安裝express
node server.js //把服務(wù)器跑起來(lái)

打開(kāi)瀏覽器輸入http://localhost:3000/
現(xiàn)在你能看到
Hello World!
我們也可以返回一個(gè)標(biāo)簽:

res.send('<h1>Hello World!</h1>')

看到就是這樣了

Hello World!

我們項(xiàng)目需要做的就是把一些寫好的組件锻离、頁(yè)面呈現(xiàn)給訪問(wèn)者,然后處理一些邏輯和展示數(shù)據(jù)墓怀。
我們?cè)傩陆ㄒ粋€(gè)index.html汽纠,內(nèi)容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
hello world!
</body>
</html>

我們?cè)俑囊幌聅erver.js文件,把html傳出去:

res.sendfile('./index.html');

webpack

我們一般用webpack來(lái)打包文件和資源傀履,并通過(guò)它來(lái)實(shí)時(shí)更新和打包虱朵。詳細(xì)可以看文檔。包括webpack的安裝钓账,配置文件的解釋和使用卧秘,打包,實(shí)時(shí)更新等內(nèi)容官扣。

由于react需要用到react.js、react-dom.js等庫(kù)羞福,項(xiàng)目中也會(huì)用到其他許許多多的庫(kù)我們先學(xué)習(xí)用webpack打包成一個(gè)很小的bundle.js文件惕蹄,然后在html文件中引用。
安裝webpack命令:

npm install webpack --save

一個(gè)最簡(jiǎn)單的Webpack配置文件webpack.config.js如下所示:

module.exports = {
    entry:[
        './src/app.js'
    ],
    output: {
        path: __dirname + '/assets/',
        publicPath: "/assets/",
        filename: 'bundle.js'
    }
};

我們創(chuàng)建兩個(gè)文件夾src治专、assets卖陵,并在src下新建app.js文件。執(zhí)行如下命令安裝react和react-dom:

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

app.js文件內(nèi)容如下:

import { render } from 'react-dom'
render((
    <div>hello world!</div>
), document.getElementById('root'));

為了讓webpack識(shí)別ES6和jsx語(yǔ)法我們需要安裝加載器loader了:

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

在webpack.config.js中添加:

module: {
        loaders: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['react', 'es2015']
            }
        }]
    }

在命令行執(zhí)行:

webpack

完成后就能在assets目錄下看到一個(gè)bundle.js文件了张峰。
為了讓我們的app.js允許訪問(wèn)本地資源泪蔫,我們加入以下代碼:

app.use(express.static('assets'));

我們?yōu)橹暗膇ndex.html添加一個(gè)script引用bundle.js:

//Express 相對(duì)于靜態(tài)目錄查找文件,因此靜態(tài)目錄的名稱不是此 URL 的一部分
<script src="/bundle.js"></script>

再次執(zhí)行:

node server.js

我們便可以看到兩個(gè)hello world!了喘批,這樣我們就把react這個(gè)“V”和服務(wù)器聯(lián)系了起來(lái)撩荣,接下來(lái)可以專心寫界面了铣揉。

react

react的官方文檔對(duì)我們的理解和使用有很大的幫助。文檔介紹了react的基本使用(組件的創(chuàng)建和渲染)餐曹,組件的生命周期(componentDidMount)逛拱,屬性的更新和值的傳遞(state、setState台猴、props)朽合。

jsx語(yǔ)法

HTML 語(yǔ)言直接寫在 JavaScript 語(yǔ)言之中,不加任何引號(hào)饱狂,這就是 JSX 的語(yǔ)法曹步,它允許 HTML 與 JavaScript 的混寫。

var names = ['a', 'b', 'c'];
render((
    <div>
        {
            names.map(function (name) {
                return <div>Hello, {name}!</div>
            })
        }
    </div>
), document.getElementById('root'));

重新打包休讳,執(zhí)行

webpack
node server.js

可以看到
Hello, a!
Hello, b!
Hello, c!
hello world!

組件(component)

新建一個(gè)Home.js文件讲婚,如下:

import React from 'react';
class Home extends React.Component {
    render() {
        return <div>
            home
        </div>
    }
}
export default Home

在app.js中引用

import { render } from 'react-dom';
import React from 'react';
import Home from './Home';
var names = ['a', 'b', 'c'];
render((
    <div>
        {
            names.map(function (name) {
                return <div>Hello, {name}!</div>
            })
        }
        <Home />
    </div>
), document.getElementById('root'));

重新打包,執(zhí)行

webpack
node server.js

可以看到
Hello, a!
Hello, b!
Hello, c!
home
hello world!

gulp

gulp就是一個(gè)自動(dòng)化工具衍腥,可以開(kāi)啟多個(gè)任務(wù)磺樱,然后將它們按序執(zhí)行,也可以結(jié)合其他插件使用婆咸。

每次都要打包竹捉,運(yùn)行是不是很麻煩,我們就需要用工具來(lái)幫我們完成這些工作尚骄。在根目錄新建一個(gè)gulpfile.babel.js文件块差。
gulp原生并不支持es6語(yǔ)法,但是我們可以告訴gulp使用babel將gulpfile轉(zhuǎn)換為es5倔丈,方法就是將gulpfile命名為gulpfile.babel.js憨闰。如果你的babel是6.0以上的版本,你需要添加一個(gè).babelrc文件:

{
  "presets": ["es2015"]
}

安裝gulp相關(guān)工具:

npm install --save gulp-cli
npm install --save-dev gulp gulp-babel
npm install --save gulp-util
npm install --save-dev del
npm install --save exec

gulpfile.babel.js文件如下:

import gulp from 'gulp';
import gulpUtil from 'gulp-util';
import webpack from 'webpack';
import webpackConfig from './webpack.config.js';
import del from 'del';
import exec from 'exec';
gulp.task('clean-all', function () {
    return del([webpackConfig.output])
});
gulp.task('watch', () => {
    return gulp.watch('src/**/*.*', ['webpack:build'])
});
gulp.task('webpack:build', (callback) => {
    // run webpack
    webpack(webpackConfig, (err) => {
        if (err)
            throw new gulpUtil.PluginError('webpack:build', err);
        callback();
    });
});
gulp.task('server', (callback) => {
    exec('node server.js', (err) => {
        if (err)
            throw new gulpUtil.PluginError('webpack:build', err);
        callback()
    })
});
gulp.task('default', ['watch', 'webpack:build', 'server']);

執(zhí)行

gulp

路由

路由可以對(duì)不同頁(yè)面進(jìn)行跳轉(zhuǎn)需五,也可以劃分項(xiàng)目的層次結(jié)構(gòu)○亩現(xiàn)在我們安裝路由

npm install react-router --save

然后在app.js中做如下改動(dòng)

import { render } from 'react-dom';
import React from 'react';
import Home from './Home';
import {browserHistory, Router, Route} from 'react-router'
render((
    <Router history={browserHistory}>
        <Route path="/" component={Home} />
    </Router>
), document.getElementById('root'));

我們?nèi)稳豢梢钥吹絟ello home!
子路由也可以不寫在Router組件里面宏邮,單獨(dú)傳入Router組件的routes屬性泽示,我們也可以將routes抽取出一個(gè)單獨(dú)的文件。

import React from 'react';
import {browserHistory, Router} from 'react-router'
import routes from './routes'

React.render((
    <Router history={browserHistory} routes={routes} />
), document.getElementById('root'));

新建routes文件夾蜜氨,新建index.js文件

import Home from '../Home';
export default {
    path: '/',
    component: Home,
}
目錄截圖

安裝自動(dòng)刷新瀏覽器的插件

npm install webpack-dev-middleware --save-dev
npm install webpack-hot-middleware --save-dev
npm install html-webpack-plugin --save-dev

在webpack.config.js中修改entry械筛,添加plugins

entry:[
        'webpack-hot-middleware/client?reload=true',
        './src/app.js'
    ],
plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin(),
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: './index.html'
        }),
    ]

在server.js中引用這些中間件,修改后如下

import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import webpackDevConfig from './webpack.config';
export default function (callback) {
    const compiler = webpack(webpackDevConfig);
    const app = express();
    app.use(express.static( webpackDevConfig.output.path));
    app.use(webpackDevMiddleware(compiler,{
        publicPath: webpackDevConfig.output.publicPath,
        noInfo: true,
        stats: {
            colors: true
        }
    }));
    app.use(webpackHotMiddleware(compiler));
    app.listen(3000, function () {
        console.log('Example app listening on port 3000!');
    });
    callback();
};

代理

除了靜態(tài)資源外飒炎,我們也會(huì)訪問(wèn)到其他資源埋哟。這時(shí)候我們就需要用到代理。

npm install http-proxy-middleware --save

在sever.js中導(dǎo)入中間件郎汪,把需要代理的請(qǐng)求都攔截下來(lái)赤赊,去目標(biāo)服務(wù)器訪問(wèn)闯狱。

import proxy from 'http-proxy-middleware';

app.use('/a', proxy({
        target: 'http://xxx.xxx.xxx.xxx:80/',
        ws: true,
    }));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市砍鸠,隨后出現(xiàn)的幾起案子扩氢,更是在濱河造成了極大的恐慌,老刑警劉巖爷辱,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件录豺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡饭弓,警方通過(guò)查閱死者的電腦和手機(jī)双饥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弟断,“玉大人咏花,你說(shuō)我怎么就攤上這事》浚” “怎么了昏翰?”我有些...
    開(kāi)封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)刘急。 經(jīng)常有香客問(wèn)我棚菊,道長(zhǎng),這世上最難降的妖魔是什么叔汁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任统求,我火速辦了婚禮,結(jié)果婚禮上据块,老公的妹妹穿的比我還像新娘码邻。我一直安慰自己,他們只是感情好另假,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布像屋。 她就那樣靜靜地躺著,像睡著了一般边篮。 火紅的嫁衣襯著肌膚如雪开睡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天苟耻,我揣著相機(jī)與錄音,去河邊找鬼扶檐。 笑死凶杖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的款筑。 我是一名探鬼主播智蝠,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼腾么,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了杈湾?” 一聲冷哼從身側(cè)響起解虱,我...
    開(kāi)封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漆撞,沒(méi)想到半個(gè)月后殴泰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浮驳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年悍汛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片至会。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡离咐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奉件,到底是詐尸還是另有隱情宵蛀,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布县貌,位于F島的核電站术陶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏窃这。R本人自食惡果不足惜瞳别,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杭攻。 院中可真熱鬧祟敛,春花似錦、人聲如沸兆解。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锅睛。三九已至埠巨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間现拒,已是汗流浹背辣垒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留印蔬,地道東北人勋桶。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親例驹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捐韩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 無(wú)意中看到zhangwnag大佬分享的webpack教程感覺(jué)受益匪淺,特此分享以備自己日后查看鹃锈,也希望更多的人看到...
    小小字符閱讀 8,160評(píng)論 7 35
  • -- 1. Gulp VS webpack 比較 Gulp 是一個(gè)任務(wù)管理工具荤胁,讓簡(jiǎn)單的任務(wù)更清晰,讓復(fù)雜的任務(wù)易...
    慢清塵閱讀 3,547評(píng)論 7 16
  • 在現(xiàn)在的前端開(kāi)發(fā)中屎债,前后端分離仅政、模塊化開(kāi)發(fā)、版本控制扔茅、文件合并與壓縮已旧、mock數(shù)據(jù)等等一些原本后端的思想開(kāi)始...
    Charlot閱讀 5,439評(píng)論 1 32
  • 前言 WebPack 是什么? WebPack 是什么召娜,WebPack 可以看做是模塊打包機(jī):它做的事情是运褪,分析你...
    Promise__閱讀 1,128評(píng)論 3 12
  • 世人都說(shuō)神仙好,只有金銀忘不了玖瘸! 終朝只恨聚無(wú)多秸讹,等到多時(shí)眼閉了; 世人都說(shuō)神仙好雅倒,只有兒孫忘不了璃诀! 癡心父母古來(lái)...
    MapleLeaf_葉閱讀 7,353評(píng)論 0 0