前端学堂
学有所用

Webpack模块加载神器


什么是Webpack

Webpack 是德国开发者 Tobias Koppers 开发的模块加载器。Instagram 工程师认为这个方案很棒, 似乎还把作者招过去了。在 Webpack 当中, 所有的资源都被当作是模块, js, css, 图片等等..因此, Webpack 当中 js 可以引用 css, css 中可以嵌入图片 dataUrl。对应各种不同文件类型的资源, Webpack 有对应的模块 loader, 比如 CoffeeScript 用的是 coffee-loader, 其他还有很多:https://webpack.github.io/docs/list-of-loaders.html

Webpack模块加载神器

大致的写法也就这样子:

1
2
3
4
5
6
module: {
loaders: [
{ test: //.coffee$/, loader: 'coffee-loader' },
{ test: //.js$/, loader: 'jsx-loader?harmony' } // loaders can take parameters as a querystring
]
}

CommonJS 与 AMD 支持

Webpack 对 CommonJS 的 AMD 的语法做了兼容, 方便迁移代码。不过实际上, 引用模块的规则是依据 CommonJS 来的

1
2
require('lodash') // 从模块目录查找
require('./file') // 按相对路径查找

AMD 语法中, 也要注意, 是按 CommonJS 的方案查找的:

1
2
3
define (require, exports. module) ->
require('lodash') # commonjs 当中这样是查找模块的
require('./file')

特殊模块的Shim

比如某个模块依赖 window.jQuery, 需要从 npm 模块中将 jquery 挂载到全局。Webpack 有不少的 Shim 的模块, 比如 expose-loader 用于解决这个问题,https://github.com/webpack/docs/wiki/shimming-modules,其他比如从模块中导出变量…具体说明有点晦涩..

手头的两个例子, 比如我们用到 Pen 这个模块,这个模块对依赖一个 window.jQuery, 可我手头的 jQuery 是 CommonJS 语法的
而 Pen 对象又是生成好了绑在全局的, 可是我又需要通过 require(‘pen’) 获取变量,最终的写法就是做 Shim 处理直接提供支持:

1
2
{test: require.resolve('jquery'), loader: 'expose?jQuery'},
{test: require.resolve('pen'), loader: 'exports?window.Pen'},

基本的使用

安装 webpack 模块之后, 可是使用 webpack 这个命令行工具。可以使用参数, 也可以配置 webpack.config.js 文件直接运行 webpack 调用
建议按照 Peter Hunt 给的教程走一遍, 基本的功能都会用到了:https://github.com/petehunt/webpack-howto

简单的例子就是这样一个文件, 可以把 ./main.js 作为入口打包 bundle.js:

1
2
3
4
5
6
7
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};

查找依赖

Webpack 是类似 Browserify 那样在本地按目录对依赖进行查找的,可以构造一个例子, 用 –display-error-details 查看查找过程,
例子当中 resolve.extensions 用于指明程序自动补全识别哪些后缀,注意一下, extensions 第一个是空字符串! 对应不需要后缀的情况.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// webpack.config.js
module.exports = {
entry: './a.js',
output: {
filename: 'b.js'
},
resolve: {
extensions: ['', '.coffee', '.js']
}
}
// a.js
require('./c')
➤➤ webpack --display-error-details
Hash: e38f7089c39a1cf34032
Version: webpack 1.5.3
Time: 54ms
Asset Size Chunks Chunk Names
b.js 1646 0 [emitted] main
[0] ./a.js 15 {0} [built] [1 error]
ERROR in ./a.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./c in /Users/chen/Drafts/webpack/details
resolve file
/Users/chen/Drafts/webpack/details/c doesn't exist
/Users/chen/Drafts/webpack/details/c.coffee doesn't exist
/Users/chen/Drafts/webpack/details/c.js doesn't exist
resolve directory
/Users/chen/Drafts/webpack/details/c doesn't exist (directory default file)
/Users/chen/Drafts/webpack/details/c/package.json doesn't exist (directory description file)
[/Users/chen/Drafts/webpack/details/c]
[/Users/chen/Drafts/webpack/details/c.coffee]
[/Users/chen/Drafts/webpack/details/c.js]
@ ./a.js 2:0-14

./c 是不存在, 从这个错误信息当中我们大致能了解 Webpack 是怎样查找的。大概就是会尝试各种文件名, 会尝试作为模块, 等等
一般模块就是查找 node_modules, 但这个也是能被配置的:
https://webpack.github.io/docs/configuration.html#resolve-modulesdirectories

CSS 及图片的引用

英文的教程上有明确的例子:
https://github.com/petehunt/webpack-howto#5-stylesheets-and-images

1
2
3
4
5
require('./bootstrap.css');
require('./myapp.less');
var img = document.createElement('img');
img.src = require('./glyph.png');

上边的是 JavaScript 代码, CSS 跟 LESS, 还有图片, 被直接引用了,实际上 CSS 被转化为

赞(1) 打赏
未经允许不得转载:前端学堂 » Webpack模块加载神器

评论 抢沙发

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏