最近React做爲當前最爲火熱的前端框架。最近也相繼而出來相關ES7的新語法。html
固然,在使用React開發web項目的時候,不得不提到的就是與之配套的相應的打包技術,以前上文已經簡單的提到React+webpack的相關環境搭建。前端
不過昨天,在技術羣聊裏,又有人提到,如何更好的利用webpack進行開發與打包。那麼今天,我就用一個例子來解釋一下,利用webpack來打包react項目與發佈的相關配置(包含Request請求和React-router的路由跳轉哦)。node
固然須要安裝WebStrom和node.js啦~至於下載地址,請看上文:React+Webpack+ES6環境搭建(自定義框架)react
首先來講說,本項目基本用到的一些開發組件(package.json):webpack
"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的配置,利用於調試以及用戶服務端口配置git
/** * 建立時間: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以後,有一些小坑,須要修復,下文會提到。github
首先,能夠配置調試文件(webpack.config.js)和發佈配置文件(webpack.production.config.js)web
'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語法不識別,npm
以前版本的寫法:json
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這個分支就可。