React项目构建(利用webpack打包)
引言
最近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这个分支就可。