Webpack+React+多語言(一) 基礎(chǔ)配置

已經(jīng)看過這一節(jié)的朋友,可以看Webpack+React+多語言(二) 插件配置+多語言
github地址:webpack-react-language
關(guān)鍵字:react 多語言 國際版 React-intl

移動端網(wǎng)站需要重構(gòu),當(dāng)前的想法是使用webpack+react來重構(gòu)移動端,當(dāng)然,是需要支持多語言的。

  • 1.創(chuàng)建一個項目:webpack-react-language

這個項目名字有點長,我主要是為了與本地其他的項目區(qū)別開來
目錄結(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)點是打包時可以直接輸webpack命令
npm install -g webpack
//在本項目中安裝webpack,--save-dev的意思是將依賴寫入項目的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文件名 
    }
};

運行webpack,webpack非全局安裝需輸入node_modules/.bin/webpack

webpack打包成功.png

看到以上提示說明打包成功了,可以看到build目錄下的bundle.js里多了很多自動生成的代碼,但預(yù)覽index.html卻什么都沒有看到,這是因為還沒有往頁面中寫入內(nèi)容。

  • 5.更方便地執(zhí)行打包命令

執(zhí)行類似于node_modules/.bin/webpack這樣的命令其實是比較煩人且容易出錯的,不過值得慶幸的是npm可以引導(dǎo)任務(wù)執(zhí)行,對其進行配置后可以使用簡單的npm start命令來代替這些繁瑣的命令。在package.json中對npm的腳本部分進行相關(guān)設(shè)置即可,設(shè)置方法如下。
打開package.json,找到script代碼塊,更改為:

"scripts": { 
    "build": "webpack"
    或者
    "start":"webpack"
}

但是start是一個特殊的腳本名稱,如果腳本名稱不是start,則需要npm run (script name),如npm run build,但是start可以直接執(zhí)行npm start

  • 6.使用Source Maps,使調(diào)試更容易
devtool選項 配置結(jié)果
source-map 在一個單獨的文件中產(chǎn)生一個完整且功能完全的文件。這個文件具有最好的source map,但是它會減慢打包文件的構(gòu)建速度
cheap-module-source-map 在一個單獨的文件中生成一個不帶列映射的map,不帶列映射提高項目構(gòu)建速度,但是也使得瀏覽器開發(fā)者工具只能對應(yīng)到具體的行,不能對應(yīng)到具體的列(符號),會對調(diào)試造成不便
eval-source-map 使用eval打包源文件模塊,在同一個文件中生成干凈的完整的source map。這個選項可以在不影響構(gòu)建速度的前提下生成完整的sourcemap,但是對打包后輸出的JS文件的執(zhí)行具有性能和安全的隱患。不過在開發(fā)階段這是一個非常好的選項,但是在生產(chǎn)階段一定不要用這個選項
cheap-module-eval-source-map 這是在打包文件時最快的生成source map的方法,生成的Source Map 會和打包后的JavaScript文件同行顯示,沒有列映射,和eval-source-map選項具有相似的缺點

正如上表所述,上述選項由上到下打包速度越來越快,不過同時也具有越來越多的負面作用,較快的構(gòu)建速度的后果就是對打包后的文件的的執(zhí)行有一定影響。

在學(xué)習(xí)階段以及在小到中性的項目上,eval-source-map是一個很好的選項,不過記得只在開發(fā)階段使用它,繼續(xù)上面的例子,進行如下配置

/webpack.config.js
module.exports = { 
    devtool: 'eval-source-map',//生成Source Maps,這里選擇eval-source-map 
    entry: __dirname + '/app/main.js',//唯一入口文件,__dirname是node.js中的一個全局變量,它指向當(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
基本插件安裝成功之后的package.json.png

在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中的一個全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄 
    output: {//輸出目錄 
        path: __dirname + '/build',//打包后的js文件存放的地方 
        filename: 'bundle.js'//打包后輸出的js的文件名 
    },
    module: {    //loaders加載器    
        loaders: [{            
            test: /\.(js|jsx)$/,//一個匹配loaders所處理的文件的拓展名的正則表達式,這里用來匹配js和jsx文件(必須)            
            exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選)            
            loader: 'babel-loader'//loader的名稱(必須) 原來可以簡寫成babel,現(xiàn)在會提示報錯,需要寫全babel-loader,后續(xù)其他的loader也是一樣的處理
        }]
    }
};

在項目根目錄下新建.babelrc文件,沒錯你沒看錯,就是只有后綴名的文件,添加如下代碼:

//.babelrc
{ 
    "presets": [ 
        "react",
        "es2015" 
    ]
}
  • 8.編寫頁面文件,為后續(xù)測試功能做準備

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,打包成功后,運行index.html,可以看到頁面上

成功運行.png

  • 9.安裝并啟用webpack-dev-server

執(zhí)行到這一步,基本的運作是可以了,但是每次修改文件之后,都需要重新打包,再運行,才可以看到新的內(nèi)容,如何能忍受這么low的執(zhí)行過程呢?

我們可以使用webpack-dev-server來搭建本地開發(fā)服務(wù)器,webpack-dev-server允許我們可以把本地項目跑在像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 建立一個 Web 服務(wù)器
  • --devtool eval:為你的代碼創(chuàng)建源地址。當(dāng)有任何報錯的時候可以讓你更加精確地定位到文件和行號
  • --progress: 顯示合并代碼進度
  • --colors: 在命令行中顯示顏色
  • --content-base build:指向設(shè)置的輸出目錄

在webpack.config.js中配置webpack-dev-server,在這里需要修改下entry的路徑,給它加一個webpack/hot/dev-server,這里會用到Hot Module Replacement(熱替換)插件,所以需要增加這個前綴,后文會提到,代碼如下:

//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中的一個全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄 
    output: {//輸出目錄 
        path: __dirname + '/build',//打包后的js文件存放的地方 
        filename: 'bundle.js'//打包后輸出的js的文件名 
    }, 
    module: { //loaders加載器 
        loaders: [ { 
            test: /\.(js|jsx)$/,//一個匹配loaders所處理的文件的拓展名的正則表達式,這里用來匹配js和jsx文件(必須) 
            exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選) 
            loader: 'babel'//loader的名稱(必須) 
        } ] 
    }, 
    //webpack-dev-server配置 
    devServer: { 
        contentBase: './build',//默認webpack-dev-server會為根文件夾提供本地服務(wù)器,如果想為另外一個目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄) 
        colors: true,//在cmd終端中輸出彩色日志 
        historyApiFallback: true,//在開發(fā)單頁應(yīng)用時非常有用,它依賴于HTML5 history API,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html 
        inline: true,//設(shè)置為true,當(dāng)源文件改變時會自動刷新頁面 
        port: 8080,//設(shè)置默認監(jiān)聽端口,如果省略,默認為"8080" 
        process: true,//顯示合并代碼進度 
    }
};

在瀏覽器中打開http://localhost:8080/,如果頁面上是空白的,沒有內(nèi)容,按F12打開控制臺,可以清除地看到錯誤提示:Uncaught Error: [HMR] Hot Module Replacement is disabled
現(xiàn)在我們來安裝和配置這個Hot Module Replacement。

新版本的webpack(當(dāng)前我使用的是webpack3.0),這樣配置會有問題。
如果用的不是webpack3,可以忽略下面這部分,直接看#10


新版webpack沿用上面的配置文件報錯

建議
1.webpack3的朋友,按下面的代碼配置,或者將webpack的版本退回我圖上的版本,進行操作。
2.推薦先看第十步的內(nèi)容,可以幫助大家了解下面代碼中的HotModuleReplacementPlugin

webpack3 配置
//webpack-dev-server配置 
    plugins: [
      new webpack.HotModuleReplacementPlugin({
          contentBase: './build',//默認webpack-dev-server會為根文件夾提供本地服務(wù)器,如果想為另外一個目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄) 
          colors: true,//在cmd終端中輸出彩色日志 
          historyApiFallback: true,//在開發(fā)單頁應(yīng)用時非常有用,它依賴于HTML5 history API,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html 
          inline: true,//設(shè)置為true,當(dāng)源文件改變時會自動刷新頁面 
          port: 8080,//設(shè)置默認監(jiān)聽端口,如果省略,默認為"8080" 
          process: true,//顯示合并代碼進度 
      })
    ]
  • 10.Hot Module Replacement

Hot Module Replacement(HMR)是webpack里很有用的一個插件,它允許你在修改組件代碼后,自動刷新實時預(yù)覽修改后的效果。
在webpack中實現(xiàn)HMR也很簡單,只需要做兩項配置

1.在webpack配置文件中添加HMR插件;
2.在Webpack Dev Server中添加“hot”參數(shù);

不過配置完這些后,JS模塊其實還是不能自動熱加載的,還需要在你的JS模塊中執(zhí)行一個Webpack提供的API才能實現(xiàn)熱加載,雖然這個API不難使用,但是如果是React模塊,使用我們已經(jīng)熟悉的Babel可以更方便的實現(xiàn)功能熱加載。
整理下我們的思路,具體實現(xiàn)方法如下

  • Babel和webpack是獨立的工具
  • 二者可以一起工作
  • 二者都可以通過插件拓展功能
  • HMR是一個webpack插件,它讓你能瀏覽器中實時觀察模塊修改后的效果,但是如果你想讓它工作,需要對模塊進行額外的配額;
  • Babel有一個叫做react-transform-hrm的插件,可以在不對React模塊進行額外的配置的前提下讓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中的一個全局變量,它指向當(dāng)前執(zhí)行腳本所在的目錄 
    output: {//輸出目錄 
        path: __dirname + '/build',//打包后的js文件存放的地方 
        filename: 'bundle.js'//打包后輸出的js的文件名 
    }, 
    module: { //loaders加載器 
        loaders: [ { 
            test: /\.(js|jsx)$/,//一個匹配loaders所處理的文件的拓展名的正則表達式,這里用來匹配js和jsx文件(必須) 
            exclude: /node_modules/,//屏蔽不需要處理的文件(文件夾)(可選) 
            loader: 'babel'//loader的名稱(必須) 
        } ] 
    }, 
    plugins: [    
        new webpack.HotModuleReplacementPlugin()//熱模塊替換插件
    ],
    //webpack-dev-server配置 
    devServer: { 
        contentBase: './build',//默認webpack-dev-server會為根文件夾提供本地服務(wù)器,如果想為另外一個目錄下的文件提供本地服務(wù)器,應(yīng)該在這里設(shè)置其所在目錄(本例設(shè)置到"build"目錄) 
        colors: true,//在cmd終端中輸出彩色日志 
        historyApiFallback: true,//在開發(fā)單頁應(yīng)用時非常有用,它依賴于HTML5 history API,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html 
        inline: true,//設(shè)置為true,當(dāng)源文件改變時會自動刷新頁面 
        port: 8080,//設(shè)置默認監(jiān)聽端口,如果省略,默認為"8080" 
        process: true,//顯示合并代碼進度 
    }
};

現(xiàn)在可以正常工作了,運行npm run dev,待命令行提示webpack: bundle is now VALID后,在瀏覽器中輸入http://localhost:8080,可以看到,正常顯示Hello World
如果覺得這樣不放心,讓我們進行如下額外配置

安裝react-transform-hmr,在不對React模塊進行額外的配置的前提下讓HMR正常工作

npm install --save-dev babel-plugin-react-transform react-transform-hmr

在.babelrc文件里配置babel,注意這里有一堆括號,別寫錯了

//.babelrc
{ 
    "presets": [ 
        "react", 
        "es2015" 
    ], 
    "env": { 
        "development": { 
            "plugins": [ 
                [ 
                    "react-transform", { 
                        "transforms": [{ 
                                "transform": "react-transform-hmr", 
                                "imports": [ "react" ], 
                                "locals": [ "module" ] 
                        }] 
                    }
                ]
             ]
         } 
    }
}

至此,已經(jīng)用webpack構(gòu)建好了React項目的基礎(chǔ)依賴,可以愉快的開發(fā)React程序了。

由于內(nèi)容太多,于是將本文分成了多個部分,下一部分Webpack+React+多語言(二) 插件配置+多語言
github地址:webpack-react-language

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,482評論 2 379

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