@chris-ren
2016-04-27T07:08:26.000000Z
字数 5095
阅读 1206
Webpack
Webpack是一个强大的前端模块管理和打包工具,出自Facebook的Instagram团队。虽然说Webpack是一个通用的工具,并不只适合于React,但是很多React的文章或者项目都使用了Webpack,尤其是react-hot-loader(React 热插拔)的存在,让Webpack成为最主流的React开发工具。
从图中可以看到Webpack的目标就是对项目中的静态资源进行统一管理,为产品的最终发布提供最优的打包部署方案。
1.安装node.js 包含npm。
2.安装webpack,使用 npm 的形式来安装
$ npm install webpack -g
3.添加package.json配置文件
$ npm init
4.在package.json中安装并添加webpack
$ npm install webpack --save-dev
说明:通过这种方式安装时,将信息写入package.json中,直接使用npm install方法就可以根据dependencies配置安装所有的依赖包,这样代码提交到github时,就不用提交node_modules这个文件夹了。
带版本的安装
$ npm install webpack@1.2.x --save-dev
5.安装开发工具
$ npm install webpack-dev-server --save-dev
通常我们会把Webpack相关参数定义在配置文件,配置文件名称一般为webpack.config.js。配置文件通常放在项目根目录之下,其本身也是一个标准的CommonJS模块。
一个最简单的Webpack配置文件webpack.config.js如下所示:
module.exports = {entry:['./app/main.js'],output: {path: __dirname + '/assets/',publicPath: "/assets/",filename: 'bundle.js'}};
其中entry参数定义了打包的入口文件,数组中的所有文件会按顺序打包。每个文件进行依赖的递归查找,直到所有相关模块都被打包。output参数定义了输出文件的位置,其中常用的参数包括:
•path: 打包文件存放的绝对路径
•publicPath: 网站运行时的访问路径
•filename: 打包后的文件名
下面做一个小小的演示,说明Webpack是如何打包一个React组件的。假设有如下项目结构:
- react-sample+ assets/- js/Hello.jsentry.jsindex.htmlwebpack.config.js
其中Hello.js定义了一个简单的React组件,使用ES6语法:
var React = require('react');class Hello extends React.Component {render() {return (<h1>Hello {this.props.name}!</h1>);}}
entry.js是入口文件,将一个Hello组件输出到界面:
var React = require('react');var Hello = require('./Hello');React.render(<Hello name="Nate" />, document.body);
index.html的内容如下:
<html><head></head><body><script src="/assets/bundle.js"></script></body></html>
在这里Hello.js和entry.js都是JSX组件语法,需要对它们进行预处理,这就要引入webpack的JSX加载器。因此在配置文件中加入如下配置:
module: {loaders: [{ test: /\.jsx?$/, loaders: ['jsx?harmony']}]}
执行webpack命令:
webpack —config webpack.custom.config.js
这样会在assets目录将生成bundle.js,打包了entry.js的内容。当浏览器打开当前服务器上的index.html,将显示“Hello Nate!”。
entry: ["./entry1"]
entry: ["./entry1", "./entry2"]
{entry: {page1: "./page1",page2: ["./entry1", "./entry2"]},output: {// Make sure to use [name] or [id] in output.filename// when using multiple entry pointsfilename: "[name].bundle.js",chunkFilename: "[id].bundle.js"}}
将项目中的模块打包成多个资源文件有两个目的:
1.将多个页面的公用模块独立打包,从而可以利用浏览器缓存机制来提高页面加载效率;
2.减少页面初次加载时间,只有当某功能被用到时,才去动态的加载。
{entry: {app: './src/app.js',search: './src/search.js'},output: {filename: '[name].js',path: __dirname + '/built',publicPath: "/assets/"}}
publicPath主要是用于href or url()等的引用。
loader格式说明:
{module: {loaders: [{ test: /\.css$/, loader: "style" },// => "style" loader用于 ".css" 文件{ test: /\.css$/, loader: "style!css" },// => "style" 和 "css" loader 用于 ".css" files//也可以用数组形式:{ test: /\.css$/, loaders: ["style", "css"] },// =>带参数的loader{ test: /\.png$/,loader:"url-loader?mimetype=image/png" },//或者{test: /\.png$/,loader: "url-loader",query: { mimetype: "image/png" }}]}}
举例如下:
module: {preLoaders: [{test: /\.js$/,exclude: /node_modules/,loader: 'jsxhint'}],loaders: [{test: /\.js$/,exclude: /node_modules/,loader: 'react-hot!jsx-loader?harmony'}, {test: /\.less/,loader: 'style-loader!css-loader!less-loader'}, {test: /\.(css)$/,loader: 'style-loader!css-loader'}, {test: /\.(png|jpg)$/,loader: 'url-loader?limit=8192'}]}
可以看到,该使用什么加载器完全取决于这里的配置,除了已有加载器,也可以自己实现自己的加载器,从而可以让Webpack统一管理项目特定的静态资源。现在也已经有很多第三方的加载器实现常见静态资源的打包管理,可以参考Webpack主页上的加载器列表。
resolve: {extensions: ['', '.js', '.jsx'],},
Webpack提供了一个基于Node.js Express框架的开发服务器——webpack-dev-server,在开发过程中,开发服务器会监听每一个文件的变化,进行实时打包,并且可以推送通知前端页面代码发生了变化,从而可以实现页面的自动刷新。但是,这个过程相对比较复杂,需要进行多方面考虑和配置。而针对React出现了一个第三方react-hot-loader加载器,使用这个加载器就可以轻松实现React组件的热替换,非常方便。
react-hot-loader安装:
npm install --save-dev react-hot-loader
Webpack开发服务器需要开启HMR参数hot,为了方便,我们创建一个名为server.js的文件用以启动Webpack开发服务器:
var webpack = require('webpack');var WebpackDevServer = require('webpack-dev-server');var config = require('../webpack.config');new WebpackDevServer(webpack(config), {publicPath: config.output.publicPath,hot: true,noInfo: false,historyApiFallback: true}).listen(8080, '127.0.0.1', function (err, result) {if (err) {console.log(err);}console.log('Listening at localhost:8080');});
为了热加载React组件,我们需要在webpack.config.js配置文件中加入相应的代码,用以接收Webpack推送过来的代码模块,进而可以通知所有相关React组件进行重新Render。
entry: ['webpack-dev-server/client?http://localhost:8080', // WebpackDevServer host and port'webpack/hot/only-dev-server']
添加react-hot-loader加载器
{test: /\.jsx?$/,loaders: ['react-hot', 'babel?stage=1'],include: __dirname+'/app',}
配置完成后,使用Node.js运行server.js:
node server.js
即可启动开发服务器并实现React组件的热加载。为了方便,我们也可以在package.json中加入配置:
"scripts": {"start": "node ./js/server.js"}
从而通过npm start命令启动开发服务器。
参考资料:
Webpack官网:http://webpack.github.io/
Webpack官方文档:http://webpack.github.io/docs/