引言
最近React作為當前最為火熱的前端框架。最近也相繼而出來相關ES7的新語法。
當然,在使用React開發web項目的時候,不得不提到的就是與之配套的相應的打包技術,之前上文已經簡單的提到React+webpack的相關環境搭建。
不過昨天,在技術群聊里,又有人提到,如何更好的利用webpack進行開發與打包。那么今天,我就用一個例子來解釋一下,利用webpack來打包react項目與發布的相關配置(包含Request請求和React-router的路由跳轉哦)。
准備工作
當然需要安裝WebStrom和node.js啦~至於下載地址,請看上文:React+Webpack+ES6環境搭建(自定義框架)
讓我們跑起來吧
首先來說說,本項目基本用到的一些開發組件(package.json):
- 開發中需要用到的,我全部放在devDependencies(npm install ...... --save-dev)中;
- 項目中有用到的組件,我全部放在dependencies(npm install ...... --save)中;
"devDependencies": { "babel-core": "^6.18.2", "babel-loader": "^6.2.8", "babel-polyfill": "^6.16.0", "babel-preset-latest": "^6.16.0", "babel-preset-react": "^6.16.0", "open": "0.0.5", "react-hot-loader": "^3.0.0-beta.6", "webpack": "^1.13.3", "webpack-dev-server": "^1.16.2" }, "dependencies": { "echarts": "^3.3.1", "isomorphic-fetch": "^2.2.1", "lodash": "^4.17.2", "react": "^15.4.0", "react-dom": "^15.4.0", "react-router": "^3.0.0" }
接下來,就是server.js的配置,利用於調試以及用戶服務端口配置

/** * 創建時間:2016年9月19日 10:12:44 * 創建人:JaminHuang * 描述:用於服務端口配置 */ 'use strict'; var open = require('open'); var webpack =require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config.js'); var compiler = webpack(config); var server = new WebpackDevServer(compiler, { publicPath:config.output.publicPath, hot:true, historyApiFallback: true, quiet: false, noInfo: false, filename: "index.js", watchOptions: { aggregateTimeout: 300, poll: 1000 }, headers: {"X-Custom-Header": "yes"}, stats: {colors: true} }); server.listen(3010, function (err, result) { if (err)console.log(err); open('http://localhost:3010'); });
配置完成后,並且在建立index.js的主入口文件后(具體怎么建立,請看前文環境搭建,這里就不重復講了)。下面就是核心,webpack.config.js的配置啦。不過這里項目用引用了熱加載(react-hot-loader),而該組件在更新版本3.0.0之后,有一些小坑,需要修復,下文會提到。
首先,可以配置調試文件(webpack.config.js)和發布配置文件(webpack.production.config.js)

'use strict'; var path = require('path'); var webpack = require('webpack'); var config = { devtool: 'source-map', entry: { app: ['webpack-dev-server/client?http://localhost:3010', 'webpack/hot/dev-server', './src/index'] }, output: { path: path.join(__dirname, 'public'), publicPath: '/public/', //chunkFilename: '[id].chunk.js', filename: "bundle.js" }, module: { loaders: [ {test: /\.js$/, loader: 'babel', include: path.join(__dirname, 'src')} ] }, plugins: [ new webpack.HotModuleReplacementPlugin(), //new webpack.optimize.CommonsChunkPlugin('shared.js'), new webpack.DefinePlugin({ 'process.env': { 'DEBUG': true } }) ] }; module.exports = config;

'use strict'; var path = require('path'); var webpack = require('webpack'); module.exports = { devtool: false, debug: false, stats: { colors: true, reasons: false }, entry: './src/index', output: { path: path.join(__dirname, 'public'), publicPath: '/public/', //chunkFilename: '[id].chunk.js', filename: 'bundle.js' }, plugins: [ new webpack.optimize.DedupePlugin(), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production'), 'DEBUG': false } }), //new webpack.optimize.CommonsChunkPlugin('shared.js'), new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false } }), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.AggressiveMergingPlugin(), new webpack.NoErrorsPlugin() ], module: { loaders: [ {test: /\.js$/, loader: "babel", exclude: /node_modules/} ] } };
由於調試文件中,引用了熱加載的問題,所以這里也提一下上面之前遇到的坑。由於3.0.0版本的react-hot-loader,對於webpack中配置的有些loaders語法不識別,
之前版本的寫法:
module: { loaders: [ {test: /\.js$/, loaders: ['react-hot', 'babel'], include: [path.join(__dirname, 'src')]} ] },
調整之后的寫法,別寫需要在之前配置的.babelrc文件中添加一行配置(當然可以寫進):
{ "plugins": ["react-hot-loader/babel"] }
webpack.config中的配置
module: { loaders: [ {test: /\.js$/, loader: 'babel', include: path.join(__dirname, 'src')} ] },
最后,在package.json中配置命令,方便執行就行了:
"scripts": { "start": "node server.js", "prod": "webpack --config webpack.production.config.js" },
這樣一些都配置完成了,如需要調試則輸入"npm start"就行,如需要發布就可以輸入"npm prod"即可
有關發布
這里在說一下,如果想要發布項目的時候,在輸入"npm prod"之后,(之前根據webpack已經配置好了目錄)只需要到項目跟目錄下把public文件夾和index.html拷出來(因為這里舉例的webpack發布配置,我並沒有將index.html也打包進入public文件夾,所以需要多打包一下)
拷出來后,則可以通過IIS進行項目發布啦。(不過如果利用IIS的話,需要添加URL重寫工具)以及在發布的根目錄下配置web.config文件,配置URL重寫。
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <!-- todo: 也許應該過濾掉靜態文件 --> <rewrite> <rules> <rule name="Main Rule" stopProcessing="true"> <match url="^(?:(?!api).)+" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="/" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
擴展內容
這里再,說一些相關擴展的內容:Request請求處理。本項目中利用了一些isomorphic-fetch組件用於幫助請求,項目中我配置了一個公共請求組件:
'use strict'; import fetch from 'isomorphic-fetch'; const baseUrl = "http://xxx"; export function FetchPost(url, data) { return fetch(`${baseUrl}/${url}`, { headers: {"Content-Type": "application/json"}, method: 'POST', body: JSON.stringify(data) }).then(response=> { return response.json(); }) }
調用方式:
Request.FetchPost("api/Gather/Sign", data).then(json=>{ if (條件 ) { //成功執行.... } else { //失敗執行.... } })
附錄
最后附上我的GitHub上該項目的Demo,如果有需要可以down下來實際操作一下,當然,請別忘記給個Star哈~內容中有分支,一個是項目搭建,一個是百度EChart的Demo,本文例子用master這個分支就可。