使用webpack、babel悲柱、react锋喜、antdesign配置單頁面應(yīng)用開發(fā)環(huán)境

這是Webpack+React系列配置過程記錄的第一篇。其他內(nèi)容請(qǐng)參考:

本文內(nèi)容將記錄使用webpack涯冠、babel炉奴、react、antdesign配置單頁面應(yīng)用開發(fā)環(huán)境的過程蛇更。這是我首次使用前端框架開發(fā)Web應(yīng)用瞻赶,在此之前,我寫Web代碼使用最原生的HTML派任、CSS砸逊、JS,即使是敲這些文字的這一刻掌逛,我還沒能熟練使用jQuery庫师逸。最近想跨出這個(gè)怪圈,希望使用一些“前沿”一些的框架重構(gòu)之前寫的書籍分享網(wǎng)站的管理后臺(tái)后臺(tái)豆混,因此才選擇使用webpack篓像、babel、react崖叫、ant design作為突破口遗淳。

主要依賴庫的版本如下(PS. 不同版本配置不一定一樣):

  • webpack: 2.4.1
  • react: 15.4.2
  • react-dom: 15.4.2
  • babel-core: 6.24.1
  • babel-loader: 7.0.0
  • antd: 2.5.2

準(zhǔn)備靜態(tài)Web服務(wù)器

靜態(tài)Web服務(wù)器可以使用Nginx、Apache等現(xiàn)成的服務(wù)器軟件心傀,僅用于接下來對(duì)配置結(jié)果的測(cè)試和校驗(yàn)屈暗。

為了節(jié)省安裝這些服務(wù)器軟件的精力,我直接使用node.js配合express寫了個(gè)簡單的靜態(tài)服務(wù)器脂男。也把這一步驟記錄下來养叛。

  1. 創(chuàng)建項(xiàng)目目錄demo,并使用npm init命令初始化node.js空項(xiàng)目宰翅,生成package.json文件弃甥。
  2. 使用npm安裝express。
  3. 創(chuàng)建Web的啟動(dòng)腳本index.js汁讼。
  4. 創(chuàng)建存放靜態(tài)資源的目錄public
  5. 在public中創(chuàng)建頁面文件index.html

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

var express = require('express');
var app = express();
app.use('/', express.static('public'));
var server = app.listen(2000, function() {
  var port = server.address().port;
  console.log('Open http://localhost:%s', port);
});

index.html文件的內(nèi)容如下:

<html>
  <head></head>
  <body>
    <p>Hello world</p>
  </body>
</html>

使用node啟動(dòng)index.js淆攻,就可以在瀏覽器中輸入 http://localhost:2000訪問到index.html中的內(nèi)容了阔墩。

接下來才是真正開始本文的真正內(nèi)容。我的目的很明確——開發(fā)一個(gè)網(wǎng)頁瓶珊,因此我將從React開始啸箫。

使用React開發(fā)頁面

使用React框架編寫頁面的方法有兩種,第一種是直接在html文件中直接引用react.js和react-dom.js伞芹,然后在后續(xù)的腳本中使用React帶來的能力忘苛。

僅改動(dòng)前文提到的index.html文件即可做到:

<html>
  <head>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
  </head>
  <body>
    <p>Hello world</p>
    <div id='main'/>
    <script>
      var e = React.createElement('p', null, 'This is React');
      ReactDOM.render(e, document.getElementById('main'));
    </script>
  </body>
</html>

在瀏覽器中訪問index.html,你將看到頁面使用React渲染了一行文字唱较。

但是通過這種方式使用React并不能很好發(fā)揮其作用扎唾。我們要使用ES6、JSX南缓、UI重用等特性胸遇,因此我們將使用下面的第二種方法。

使用Webpack西乖、Babel和React開發(fā)頁面

這種方法實(shí)際上你所寫的代碼并不是最終在用戶瀏覽器上執(zhí)行的代碼狐榔。源代碼將經(jīng)過Babel和Webpack進(jìn)行轉(zhuǎn)換處理,然后生成可在用戶瀏覽器上執(zhí)行的代碼获雕。這個(gè)過程有點(diǎn)像C或者C++的編譯薄腻。

安裝React

使用下面命令安裝React(參考:https://facebook.github.io/react/docs/installation.html)

npm install react@15.4.2 react-dom@15.4.2 --save

由于在寫這篇文章之前做過了一次測(cè)試,預(yù)料到如果使用最新版本的react届案,后面引入的ant design將會(huì)報(bào)兼容性錯(cuò)誤庵楷,故指定了react的版本。

因?yàn)闉g覽器并沒有提供給我們引入其他模塊的能力楣颠,我們也就無法直接使用React模塊尽纽,這時(shí)需要Webpack的幫助。

安裝與配置Webpack

使用下面命令安裝Webpack

npm install webpack --save-dev

配置Webpack的方法有好幾種童漩,我使用的是配置文件的方式弄贿。在項(xiàng)目根目錄下生成webpack.config.js文件。內(nèi)容如下:

var path = require('path');
module.exports = {
  entry: './public/index.js',
  output: {
    filename: 'out.js',
    path: path.resolve(__dirname, 'public')
  }
};

這個(gè)文件配置了webpack的入口為public目錄下的index.js矫膨,轉(zhuǎn)換后生成的文件為public/out.js差凹。

接下來在package.json配置一個(gè)build命令,內(nèi)容為:

...
"scripts": {
    "build": "webpack --config webpack.config.js",
    "start": "node index.js",
  },
...

這樣就可以使用npm run build調(diào)用webpack對(duì)js文件進(jìn)行轉(zhuǎn)換侧馅。

再看一下此刻的public目錄的index.js文件內(nèi)容:

import React from 'react';
import ReactDOM from 'react-dom';
var e = React.createElement('p', null, 'This is React');
ReactDOM.render(e, document.getElementById('main'));

而index.html文件的內(nèi)容:

<html>
  <head>
  </head>
  <body>
    <p>Hello world</p>
    <div id='main'></div>
    <script src="out.js"></script>
  </body>
</html>

注意到html中script標(biāo)簽引用的js文件是out.js危尿,這個(gè)文件是webpack生成的,是最終在用戶瀏覽器上執(zhí)行的腳本馁痴。

現(xiàn)在我們執(zhí)行npm run build命令谊娇,項(xiàng)目文件布局內(nèi)容如下圖所示:

項(xiàng)目文件布局

確實(shí)生成了我們想要的out.js文件了。

Webpack有一個(gè)優(yōu)點(diǎn)就是針對(duì)JS文件罗晕,它能夠做到按需加載济欢。后面你將會(huì)發(fā)現(xiàn)對(duì)于其他類型的文件赠堵,如:css、html法褥、jade等顾腊,只要使用了適當(dāng)?shù)牟寮材茏龅桨葱杓虞d。

到這里挖胃,你會(huì)發(fā)現(xiàn)不需要使用Babel,我們就可以使用React開發(fā)頁面內(nèi)容了梆惯。但是你會(huì)注意到酱鸭,除了import語句是webpack做了兼容性處理的,我所使用的其他語法都是ES5的語法垛吗。

如果在index.js中使用JSX語法凹髓,webpack構(gòu)建的時(shí)候就會(huì)報(bào)錯(cuò)。同樣地怯屉,如果在index.js中添加ES6的語法蔚舀,盡管webpack構(gòu)建時(shí)不會(huì)報(bào)錯(cuò),但生成的out.js文件末尾部分依舊可以找到這部分ES6語法的代碼锨络,這樣的代碼被用戶加載到瀏覽器中執(zhí)行赌躺,是否能被瀏覽器支持是無法得到保證的。

為此羡儿,我們需要引入Babel礼患,讓其把所有瀏覽器可能不支持的語法轉(zhuǎn)換成ES5的語法。

安裝與配置Babel

使用Babel的方法也有好多種掠归,官網(wǎng)的幫助文檔可以根據(jù)環(huán)境提供對(duì)應(yīng)的幫助缅叠。本文是基于Webpack使用Babel,因此無論是增加的依賴庫還是配置流程均只對(duì)Webpack的場(chǎng)景有效虏冻。我們將使用Webpack關(guān)于Babel的一個(gè)擴(kuò)展加載器babel-loader關(guān)聯(lián)這兩者肤粱。而且關(guān)于Babel的配置也集合到webpack.config.js中,通過webpack傳遞給babel厨相,這樣可以省去獨(dú)立配置babel步驟领曼。

安裝基于Webpack的Babel使用下面命令:

npm install --save-dev babel-loader
npm install --save-dev babel-core

上文提到,Babel用于把新版本的JS代碼翻譯成大多數(shù)瀏覽器都支持的ES5版本的代碼领铐。要做到這些翻譯悯森,只需要使用對(duì)應(yīng)的擴(kuò)展即可。例如:

  • babel-preset-env根據(jù)配置環(huán)境計(jì)算babel對(duì)代碼填充何種等級(jí)的polyfill绪撵,已包括es2015的配置瓢姻,但沒有包括stage-x。官方首推音诈。
  • babel-preset-[stage-0幻碱、stage-1绎狭、stage-2、stage-3]與ES7相關(guān)的配置;
  • 除此之外褥傍,Babel還可以有其他擴(kuò)展儡嘶,比如我們希望使用JSX語法,這時(shí)需要引入babel-preset-react處理器恍风。

根據(jù)官方的推薦蹦狂,我們暫時(shí)先使用這幾個(gè):

npm install --save-dev babel-preset-react
npm install --save-dev babel-preset-stage-0
npm install --save-dev babel-preset-env

在webpack.config.js中配置babel,內(nèi)容更新為:

var path = require('path');
module.exports = {
  entry: './public/index.js',
  output: {
    filename: 'out.js',
    path: path.resolve(__dirname, 'public')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env', 'stage-0', 'react'],
            plugins: []
          }
        }
      }
    ],
  },
};

注意到我們?cè)趍odule.rules中添加了一個(gè)規(guī)則朋贬。這個(gè)規(guī)則只要匹配到node_modules以外的js后綴的文件就會(huì)使用babel-loader進(jìn)行轉(zhuǎn)換凯楔,轉(zhuǎn)換過程依次使用了plugins和presets制定的擴(kuò)展。注意presets的處理順序比較特別锦募,是從右到左順序執(zhí)行的摆屯。

到這里就配置完babel了。我們修改index.js文件:

import React from 'react';
import ReactDOM from 'react-dom';
class Text extends React.Component {
  render() {
    return (
      <p>This is a react Component</p>
    );
  }
}
ReactDOM.render(<Text/>, document.getElementById('main'));

使用命令編譯并啟動(dòng)服務(wù)器糠亩,沒有再因?yàn)镴SX語法報(bào)錯(cuò)虐骑。

npm run build
npm start

在瀏覽器訪問index.html可以看到“This is a react Component”,這說明Babel很好地工作了赎线。

到這里如果沒有其他需求就可以開始開發(fā)了廷没。

使用Ant Design作為React的UI庫

由于我已經(jīng)怕自己造輪子了,這里我要引入基于React的一個(gè)Ant Design規(guī)范UI庫antd氛驮。

安裝Ant Design
npm install --save antd

好了可以直接使用Ant Design的UI了腕柜。修改index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { DatePicker } from 'antd';
class Text extends React.Component {
  render() {
    return (
      <div>
        <p>This is a react Component</p>
        <DatePicker/>
      </div>
    );
  }
}
ReactDOM.render(<Text/>, document.getElementById('main'));

重新構(gòu)建后執(zhí)行,在瀏覽器訪問index.html可以看到多了個(gè)日期選擇器矫废,但是沒有相應(yīng)的樣式盏缤。

加載樣式表

想要在js中引入css樣式表,需要添加webpack的加載器蓖扑,這樣在js中引入的css樣式將會(huì)被webpack構(gòu)建成以動(dòng)態(tài)方式插入到html文件中唉铜。

針對(duì)css樣式,需要下面兩個(gè)加載器:

npm install --save-dev css-loader
npm install --save-dev style-loader

然后在webpack.config.js中配置一個(gè)新的規(guī)則:

var path = require('path');
module.exports = {
  entry: './public/index.js',
  output: {
    filename: 'out.js',
    path: path.resolve(__dirname, 'public')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env', 'stage-0', 'react'],
            plugins: []
          }
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ],
  },
};

注意不要犯我的一個(gè)錯(cuò)誤:因?yàn)閍ntd的樣式是放在node_modules中的律杠,不要在css的loader中添加exclude命令刨除掉node_modules目錄潭流。

這時(shí)候可以在index.js中添加下面一行代碼:

...
import { DatePicker } from 'antd';
import 'antd/dist/antd.css';  // Add
...

重新構(gòu)建運(yùn)行就可以看到日期選擇器有樣式了。

配置按需加載

上述方法實(shí)際上加載整個(gè)antd包到最終生成的out.js文件中了柜去。不信的話灰嫉,在瀏覽器訪問index.html可以在console中看到下面的提示:


Ant Design警告

配置按需加載需要使用另外一個(gè)Babel的插件babel-plugin-import,安裝命令如下:

npm install --save-dev babel-plugin-import

因?yàn)檫@是Babel的插件嗓奢,所以它的配置要在babel-loader的plugins節(jié)點(diǎn)中配置讼撒。修改后的webpack.config.js內(nèi)容如下:

var path = require('path');
module.exports = {
  entry: './public/index.js',
  output: {
    filename: 'out.js',
    path: path.resolve(__dirname, 'public')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env', 'stage-0', 'react'],
            plugins: [['import', {"libraryName": "antd", "style": "css"}]]
          }
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ],
  },
};

這樣就完成了按需加載的配置了。

使用antd的組件的時(shí)候也無需再增加import樣式文件的語句了。去除掉剛剛在index.js中增加的那一行語句吧根盒。重新構(gòu)建運(yùn)行钳幅,你會(huì)看到警告沒有了。out.js中的行數(shù)從原來的13萬多行減少到了5萬多炎滞。

到此配置完畢敢艰。

注:所有內(nèi)容均參考自React、Babel册赛、Webpack钠导、AntDesign、第三方插件等的官方網(wǎng)站或?qū)?yīng)Github森瘪。

本文來自作者同步博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辈双,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子柜砾,更是在濱河造成了極大的恐慌,老刑警劉巖换衬,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痰驱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡瞳浦,警方通過查閱死者的電腦和手機(jī)担映,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叫潦,“玉大人蝇完,你說我怎么就攤上這事〈H铮” “怎么了短蜕?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長傻咖。 經(jīng)常有香客問我朋魔,道長,這世上最難降的妖魔是什么卿操? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任警检,我火速辦了婚禮,結(jié)果婚禮上害淤,老公的妹妹穿的比我還像新娘扇雕。我一直安慰自己,他們只是感情好窥摄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布镶奉。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腮鞍。 梳的紋絲不亂的頭發(fā)上值骇,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音移国,去河邊找鬼吱瘩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛迹缀,可吹牛的內(nèi)容都是我干的使碾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼祝懂,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼票摇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砚蓬,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤矢门,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后灰蛙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祟剔,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年摩梧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了物延。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仅父,死狀恐怖叛薯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笙纤,我是刑警寧澤耗溜,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站省容,受9級(jí)特大地震影響强霎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蓉冈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一城舞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寞酿,春花似錦家夺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春煌茴,著一層夾襖步出監(jiān)牢的瞬間随闺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工蔓腐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矩乐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓回论,卻偏偏與公主長得像散罕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子傀蓉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺欧漱,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,171評(píng)論 7 35
  • 最近在學(xué)習(xí) Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學(xué)習(xí) Webpack 的...
    My_Oh_My閱讀 8,184評(píng)論 40 247
  • GitChat技術(shù)雜談 前言 本文較長葬燎,為了節(jié)省你的閱讀時(shí)間误甚,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,697評(píng)論 7 110
  • webpack 介紹 webpack 是什么 為什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert閱讀 6,470評(píng)論 2 71
  • 嚴(yán)格意義來說谱净,這是實(shí)質(zhì)介入培訓(xùn)工作的第三個(gè)工作日靶草。一天八個(gè)小時(shí),這一天關(guān)于培訓(xùn)工作主要從兩個(gè)方面來談點(diǎn)想...
    zhiliner閱讀 252評(píng)論 0 0