#WebPack是什么
一个打包工具
一个模块加载工具
各种资源都可以当成模块来处理
网站 http://webpack.github.io/ 如今,越来越多的JavaScript代码被使用在页面上,我们添加很多的内容在浏览器里。如何去很好的组织这些代码,成为了一个必须要解决的难题。
对于模块的组织,通常有如下几种方法:
通过书写在不同文件中,使用script标签进行加载
CommonJS进行加载(NodeJS就使用这种方式)
AMD进行加载(require.js使用这种方式)
ES6模块
setup 安装命令 $ npm install webpack -g 使用webpack $ npm init # 会自动生成一个package.json文件 $ npm install webpack –save-dev #将webpack增加到package.json文件中 可以使用不同的版本 $ npm install webpack@1.2.x –save-dev 如果想要安装开发工具 $ npm install webpack-dev-server –save-dev $ webpack-dev-server –progress –colors 服务器可以自动生成和刷新,修改代码保存后自动更新画面 $ http://localhost:8080/webpack-dev-server/bundle
Loader Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。
Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require
来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。
先来看看 loader 有哪些特性?
Loader 可以通过管道方式链式调用,每个 loader 可以把资源转换成任意格式并传递给下一个 loader ,但是最后一个 loader 必须返回 JavaScript。
Loader 可以同步或异步执行。
Loader 运行在 node.js 环境中,所以可以做任何可能的事情。
Loader 可以接受参数,以此来传递配置项给 loader。
Loader 可以通过文件扩展名(或正则表达式)绑定给不同类型的文件。
Loader 可以通过 npm
发布和安装。
除了通过 package.json
的 main
指定,通常的模块也可以导出一个 loader 来使用。
Loader 可以访问配置。
插件可以让 loader 拥有更多特性。
Loader 可以分发出附加的任意文件。
Loader 本身也是运行在 node.js 环境中的 JavaScript 模块,它通常会返回一个函数。大多数情况下,我们通过 npm 来管理 loader,但是你也可以在项目中自己写 loader 模块。
按照惯例,而非必须,loader 一般以 xxx-loader
的方式命名,xxx
代表了这个 loader 要做的转换功能,比如 json-loader
。
在引用 loader 的时候可以使用全名 json-loader
,或者使用短名 json
。这个命名规则和搜索优先级顺序在 webpack 的 resolveLoader.moduleTemplates
api 中定义。
1
Default: ["*-webpack-loader", "*-web-loader", "*-loader", "*"]
Loader 可以在 require()
引用模块的时候添加,也可以在 webpack 全局配置中进行绑定,还可以通过命令行的方式使用。
接上一节的例子,我们要在页面中引入一个 CSS 文件 style.css,首页将 style.css 也看成是一个模块,然后用 css-loader
来读取它,再用 style-loader
把它插入到页面中。
1
2
body { background : yellow; }
修改 entry.js:
1
2
3
require ("!style!css!./style.css" )
document .write('It works.' )
document .write(require ('./module.js' ))
安装 loader:
1
npm install css-loader style-loader
重新编译打包,刷新页面,就可以看到黄色的页面背景了。
如果每次 require
CSS 文件的时候都要写 loader 前缀,是一件很繁琐的事情。我们可以根据模块类型(扩展名)来自动绑定需要的 loader。
将 entry.js 中的 require("!style!css!./style.css")
修改为 require("./style.css")
,然后执行:
1
2
3
4
$ webpack entry.js bundle.js --module-bind 'css=style!css'
$ webpack entry.js bundle.js --module-bind "css=style!css"
显然,这两种使用 loader 的方式,效果是一样的。
config 每个项目下都必须配置有一个 webpack.config.js
基本示例1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
}
下面是一个较完整的例子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
var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
module.exports = {
//插件项
plugins: [commonsPlugin],
//页面入口文件配置
entry: {
index : './src/js/page/index.js'
},
//入口文件输出配置
output: {
path: 'dist/js/page',
filename: '[name].js'
},
module: {
//加载器配置
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' },
{ test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
]
},
//其它解决方案配置
resolve: {
root: 'E:/github/flux-example/src', //绝对路径
extensions: ['', '.js', '.json', '.scss'],
alias: {
AppStore : 'js/stores/AppStores.js',
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
}
}
};
plugins 是插件项,这里我们使用了一个 CommonsChunkPlugin的插件,它用于提取多个入口文件的公共脚本部分,然后生成一个 common.js 来方便多页面之间进行复用。 entry 是页面入口文件配置,output 是对应输出项配置 (即入口文件最终要生成什么名字的文件、存放到哪里) module.loaders 是最关键的一块配置。它告知 webpack 每一种文件都需要使用什么加载器来处理。 所有加载器需要使用npm来加载 最后是 resolve 配置,配置查找模块的路径和扩展名和别名(方便书写)