Webpack模块加载神器


什么是Webpack

Webpack 是德国开发者 Tobias Koppers 开发的模块加载器。Instagram 工程师认为这个方案很棒, 似乎还把作者招过去了。在 Webpack 当中, 所有的资源都被当作是模块, js, css, 图片等等..因此, Webpack 当中 js 可以引用 css, css 中可以嵌入图片 dataUrl。对应各种不同文件类型的资源, Webpack 有对应的模块 loader, 比如 CoffeeScript 用的是 coffee-loader, 其他还有很多:http://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, 但这个也是能被配置的:
http://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 被转化为

未经允许不得转载:皓眸大前端 » Webpack模块加载神器

赞 (1)
分享到:更多 ()

评论 0