关于Webpack

或许你对Webpack并没那么熟悉,那你应该听过browserify吧,如果没有听过browserify,那应该知道gulp或者grunt这两个东西吧。

其实Webpack就是一个模块加载器,官方的原话如下:

webpack takes modules with dependencies and generates static assets representing those modules.

在谈Webpack之前,我们先谈谈两个规范:CMDAMD

CMD,也称通用模块定义,是一种同步的模块机制,相信玩过Node的童鞋对下面这种写法一点也不陌生:


var demo = require('otherModule');
// some code...
module.exports = demo;

AMD,也称异步模块定义,是一种异步的模块机制,比较典型的是requireJS的写法:


define( ['module1','module2'], function(module1,module2){
// some code...
return module;
});

对比上面两种规范的写法,显然我们更加愿意接受CMD,相信写过一大堆callback的童鞋深有体会。随着npm成为主流的JavaScript组件发布平台,越来越多的前端项目也依赖于npm上的项目,这时候browserify就出现了,它支持require()的同步语法去加载npm模块。

当然在最近公布的ES2015(ES6)里也定义了一套新的模块机制,写法大概如下:


import {module1} from 'module1';
// some code...
export module2;

为何用webpack

webpack具有非常好的功能特性:

  1. 同时支持CMD和AMD模块;
  2. 支持模块加载器和插件机制,可对模块进行定制;
  3. 可通过配置,打包成多个文件,有效利用浏览器的缓存机制提升性能;
  4. 对样式文件和图片等静态资源视为模块进行打包,配合loader加载器可以支持sass,less等css预处理器;
  5. 内置source map,即使打包在一起依旧方便调试。

webpack使用入门

全局安装webpack

在终端执行下面代码将webpack安装到全局:npm install -g webpack,若是mac或者linux系统提示权限不足,请用sudo npm install -g webpack然后输入管理员密码执行。

初始化项目

  • 新建一个名为xxx的项目,在该项目根目录下打开终端,执行npm init,接下来填写一些项目的基本信息,最后确认ok之后会在根目录下生成package.json文件。

  • 新建一些示例文件,大概示意图如下:

    xxx
    assets
    css
    demo.less
    js
    entry.js
    index.js
    html
    index.html
    build
    package.json(上一步生成的文件)
    webpack.config.js(webpack核心配置文件)

配置webpack.config.js

我们在使用webpack的时候默认配置文件是webpack.config.js,下面配置一下这个js文件(稍微复杂了一点,已经有详细的说明):


var webpack = require('webpack');
module.exports = {
// webpack入口文件
entry : './assets/js/entry.js',
// webpack输出文件,
output : {
path : './build',
publicPath : '/assets/',
filename : 'bundle.js'
},
// loader加载器,包括了less编译,图片压缩为base64,es6转为es5三个
module : {
loaders : [
{ test : /\.less/, loader : 'style-loader!css-loader!less-loader' },
{ test : /\.(png|jpg)$/, loader : 'url-loader?limit=8192' },
{ test : /\.js$/, exclude : /node_modules/, loader : 'babel-loader' }
]
},
// 文件不写扩展名时使用的默认扩展名
resolve : {
extensions : ['', '.js', '.json']
},
// 插件,提取公用的JS出来,重复利用
plugins : [
new webpack.optimize.CommonsChunkPlugin('common.js')
]
};

完善其他demo文件

  • index.html文件

index.html文件只需要引入bundle.js即可,代码如下:

%lt;script src="/assets/bundle.js"></script>
  • index.js文件

index.js文件写了一个es6的demo,代码如下:


class People {
constructor( name ) {
this.name = name;
}
sayHi() {
let name = `hi ${this.name} !`;
console.log(name);
}
}
module.exports = People;

  • entry.js文件

entry.js文件则引入index.js文件以及less样式文件写一些demo代码:


let People = require('./index');
let p = new People('sky');
p.sayHi();
require('../css/demo.less');

  • demo.less

demo.less文件主要写一些演示的样式代码:


h1 {
color:#f00;
font-size:20px;
}

启动webpack

这时候上面的整个项目已经准备好,只需要在项目根目录下面,用webpack的命令执行即可:


// webpack 命令行的几种基本命令,更多命令可以在终端输入webpack --help
$ webpack // 最基本的启动webpack方法
$ webpack -w // 提供watch方法,实时进行打包更新
$ webpack -p // 对打包后的文件进行压缩,提供production
$ webpack -d // 提供source map,方便调试。

验证

经过上一步的webpack执行命令之后,build文件夹下面应该多了一个bundle.js文件,这时候打开index.html文件会发现less样式也已经生效。

实战项目注意点

  • 项目中如果需要引入Zepto这类前端包是不兼容webpack的,需要加入包引出的声明:
    module.exports=Zepto

最后总结

前端组件化是一条很漫长的路,也只有前端这个圈子在不断的造轮子却还依旧欣欣向荣的景象,在新技术层出不穷的情况下,保持对新技术的热情追求,但追根到底,背后的模块化思想才是支持这些东西源源不断的动力。