webpack

什么是Webpack?

事实上它是一个打包工具,而不是像RequireJS或SeaJS这样的模块加载器,经过使用Webpack,可以像Node.js同样处理依赖关系,而后解析出模块之间的依赖,将代码打包javascript

安装Webpack

首先得有Node.jscss

而后经过npm install -g webpack安装webpack,固然也能够经过gulp来处理webpack任务,若是使用gulp的话就npm install --save-dev gulp-webpackhtml

配置Webpack

Webpack的构建过程须要一个配置文件,一个典型的配置文件大概就是这样java

var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { entry: { entry1: './entry/entry1.js', entry2: './entry/entry2.js' }, output: { path: __dirname, filename: '[name].entry.js' }, resolve: { extensions: ['', '.js', '.jsx'] }, module: { loaders: [{ test: /\.js$/, loader: 'babel-loader' }, { test: /\.jsx$/, loader: 'babel-loader!jsx-loader?harmony' }] }, plugins: [commonsPlugin] }; 

这里对Webpack的打包行为作了配置,主要分为几个部分:react

  • entry:指定打包的入口文件,每有一个键值对,就是一个入口文件
  • output:配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称,filename里面的[name]会由entry中的键(这里是entry1和entry2)替换
  • resolve:定义了解析模块路径时的配置,经常使用的就是extensions,能够用来指定模块的后缀,这样在引入模块时就不须要写后缀了,会自动补全
  • module:定义了对模块的处理逻辑,这里能够用loaders定义了一系列的加载器,以及一些正则。当须要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的缘由。好比这里定义了凡是.js结尾的文件都是用babel-loader作处理,而.jsx结尾的文件会先通过jsx-loader处理,而后通过babel-loader处理。固然这些loader也须要经过npm install安装
  • plugins: 这里定义了须要使用的插件,好比commonsPlugin在打包多个入口文件时会提取出公用的部分,生成common.js

固然Webpack还有不少其余的配置,具体能够参照它的配置文档webpack

执行打包

若是经过npm install -g webpack方式安装webpack的话,能够经过命令行直接执行打包命令,好比这样:git

$webpack --config webpack.config.js 

这样就会读取当前目录下的webpack.config.js做为配置文件执行打包操做程序员

若是是经过gulp插件gulp-webpack,则能够在gulpfile中写上gulp任务:es6

var gulp = require('gulp'); var webpack = require('gulp-webpack'); var webpackConfig = require('./webpack.config'); gulp.task("webpack", function() { return gulp .src('./') .pipe(webpack(webpackConfig)) .pipe(gulp.dest('./build')); }); 

组件编写

使用Babel提高逼格

Webpack使得咱们可使用Node.js的CommonJS规范来编写模块,好比一个简单的Hello world模块,就能够这么处理:github

var React = require('react'); var HelloWorldComponent = React.createClass({ displayName: 'HelloWorldComponent', render: function() { return ( <div>Hello world</div> ); } }); module.exports = HelloWorldComponent; 

等等,这和以前的写法没啥差异啊,依旧没有逼格...程序员敲码要有geek范,要逼格than逼格,这太low了。如今都ES6了,React的代码也要写ES6,babel-loader就是干这个的。Babel可以将ES6代码转换成ES5。首先须要经过命令npm install --save-dev babel-loader来进行安装,安装完成后就可使用了,一种使用方式是以前介绍的在webpack.config.js的loaders中配置,另外一种是直接在代码中使用,好比:

var HelloWorldComponent = require('!babel!jsx!./HelloWorldComponent'); 

那咱们应当如何使用Babel提高代码的逼格呢?改造一下以前的HelloWorld代码吧:

import React from 'react'; export default class HelloWorldComponent extends React.Component { constructor() { super(); this.state = {}; } render() { return ( <div>Hello World</div> ); } } 

这样在其余组件中须要引入HelloWorldComponent组件,就只要就能够了:

import HelloWorldComponent from './HelloWorldComponent' 

怎么样是否是更有逼格了?经过import引入模块,还能够直接定义类和类的继承关系,这里也再也不须要getInitialState了,直接在构造函数constructor中用this.state = xxx就行了

Babel带来的固然还不止这些,在其帮助下还能尝试不少优秀的ES6特性,好比箭头函数,箭头函数的特色就是内部的this和外部保持一致,今后能够和that_this说再见了

['H', 'e', 'l', 'l', 'o'].map((c) => { return (<span>{c}</span>); }); 

其余还有不少,具体能够参照Babel的学习文档

样式编写

我是一个强烈地Less依赖患者,脱离了Less直接写CSS就会出现四肢乏力、不想干活、心情烦躁等现象,并且还不喜欢在写Less时候加前缀,日常都是gulp+less+autoprefixer直接处理的,那么在Webpack组织的React组件中要怎么写呢?

没错,依旧是使用loader

能够在webpack.config.js的loaders中增长Less的配置:

{
  test: /\.less$/, loader: 'style-loader!css-loader!autoprefixer-loader!less-loader' } 

经过这样的配置,就能够直接在模块代码中引入Less样式了:

import React from 'react'; require('./HelloWorldComponent.less'); export default class HelloWorldComponent extends React.Component { constructor() { super(); this.state = {}; } render() { return ( <div>Hello World</div> ); } } 

其余

Webpack的loader为React组件化提供了不少帮助,像图片也提供了相关的loader:

{ test: /\.png$/, loader: "url-loader?mimetype=image/png" } 

更多地loader能够移步webpack的wiki

在Webpack下实时调试React组件

Webpack和React结合的另外一个强大的地方就是,在修改了组件源码以后,不刷新页面就能把修改同步到页面上。这里须要用到两个库webpack-dev-serverreact-hot-loader

首先须要安装这两个库,npm install --save-dev webpack-dev-server react-hot-loader

安装完成后,就要开始配置了,首先须要修改entry配置:

entry: {
  helloworld: [
    'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server', './helloworld' ] }, 

经过这种方式指定资源热启动对应的服务器,而后须要配置react-hot-loader到loaders的配置当中,好比个人全部组件代码所有放在scripts文件夹下:

{
  test: /\.js?$/, loaders: ['react-hot', 'babel'], include: [path.join(__dirname, 'scripts')] } 

最后配置一下plugins,加上热替换的插件和防止报错的插件:

plugins: [
  new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ] 

这样配置就完成了,可是如今要调试须要启动一个服务器,并且以前配置里映射到http://localhost:3000,因此就在本地3000端口起个服务器吧,在项目根目录下面建个server.js:

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, historyApiFallback: true }).listen(3000, 'localhost', function (err, result) { if (err) console.log(err); console.log('Listening at localhost:3000'); }); 

这样就能够在本地3000端口开启调试服务器了,好比个人页面是根目录下地index.html,就能够直接经过http://localhost:3000/index.html访问页面,修改React组件后页面也会被同步修改,这里貌似使用了websocket来同步数据。图是一个简单的效果:

相关文章
相关标签/搜索