使用webpack輕松構(gòu)建你的第一個(gè)react開(kāi)發(fā)框架

react的路很長(zhǎng),這將是一個(gè)開(kāi)始酬诀。

開(kāi)始.jpg

開(kāi)發(fā)之前磺芭,你需要首先了解一下幾點(diǎn):

webpack:

Webpack 是當(dāng)下最熱門(mén)的前端資源模塊化管理和打包工具。它可以將許多松散的模塊按照依賴(lài)和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源是尖。還可以將按需加載的模塊進(jìn)行代碼分隔意系,等到實(shí)際需要的時(shí)候再異步加載。通過(guò) loader 的轉(zhuǎn)換饺汹,任何形式的資源都可以視作模塊蛔添,比如 CommonJs 模塊、 AMD 模塊、 ES6 模塊迎瞧、CSS夸溶、圖片、 JSON凶硅、Coffeescript缝裁、 LESS 等。

webpack-dev-server:

在webpack中有一個(gè)在開(kāi)發(fā)時(shí)很好用的功能足绅,熱加載(Hot-replace)捷绑,在react開(kāi)發(fā)中,結(jié)合上react-hot-loader插件氢妈,開(kāi)發(fā)工作將會(huì)變得更棒:更改代碼之后粹污,你甚至都不需要去刷新你的瀏覽器,界面就會(huì)自動(dòng)刷新首量。但是壮吩,要使用這一功能的話,我們就需要使用webpack-dev-server加缘。webpack-dev-server是一個(gè)小型的node.js Express服務(wù)器,它使用webpack-dev-middleware中間件來(lái)為通過(guò)webpack打包生成的資源文件提供Web服務(wù)鸭叙。它還有一個(gè)通過(guò)Socket.IO連接著webpack-dev-server服務(wù)器的小型運(yùn)行時(shí)程序。webpack-dev-server發(fā)送關(guān)于編譯狀態(tài)的消息到客戶(hù)端拣宏,客戶(hù)端根據(jù)消息作出響應(yīng)递雀。

react-router:

在react開(kāi)發(fā)中,react-router是由官方維護(hù)的蚀浆,唯一可選的路由庫(kù)缀程。它通過(guò)管理 URL,實(shí)現(xiàn)組件的切換和狀態(tài)的變化市俊,開(kāi)發(fā)復(fù)雜的應(yīng)用幾乎肯定會(huì)用到杨凑。

babel:

Babel是一個(gè)JavaScript編譯器。默認(rèn)情況下摆昧,babel自帶了一組ES2015語(yǔ)法轉(zhuǎn)化器撩满。這些轉(zhuǎn)化器可以讓你現(xiàn)在就使用最新的JavaScript語(yǔ)法,而不需要等待瀏覽器提供支持绅你。本文要講的開(kāi)發(fā)例子中伺帘,就使用到了ES6以及部分ES7所提出的一些新規(guī)范,所以需要使用babel來(lái)進(jìn)行轉(zhuǎn)化忌锯。

一伪嫁、配置package.json文件

首先建立項(xiàng)目文件夾,在該項(xiàng)目文件夾目錄下執(zhí)行npm init命令偶垮,然后一直回車(chē)到底张咳,生成package.json文件帝洪,接下來(lái)再進(jìn)行詳細(xì)的配置。

package.json
{
  "name": "webpack-react",
  "version": "1.0.0",
  "description": " webpack-react ",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot --progress --colors",
    "build": "webpack --progress --colors"
  },
  "author": "CainZK",
  "license": "ISC",
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.7.2",
    "babel-loader": "^6.2.4",
    "babel-plugin-react-transform": "^2.0.2",
    "babel-plugin-transform-class-properties": "^6.16.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-2": "^6.17.0",
    "classnames": "^2.2.5",
    "css-loader": "^0.23.1",
    "file-loader": "^0.8.5",
    "html-webpack-plugin": "^2.10.0",
    "react": "^0.14.8",
    "react-dom": "^15.3.2",
    "react-hot-loader": "^1.3.0",
    "react-router": "^2.8.1",
    "react-slick": "^0.14.5",
    "react-transform-hmr": "^1.0.4",
    "rmc-list-view": "^0.6.2",
    "sass-loader": "^3.2.0",
    "style-loader": "^0.13.0",
    "url-loader": "^0.5.7",
    "webpack": "^1.12.14",
    "webpack-dev-server": "^1.14.1"
  }
}

這里需要說(shuō)一下scripts字段以及devDependencies字段脚猾。在scripts字段下第一個(gè)命令"start": "webpack-dev-server --hot --progress --colors"表示執(zhí)行npm start命令時(shí)葱峡,會(huì)執(zhí)行后面的命令,即用webpack-dev-server啟動(dòng)服務(wù)龙助, --hot表示熱替換配置砰奕,--progress表示顯示進(jìn)度,--colors表示配置輸出的顏色提鸟。第二個(gè)命令build表示執(zhí)行npm run build的時(shí)候军援,會(huì)使用webpack進(jìn)行打包操作。

二沽一、配置webpack.config.js文件

上一步打包的時(shí)候,所有的配置工作都是在webpack.config.js文件中進(jìn)行的漓糙。所以接下來(lái)我們來(lái)完善webpack的相關(guān)配置铣缠。

webpack.config.js
var path = require('path');
var webpack = require('webpack');
var ROOT_PATH = path.resolve(__dirname);
var APP_PATH = path.resolve(ROOT_PATH, 'app');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
// var htmlWebpackPlugin =  require('html-webpack-plugin');

module.exports = {
  entry: {
    a:[
      'webpack/hot/only-dev-server',
      "./app/index.js"
    ],
    b:[
      'webpack/hot/only-dev-server',
      "./app/index2.js"
    ]
  },
  output: {
      path: BUILD_PATH,
      publicPath: "/build/", 
      filename: "[name].bundle.js"
  },
  module: {
      loaders: [  
          {
            test: /\.js$/, 
            exclude: /node_modules/, 
            loader: "babel-loader", 
            query:
              {
                presets:['react','es2015','stage-2'] // babel配置:添加這三個(gè)presets用來(lái)處理js和jsx
              }
          }, {
              test: /\.css$/,
              loaders: ['style', 'css', 'sass'], //.scss 文件使用 style-loader、css-loader 和 sass-loader 來(lái)編譯處理
              include: APP_PATH
          }, {
              test: /\.(png|jpg)$/,
              loader: 'url?limit=40000'  //圖片文件使用 url-loader 來(lái)處理昆禽,小于40000字節(jié)的直接轉(zhuǎn)為base64
          }
      ]
  },
  resolve:{
      extensions:['','.js','.json']   //自動(dòng)擴(kuò)展文件后綴名蝗蛙,意味著我們r(jià)equire模塊可以省略不寫(xiě)后綴名
  },
  devServer: {
      hot: true,  //熱加載模式
      inline: true //inline模式(將webpack-dev-sever的客戶(hù)端入口添加到包(bundle)中)
  },
  plugins: [
    new webpack.NoErrorsPlugin(),//用來(lái)跳過(guò)編譯時(shí)出錯(cuò)的代碼并記錄,使編譯后運(yùn)行時(shí)的包不會(huì)發(fā)生錯(cuò)誤
    new webpack.HotModuleReplacementPlugin()//全局開(kāi)啟代碼熱替換
  ]
};

entry:入口配置醉鳖,這里我進(jìn)行的是多頁(yè)面入口文件的配置捡硅,如果是單頁(yè)面的話可以這樣來(lái)進(jìn)行配置:

entry: {
      'webpack/hot/only-dev-server',
      "./app/index.js"
  },

path是webpack輸出地址,取絕對(duì)路徑盗棵;
publicPath是webpack-dev-server啟動(dòng)服務(wù)時(shí)在內(nèi)存中文件生成的地址壮韭。
filename:這里多頁(yè)面入口文件配置需要加上[name]。
loaders:使用loader對(duì)一些文件進(jìn)行相應(yīng)的處理纹因。
test:使用正則匹配要處理的文件喷屋。
exclude:排除不處理的目錄。
loader:要使用的loader瞭恰。
...(其余相關(guān)配置已寫(xiě)在代碼注釋中)

三屯曹、完善入口頁(yè)面

在項(xiàng)目根目錄下簡(jiǎn)歷index.html以及index1.html表示兩個(gè)入口頁(yè)面。

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" type="text/css" href="./app/css/base.css">
    <title>React App</title>
  </head>
  <body>
    <div id="content"></div>
    <script src="./build/b.bundle.js"></script>
  </body>
</html>

index1.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <div id="content"></div>
  <script src="./build/a.bundle.js"></script>
</body>
</html>

在根目錄下新建app目錄惊畏,新建index.js以及index1.js文件恶耽。

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import myBt from './example/myBt';
import Carousel from './example/myCarousel';
import ActionSheet from './example/myActionSheet';
import { Router, Route, IndexRoute, hashHistory} from 'react-router';
import rt from './example/route';

class App extends React.Component {
    render () {
      console.log(window.screen.height);
        return (
          <div>
          {this.props.children}
          </div>
        );
    }
}

ReactDOM.render((
  <Router history={hashHistory}>
        <Route path="/" component={App} >
            <IndexRoute component={rt}/>
            <Route path="/carousel" component={Carousel}/>
            <Route path="/button" component={myBt}/>
            <Route path="/actionSheet" component={ActionSheet}/>
        </Route>
  </Router>),
  document.getElementById('content')
);
index1.js
import React from 'react';
import ReactDOM from 'react-dom';
import ListView from 'rmc-list-view';

var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
class App extends React.Component {
  constructor(props) {
  super(props);
  var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds,
      loaded:false,
    };
  }
  componentDidMount() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
          loaded: true,
        });
      })
  }
  renderLoadingView() {
    return (
        <div>
          Loading ...
        </div>
    );
  }
  render() {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }
    var rowStyle = {
      flex: 1,
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#F5FCFF'
    }
    var imgStyle = {
      height:120,
      width:80
    }
    return(
      <ListView
        style={{ height: 667, backgroundColor:'#FAFAFA' }}
        dataSource={this.state.dataSource}
        renderRow={(rowData) => (
          <div style={rowStyle}>
            <img src={rowData.posters.thumbnail} style={imgStyle}/>
            <a style={{flex: 1,marginTop:15,marginLeft:10,fontSize:18,height:36,position:'absolute'}}>
              {rowData.title}
            </a>
          </div>
        )}
      />
    );
  }
};

ReactDOM.render(<App/>, document.getElementById('content'));

這里我們?cè)趇ndex.js文件中使用了react-router,簡(jiǎn)單介紹一下它的一些配置及簡(jiǎn)單的用法颜启。
導(dǎo)入路由:

import { Router, Route, IndexRoute, hashHistory} from 'react-router';

配置路由信息:

<Router history={hashHistory}>
     <Route path="/" component={App} >
          <IndexRoute component={rt}/>
          <Route path="/carousel" component={Carousel}/>
          <Route path="/button" component={myBt}/>
          <Route path="/actionSheet" component={ActionSheet}/>
     </Route>
</Router>

路由跳轉(zhuǎn)頁(yè)面設(shè)置:

import React from 'react';

export default class Button extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div style={{padding:20}}>
        <a href="#carousel" style={{marginLeft:20}}>
          carousel
        </a>
        <a href="#button" style={{marginLeft:20}}>
          button
        </a>
        <a href="#actionSheet" style={{marginLeft:20}}>
          actionSheet
        </a>
      </div>
    );
  }
};

path是跳轉(zhuǎn)路徑偷俭,component中的是跳轉(zhuǎn)路徑過(guò)后要展示出來(lái)的react組件。具體的詳細(xì)用法可以參考npm官網(wǎng)的介紹缰盏,這里就不多說(shuō)了社搅。

到這里框架搭建基本完成驻债,缺的只有文中所引用的第三方組件了,如果您感興趣的話形葬,可以參考github合呐,將項(xiàng)目down下來(lái),再進(jìn)行研究笙以,我也會(huì)繼續(xù)完善這個(gè)簡(jiǎn)單的框架淌实,添加更多的組件進(jìn)去,方便開(kāi)發(fā)猖腕。

成功搭建后的演示:


Image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拆祈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子倘感,更是在濱河造成了極大的恐慌放坏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件老玛,死亡現(xiàn)場(chǎng)離奇詭異淤年,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蜡豹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)麸粮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人镜廉,你說(shuō)我怎么就攤上這事弄诲。” “怎么了娇唯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵齐遵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我塔插,道長(zhǎng)洛搀,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任佑淀,我火速辦了婚禮留美,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伸刃。我一直安慰自己谎砾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布捧颅。 她就那樣靜靜地躺著景图,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碉哑。 梳的紋絲不亂的頭發(fā)上挚币,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天亮蒋,我揣著相機(jī)與錄音,去河邊找鬼妆毕。 笑死慎玖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的笛粘。 我是一名探鬼主播趁怔,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼薪前!你這毒婦竟也來(lái)了润努?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤示括,失蹤者是張志新(化名)和其女友劉穎铺浇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體垛膝,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鳍侣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了繁涂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拱她。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡二驰,死狀恐怖扔罪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桶雀,我是刑警寧澤矿酵,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站矗积,受9級(jí)特大地震影響全肮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棘捣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一辜腺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乍恐,春花似錦评疗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至呜投,卻和暖如春加匈,著一層夾襖步出監(jiān)牢的瞬間存璃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工雕拼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纵东,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓悲没,卻偏偏與公主長(zhǎng)得像篮迎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子示姿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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

  • 無(wú)意中看到zhangwnag大佬分享的webpack教程感覺(jué)受益匪淺甜橱,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,140評(píng)論 7 35
  • GitChat技術(shù)雜談 前言 本文較長(zhǎng)栈戳,為了節(jié)省你的閱讀時(shí)間岂傲,在文前列寫(xiě)作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,674評(píng)論 7 110
  • 構(gòu)建一個(gè)小項(xiàng)目——FlyBird子檀,學(xué)習(xí)webpack和react镊掖。(本文成文于2017/2/25) 從webpac...
    布蕾布蕾閱讀 16,801評(píng)論 31 98
  • 前言 WebPack 是什么? WebPack 是什么褂痰,WebPack 可以看做是模塊打包機(jī):它做的事情是亩进,分析你...
    Promise__閱讀 1,121評(píng)論 3 12
  • 根據(jù)本人的教學(xué)經(jīng)驗(yàn),“創(chuàng)設(shè)提問(wèn)”是一種有效的閱讀教學(xué)方式缩歪,所謂“創(chuàng)設(shè)提問(wèn)”就是通過(guò)提出一些創(chuàng)新性归薛、可操作性、引導(dǎo)性...
    林夕眠閱讀 178評(píng)論 0 0