已經(jīng)看過(guò)這一節(jié)的朋友魄眉,可以看Webpack+React+多語(yǔ)言(二) 插件配置+多語(yǔ)言
github地址:webpack-react-language
關(guān)鍵字:react 多語(yǔ)言 國(guó)際版 React-intl
移動(dòng)端網(wǎng)站需要重構(gòu),當(dāng)前的想法是使用webpack+react來(lái)重構(gòu)移動(dòng)端名段,當(dāng)然,是需要支持多語(yǔ)言的霎冯。
-
1.創(chuàng)建一個(gè)項(xiàng)目:webpack-react-language
這個(gè)項(xiàng)目名字有點(diǎn)長(zhǎng)链峭,我主要是為了與本地其他的項(xiàng)目區(qū)別開來(lái)
目錄結(jié)構(gòu)
|- build
|-- index.html
|-- bundle.js(該文件是webpack打包后生成的)
|- app
|-- components
|--- Dialog.jsx
|-- main.js
|- package.json(第二步生成)
|- webpack.config.js(第四步生成)
-
2.創(chuàng)建package.json
npm init
-
3.安裝webpack
//全局安裝webpack,優(yōu)點(diǎn)是打包時(shí)可以直接輸webpack命令
npm install -g webpack
//在本項(xiàng)目中安裝webpack加派,--save-dev的意思是將依賴寫入項(xiàng)目的package.json文件
npm install --save-dev webpack
-
4.創(chuàng)建webpack.config.js配置文件
module.exports = {
entry: __dirname + "/app/main.js",//唯一入口文件,就像Java中的main方法
output: {//輸出目錄
path: __dirname + "/build",//打包后的js文件存放的地方
filename: "bundle.js"http://打包后的js文件名
}
};
運(yùn)行webpack
跳芳,webpack非全局安裝需輸入node_modules/.bin/webpack
看到以上提示說(shuō)明打包成功了芍锦,可以看到build目錄下的bundle.js里多了很多自動(dòng)生成的代碼,但預(yù)覽index.html卻什么都沒有看到飞盆,這是因?yàn)檫€沒有往頁(yè)面中寫入內(nèi)容娄琉。
-
5.更方便地執(zhí)行打包命令
執(zhí)行類似于node_modules/.bin/webpack
這樣的命令其實(shí)是比較煩人且容易出錯(cuò)的,不過(guò)值得慶幸的是npm可以引導(dǎo)任務(wù)執(zhí)行吓歇,對(duì)其進(jìn)行配置后可以使用簡(jiǎn)單的npm start命令來(lái)代替這些繁瑣的命令孽水。在package.json中對(duì)npm的腳本部分進(jìn)行相關(guān)設(shè)置即可,設(shè)置方法如下城看。
打開package.json女气,找到script代碼塊,更改為:
"scripts": {
"build": "webpack"
或者
"start":"webpack"
}
但是start是一個(gè)特殊的腳本名稱析命,如果腳本名稱不是start主卫,則需要npm run (script name)
,如npm run build
鹃愤,但是start可以直接執(zhí)行npm start
-
6.使用Source Maps簇搅,使調(diào)試更容易
devtool選項(xiàng) | 配置結(jié)果 |
---|---|
source-map | 在一個(gè)單獨(dú)的文件中產(chǎn)生一個(gè)完整且功能完全的文件。這個(gè)文件具有最好的source map软吐,但是它會(huì)減慢打包文件的構(gòu)建速度 |
cheap-module-source-map | 在一個(gè)單獨(dú)的文件中生成一個(gè)不帶列映射的map瘩将,不帶列映射提高項(xiàng)目構(gòu)建速度,但是也使得瀏覽器開發(fā)者工具只能對(duì)應(yīng)到具體的行凹耙,不能對(duì)應(yīng)到具體的列(符號(hào))姿现,會(huì)對(duì)調(diào)試造成不便 |
eval-source-map | 使用eval打包源文件模塊,在同一個(gè)文件中生成干凈的完整的source map肖抱。這個(gè)選項(xiàng)可以在不影響構(gòu)建速度的前提下生成完整的sourcemap备典,但是對(duì)打包后輸出的JS文件的執(zhí)行具有性能和安全的隱患。不過(guò)在開發(fā)階段這是一個(gè)非常好的選項(xiàng)意述,但是在生產(chǎn)階段一定不要用這個(gè)選項(xiàng) |
cheap-module-eval-source-map | 這是在打包文件時(shí)最快的生成source map的方法提佣,生成的Source Map 會(huì)和打包后的JavaScript文件同行顯示,沒有列映射荤崇,和eval-source-map選項(xiàng)具有相似的缺點(diǎn) |
正如上表所述拌屏,上述選項(xiàng)由上到下打包速度越來(lái)越快,不過(guò)同時(shí)也具有越來(lái)越多的負(fù)面作用术荤,較快的構(gòu)建速度的后果就是對(duì)打包后的文件的的執(zhí)行有一定影響倚喂。
在學(xué)習(xí)階段以及在小到中性的項(xiàng)目上,eval-source-map是一個(gè)很好的選項(xiàng)瓣戚,不過(guò)記得只在開發(fā)階段使用它端圈,繼續(xù)上面的例子,進(jìn)行如下配置
/webpack.config.js
module.exports = {
devtool: 'eval-source-map',//生成Source Maps,這里選擇eval-source-map
entry: __dirname + '/app/main.js',//唯一入口文件,__dirname是node.js中的一個(gè)全局變量带兜,它指向當(dāng)前執(zhí)行腳本所在的目錄
output: {//輸出目錄
path: __dirname + '/build',//打包后的js文件存放的地方
filename: 'bundle.js'//打包后輸出的js的文件名
}
};
-
7.安裝React枫笛、Babel
npm install react --save-dev
npm install react-dom --save-dev
npm install babel-core --save-dev
npm install babel-loader --save-dev
npm install babel-preset-es2015 --save-dev
npm install babel-preset-react --save-dev
在webpack.config.js中
/webpack.config.js
module.exports = {
devtool: 'eval-source-map',//生成Source Maps,這里選擇eval-source-map
entry: __dirname + '/app/main.js',//唯一入口文件,__dirname是node.js中的一個(gè)全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄
output: {//輸出目錄
path: __dirname + '/build',//打包后的js文件存放的地方
filename: 'bundle.js'//打包后輸出的js的文件名
},
module: { //loaders加載器
loaders: [{
test: /\.(js|jsx)$/,//一個(gè)匹配loaders所處理的文件的拓展名的正則表達(dá)式刚照,這里用來(lái)匹配js和jsx文件(必須)
exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選)
loader: 'babel-loader'//loader的名稱(必須) 原來(lái)可以簡(jiǎn)寫成babel刑巧,現(xiàn)在會(huì)提示報(bào)錯(cuò),需要寫全babel-loader无畔,后續(xù)其他的loader也是一樣的處理
}]
}
};
在項(xiàng)目根目錄下新建.babelrc文件啊楚,沒錯(cuò)你沒看錯(cuò),就是只有后綴名的文件浑彰,添加如下代碼:
//.babelrc
{
"presets": [
"react",
"es2015"
]
}
-
8.編寫頁(yè)面文件恭理,為后續(xù)測(cè)試功能做準(zhǔn)備
app/main.js
import React from 'react';
import ReactDom from 'react-dom';
import Dialog from './components/dialog.jsx';
ReactDom.render(
<Dialog />,
document.getElementById('content')
);
app/components/dialog.jsx
import React from 'react';
class Dialog extends React.Component {
render() {
return (
<div>Hello World!</div>
)
}
}
//導(dǎo)出組件
export default Dialog;
build/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content"></div>
<script src="bundle.js"></script>
</body>
</html>
我使用的編輯器是webstorm,上述步驟完成之后郭变,執(zhí)行npm start
颜价,打包成功后涯保,運(yùn)行index.html,可以看到頁(yè)面上
-
9.安裝并啟用webpack-dev-server
執(zhí)行到這一步周伦,基本的運(yùn)作是可以了夕春,但是每次修改文件之后,都需要重新打包专挪,再運(yùn)行及志,才可以看到新的內(nèi)容,如何能忍受這么low的執(zhí)行過(guò)程呢寨腔?
我們可以使用webpack-dev-server來(lái)搭建本地開發(fā)服務(wù)器速侈,webpack-dev-server允許我們可以把本地項(xiàng)目跑在像nginx那樣的web服務(wù)器上,修改代碼后迫卢,立即可以看到變化倚搬;所見即所得,大大增加開發(fā)效率乾蛤。
安裝webpack-dev-server
npm install webpack-dev-server -g
npm install webpack-dev-server --save-dev
更改packaje.json中的代碼塊
"scripts": {
"start": "webpack",
"dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"
}
ps:dev里各屬性值的意思是:
- webpack-dev-server: 在 localhost:8080 建立一個(gè) Web 服務(wù)器
- --devtool eval:為你的代碼創(chuàng)建源地址潭枣。當(dāng)有任何報(bào)錯(cuò)的時(shí)候可以讓你更加精確地定位到文件和行號(hào)
- --progress: 顯示合并代碼進(jìn)度
- --colors: 在命令行中顯示顏色
- --content-base build:指向設(shè)置的輸出目錄
在webpack.config.js中配置webpack-dev-server,在這里需要修改下entry的路徑幻捏,給它加一個(gè)webpack/hot/dev-server盆犁,這里會(huì)用到Hot Module Replacement(熱替換)插件,所以需要增加這個(gè)前綴篡九,后文會(huì)提到谐岁,代碼如下:
//webpack.config.js
module.exports = {
devtool: 'eval-source-map',//生成Source Maps,這里選擇eval-source-map
entry: ['webpack/hot/dev-server', __dirname + '/app/main.js'],//唯一入口文件,__dirname是node.js中的一個(gè)全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄
output: {//輸出目錄
path: __dirname + '/build',//打包后的js文件存放的地方
filename: 'bundle.js'//打包后輸出的js的文件名
},
module: { //loaders加載器
loaders: [ {
test: /\.(js|jsx)$/,//一個(gè)匹配loaders所處理的文件的拓展名的正則表達(dá)式榛臼,這里用來(lái)匹配js和jsx文件(必須)
exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選)
loader: 'babel'//loader的名稱(必須)
} ]
},
//webpack-dev-server配置
devServer: {
contentBase: './build',//默認(rèn)webpack-dev-server會(huì)為根文件夾提供本地服務(wù)器伊佃,如果想為另外一個(gè)目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄)
colors: true,//在cmd終端中輸出彩色日志
historyApiFallback: true,//在開發(fā)單頁(yè)應(yīng)用時(shí)非常有用沛善,它依賴于HTML5 history API航揉,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html
inline: true,//設(shè)置為true金刁,當(dāng)源文件改變時(shí)會(huì)自動(dòng)刷新頁(yè)面
port: 8080,//設(shè)置默認(rèn)監(jiān)聽端口帅涂,如果省略,默認(rèn)為"8080"
process: true,//顯示合并代碼進(jìn)度
}
};
在瀏覽器中打開http://localhost:8080/
尤蛮,如果頁(yè)面上是空白的媳友,沒有內(nèi)容,按F12打開控制臺(tái)产捞,可以清除地看到錯(cuò)誤提示:Uncaught Error: [HMR] Hot Module Replacement is disabled
現(xiàn)在我們來(lái)安裝和配置這個(gè)Hot Module Replacement醇锚。
新版本的webpack(當(dāng)前我使用的是webpack3.0),這樣配置會(huì)有問(wèn)題坯临。
如果用的不是webpack3焊唬,可以忽略下面這部分恋昼,直接看#10
建議
1.webpack3的朋友,按下面的代碼配置赶促,或者將webpack的版本退回我圖上的版本焰雕,進(jìn)行操作。
2.推薦先看第十步的內(nèi)容芳杏,可以幫助大家了解下面代碼中的HotModuleReplacementPlugin
webpack3 配置
//webpack-dev-server配置
plugins: [
new webpack.HotModuleReplacementPlugin({
contentBase: './build',//默認(rèn)webpack-dev-server會(huì)為根文件夾提供本地服務(wù)器,如果想為另外一個(gè)目錄下的文件提供本地服務(wù)器辟宗,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄)
colors: true,//在cmd終端中輸出彩色日志
historyApiFallback: true,//在開發(fā)單頁(yè)應(yīng)用時(shí)非常有用爵赵,它依賴于HTML5 history API,如果設(shè)置為true泊脐,所有的跳轉(zhuǎn)將指向index.html
inline: true,//設(shè)置為true空幻,當(dāng)源文件改變時(shí)會(huì)自動(dòng)刷新頁(yè)面
port: 8080,//設(shè)置默認(rèn)監(jiān)聽端口,如果省略容客,默認(rèn)為"8080"
process: true,//顯示合并代碼進(jìn)度
})
]
-
10.Hot Module Replacement
Hot Module Replacement(HMR)是webpack里很有用的一個(gè)插件秕铛,它允許你在修改組件代碼后,自動(dòng)刷新實(shí)時(shí)預(yù)覽修改后的效果缩挑。
在webpack中實(shí)現(xiàn)HMR也很簡(jiǎn)單但两,只需要做兩項(xiàng)配置
1.在webpack配置文件中添加HMR插件;
2.在Webpack Dev Server中添加“hot”參數(shù)供置;
不過(guò)配置完這些后谨湘,JS模塊其實(shí)還是不能自動(dòng)熱加載的,還需要在你的JS模塊中執(zhí)行一個(gè)Webpack提供的API才能實(shí)現(xiàn)熱加載芥丧,雖然這個(gè)API不難使用紧阔,但是如果是React模塊,使用我們已經(jīng)熟悉的Babel可以更方便的實(shí)現(xiàn)功能熱加載续担。
整理下我們的思路擅耽,具體實(shí)現(xiàn)方法如下
- Babel和webpack是獨(dú)立的工具
- 二者可以一起工作
- 二者都可以通過(guò)插件拓展功能
- HMR是一個(gè)webpack插件,它讓你能瀏覽器中實(shí)時(shí)觀察模塊修改后的效果物遇,但是如果你想讓它工作乖仇,需要對(duì)模塊進(jìn)行額外的配額;
- Babel有一個(gè)叫做react-transform-hrm的插件询兴,可以在不對(duì)React模塊進(jìn)行額外的配置的前提下讓HMR正常工作这敬;
在webpack.config.js中配置如下:
//webpack.config.js
var webpack = require('webpack')
module.exports = {
devtool: 'eval-source-map',//生成Source Maps,這里選擇eval-source-map
entry: ['webpack/hot/dev-server', __dirname + '/app/main.js'],//唯一入口文件,__dirname是node.js中的一個(gè)全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄
output: {//輸出目錄
path: __dirname + '/build',//打包后的js文件存放的地方
filename: 'bundle.js'//打包后輸出的js的文件名
},
module: { //loaders加載器
loaders: [ {
test: /\.(js|jsx)$/,//一個(gè)匹配loaders所處理的文件的拓展名的正則表達(dá)式蕉朵,這里用來(lái)匹配js和jsx文件(必須)
exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選)
loader: 'babel'//loader的名稱(必須)
} ]
},
plugins: [
new webpack.HotModuleReplacementPlugin()//熱模塊替換插件
],
//webpack-dev-server配置
devServer: {
contentBase: './build',//默認(rèn)webpack-dev-server會(huì)為根文件夾提供本地服務(wù)器崔涂,如果想為另外一個(gè)目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄)
colors: true,//在cmd終端中輸出彩色日志
historyApiFallback: true,//在開發(fā)單頁(yè)應(yīng)用時(shí)非常有用始衅,它依賴于HTML5 history API冷蚂,如果設(shè)置為true缭保,所有的跳轉(zhuǎn)將指向index.html
inline: true,//設(shè)置為true,當(dāng)源文件改變時(shí)會(huì)自動(dòng)刷新頁(yè)面
port: 8080,//設(shè)置默認(rèn)監(jiān)聽端口蝙茶,如果省略艺骂,默認(rèn)為"8080"
process: true,//顯示合并代碼進(jìn)度
}
};
現(xiàn)在可以正常工作了,運(yùn)行npm run dev
隆夯,待命令行提示webpack: bundle is now VALID
后钳恕,在瀏覽器中輸入http://localhost:8080
,可以看到蹄衷,正常顯示Hello World
如果覺得這樣不放心忧额,讓我們進(jìn)行如下額外配置
安裝react-transform-hmr,在不對(duì)React模塊進(jìn)行額外的配置的前提下讓HMR正常工作
npm install --save-dev babel-plugin-react-transform react-transform-hmr
在.babelrc文件里配置babel愧口,注意這里有一堆括號(hào)睦番,別寫錯(cuò)了
//.babelrc
{
"presets": [
"react",
"es2015"
],
"env": {
"development": {
"plugins": [
[
"react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": [ "react" ],
"locals": [ "module" ]
}]
}
]
]
}
}
}
至此,已經(jīng)用webpack構(gòu)建好了React項(xiàng)目的基礎(chǔ)依賴耍属,可以愉快的開發(fā)React程序了托嚣。
由于內(nèi)容太多,于是將本文分成了多個(gè)部分厚骗,下一部分Webpack+React+多語(yǔ)言(二) 插件配置+多語(yǔ)言
github地址:webpack-react-language