What、Why、How?解读Webpack官方文档

What is Webpack?

Webpack具有Grunt、Gulp对于静态资源自动化构建的能力,但更重要的是,Webpack弥补了requireJS在模块化方面的缺陷,同时兼容AMD与CMD的模块加载规范,具有更强大的JS模块化的功能。

因此我理解的Webpack,就是一个更出色的前端自动化构建工具、模块化工具、资源管理工具。

webpack is a module bundler. webpack takes modules with dependencies and generates static assets representing those modules.


Why Webpack?

为什么选择Webpack,两点原因。
1、前端需要模块化:JS模块化不仅仅为了提高代码复用性,更是为了让资源文件更合理地进行缓存;

2、AMD与CMD规范日渐衰弱:原因?ES6带来了很强的模块化语法糖。虽然ES6的更多语法糖让JS可能失去了简单的优势,在一些技术社区还偶尔看到一些反ES6的文章,但感觉ES6仍然是未来发展的趋势;

参考使用简单的JavaScript,我们为什么应该抵制ES6例子。

当然,ES6,我觉得还是未来的事情,尤其是在China地盘要全面普及支持ES6的高级浏览器,真的比证明你妈是你妈还要困难。

所以,我认为,AMD跟CMD慢慢过时的原因,是模块化前端项目的发布打包问题,requireJS跟seaJS都没有一个很好的解决方案。下面配置文件是,我曾经做过的一个backbone的项目以requireJS做模块化加载。项目初始阶段还好,当随着项目深入,模块切分得越细,最后发布上线的时候,页面对于JS的请求数量竟然多达20个以上。大量的HTTPRequest造成的后果,不用多想,大家都知道。

为了解决这个问题,引入的RequireJS的优化方案:r.js Optimizer。详情:前端优化:RequireJS Optimizer 的使用和配置方法

 

r.js同样可以对各个js进行压缩混淆优化,并最终在out配置中合并成一个JS文件,然后在页面中调用。就是说,不管三七二十一,每个页面对应引用的JS,都会被打包成一个JS,但这样的话,一个站点中多个页面之间公用的JS模块就无法缓存起来了。

说这么多,其实就是说,Webpack把以上两个问题解决了。

模块化

所有资源都是模块

大家可以回头看下Webpack官方实例图,有一点不知道大家是否注意到:Webpack处理后,输出的静态文件只剩下js与png,而css、less、jade其他的文件都合并到了js中。在Webpack当中,所有资源的都是模块,模块都需要通过AMD或者CMD规范加载,就像css样式文件,不再在HTML中以 <link> 标签加载。

content.js

entry.js

style.css

webpack.config.js

bundle.js

打包好的bundle,包含了样式表在内的静态资源,而index页面下载bundle后,会将样式还原到DOM当中。如下图。

index.html


代码切分

代码切分——抽取多个页面公用模块,打包成commonjs,便于缓存;

两大重要概念:切分点(split point)与代码块(Chunk)

AMD and CommonJs specify different methods to load code on demand.Both are supported and act as split points

AMD与CMD定义引用模块的入口就是切分点

All dependencies at a split point go into a new chunk

切分点定义中依赖的所有模块,合起来就是一个代码块。说白了就是,一个页面引用一个代码块

示例:Github common example

组织结构:build为输出结果目录

逻辑结构

配置代码

 兼容AMD与CMD

CMD允许异步加载,写法:

Note: require.ensure only loads the modules, it doesn’t evaluate them.
注意:只下载,不执行

AMD写法,与requireJS一致:

Note: AMD require loads and evaluate the modules. In webpack modules are evaluated left to right.
注意:与CMD不一样,AMD会下载并执行,执行顺序从左到右

Note: It’s allowed to omit the callback.
注意:并且允许省略回调

无论是AMD与CMD,文件组织方式与模块之间的逻辑都是一样的

AMD示例:Github AMD example

CMD示例:Github CMD example

丑化

webpack提供插件UglifyJsPlugin,可以优化(支持压缩、混淆)代码。插件引用方法详细,请参照。
其中混淆配置是值得注意的,由于AMD中的引用变量或方法名称混淆容易造成错误,因此混淆配置可以控制配置变量不被混淆。

A specific configuration is about mangling variable names. By default the mangle option is false. But you can say to the plugin avoid mangling a variable name passing a except list:

配置以下列表,在混淆代码时,以下配置的变量,不会被混淆

以上变量‘$super’, ‘$’, ‘exports’ or ‘require’,不会被混淆

Example:Github uglify example

entry.js

 

版本控制

对于静态资源的版本控制,目前微信项目采取办法是版本号作为请求参数,版本号为发布日期,但有两个问题:
1、更新版本时,CDN不能及时更新;
2、没有发生变更的文件也被赋上新版本

Webpack的做法是,生成hash,区分文件。

Compute a hash of all chunks and add it.
生成所有代码块的hash

配置方法

生成结果

Compute a hash per chunk and add it.
生成单个代码块文件的hash

配置方法

 How to use?

安装

全局安装,在任意目录,输入以下命令

仅在项目在中安装,切换到项目根目录,输入以下命令

检查安装成功后,显示如下。

加载插件(Plugin)

引用项目根目录node_modules

 加载加载器(Loaders)

通过加载器可以加载不同的资源文件进去各种操作,例如CoffeeScript及JSX……

安装加载器命令

加载器应用方法有3种:

  1. explicit in the require statement (通过require语句,显示引用)
  2. configured via configuration (通过configuration来配置)
  3. configured via CLI (通过CLI配置)

引入方法如下:

配置方法如下:

 

1 5 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部