這是Webpack+React系列配置過程記錄的第一篇。其他內(nèi)容請(qǐng)參考:
- 第一篇:使用webpack豌鸡、babel嘿般、react、antdesign配置單頁面應(yīng)用開發(fā)環(huán)境
- 第二篇:使用react-router實(shí)現(xiàn)單頁面應(yīng)用路由
- 第三篇:優(yōu)化單頁面開發(fā)環(huán)境:webpack與react的運(yùn)行時(shí)打包與熱更新
- 第四篇:React配合Webpack實(shí)現(xiàn)代碼分割與異步加載
- 第五篇:分離Webpack開發(fā)環(huán)境與生產(chǎn)環(huán)境的配置
- 第六篇:在React中使用Redux
本文內(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ù)器脂男。也把這一步驟記錄下來养叛。
- 創(chuàng)建項(xiàng)目目錄demo,并使用npm init命令初始化node.js空項(xiàng)目宰翅,生成package.json文件弃甥。
- 使用npm安裝express。
- 創(chuàng)建Web的啟動(dòng)腳本index.js汁讼。
- 創(chuàng)建存放靜態(tài)資源的目錄public
- 在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)容如下圖所示:
確實(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中看到下面的提示:
配置按需加載需要使用另外一個(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森瘪。
本文來自作者同步博客