@chris-ren
2016-04-27T07:08:26.000000Z
字数 5095
阅读 1113
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.js
entry.js
index.html
webpack.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 points
filename: "[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/