Webpack最近貌似很火啊,所以挤空学习掌握了一下,主要最近打算做个自己的网站,后端用node+mongodb,所以没什么时间
Webpack是一个模块打包器。它将根据模块的依赖关系进行静态的分析,然后将这些模块按照指定的规则生成对应的静态资源。
虽然市面上已经有很多模块管理工具和打包工具,gulp啊,grunt啊种种。但是这些已有的模块化工具并不能很好的完成如下的目标:
- 将依赖树拆分成按需加载的块
- 初始化加载的耗时尽量少
- 各种静态资源都可以视为模块
- 将第三方库整合成模块的能力
- 可以自定义大包逻辑的能力
- 适合大项目,无论是单页面或者多页面的web应用
Webpack的特点以及优势:
- 代码拆分:webpack有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包
- Loader:wp本身只能处理原生js模块,但loader转换器可以将各种类型的资源转换成js模块,这样,任何资源都可以成为wp可以处理的模块。
- 智能分析:wp有一个智能分析器,基弧可以处理任何第三方库无论他们的模块形式是CommonJS,AMD还是普通的js文件。甚至在加载依赖的时候,允许使用动态表达式require(“./teplates/“+name+”.jade”);
- 插件系统:wp还有一个功能丰富的插件系统。大多数内容功能都是可以基于这个插件系统运行的,还可以开发和使用开源的wp插件,来满足各式各样的需求
- 快速运行:wp使用异步I/O和多级缓存提高运行效率,这使得wp能够以令人难以执行的速度快速增量编译。
安装和使用
webpack的安装首先需要Node.js,因为node自带了软件包管理器nam,wp需要node v0.6以上的支持,当然,这个我们最好是使用最新版稳定的node
用nam安装wp:nam install -g webpack
此时,wp已经安装到全局环境下了,可以通过webpack -h试试
然后在项目中安装wp:
这个和gulp很类似啊,全局安装一个,项目中也需要安装下.
wp目前有两个主版本,一个是在master主干的稳定版,一个是在webpack-2分支的测试版,测试版拥有一些实验性功能并且和稳定版不兼容,在正式项目中应该使用稳定版。
通过 npm info webpack来查看当前wp的信息
然后安装制定的版本的webpack
然后在我们的项目中新建一个index.html,在index.html中引入bundle.js,在新建一个entry.js
运行 webpack entry.js bundle.js
回生成如下的bundle.js文件:
下面我们把一些代码移到我们新建的content.js中,然后修改entry.js文件里的内容如下:
/**
* Created by Nealyang on 16/10/24.
*/
// document.write('it works');
document.write(require('./content'));
content.js文件内容如下:
/**
* Created by Nealyang on 16/10/24.
*/
module.exports = 'It works from contenetJs';
运行命令:
webpack ./entry.js bundle.js
结果我想大家都应该可以想到,可以自己试一试。
wp会分析入口文件,解析包依赖关系的各个文件,这些文件或者模块都打包到bundle.js。wp会给每一个模块分配一个唯一的id并通过id来索引和访问模块。在页面启动的时候会执行entry.js中的代码,其他的模块会运行require的时候再执行。
Loader介绍
wp本身只能处理js模块,如果要处理其它类型的文件,就需要使用loader进行转换
loader可以理解为是模块和资源的转换器,它本身就是一个函数,接受源文件作为参数,转返回转换后的结果。这样我们可以通过require来加载任何类型的模块和文件,比如coffeescript,jsx,less或者图片
先看看Loader有哪些特点:
- Loader可以通过管道方式链式调用(这一点和gulp非常的累死)每一个Loader可以把资源转换成任意格式并传递给下一个Loader,但是最后一个Loader必须返回js。
- Loader可以同步或者异步
- Loader运行在nodejs的环境中,所以可以做任何可能的事情
- Loader可以接受参数,以此来传递配置项给Loader
- Loader可以通过文件扩展名或者正则表达式绑定给不同类型的文件
- Loader可以通过npm安装和发布
- 除了通过package.json的main指定,通常的模块也可以导出一个Loader来使用
- Loader可以访问配置
- 插件可以让Loader拥有更多的特性
- Loader可以分发出附件的任意文件
Loader简单的实例:加载css文件
首先安装loader :npm install css-loader style-loader
注意这里安装loders只需要安装本地的,不要全局的,并且它会创建一个node_modules文件夹。
我们添加一个style.css文件:
body{
background-color: red;
}
然后在entry中添加一行:
/**
* Created by Nealyang on 16/10/24.
*/
// document.write('it works');
require("!style!css!./style.css");
document.write(require('./content'));
最后重新编译。。。
就可以看到背景颜色已经修改为红色了
如果每一次require css文件都要写loader前缀,是一件非常繁琐的事情。
所以我们可以根据模块类型来自动绑定需要的loader这样写
require(“./style.css”);
修改entry.js文件
/**
* Created by Nealyang on 16/10/24.
*/
// document.write('it works');
// require("!style!css!./style.css");
require("./style.css");
document.write(require('./content'));
编译:
webpack ./entry.js bundle.js --module-bind "css=style!css"
注意:!在shell中有特殊意义,需要转义,这样写才会成功的
webpack ./entry.js bundle.js --module-bind "css=style\!css"
当然,这两种方式,效果是一样的
配置文件
webpack在执行的时候除了可以在命令行中传入参数,还可以通过制定的配置文件来执行。默认情况下,会搜索当前目录的webpack.config.js文件,这个文件是一个node.js模块,返回一个json格式的配置信息对象,或者通过—cofnig选项来置顶配置文件。
我们想将配置选项移动到配置文件中,创建一个webpack.config.js
/**
* Created by Nealyang on 16/10/24.
*/
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
现在我们仅仅运行:webpack
这里对Webpack的打包行为做了配置,主要分为几个部分:
- entry:指定打包的入口文件,每有一个键值对,就是一个入口文件
- output:配置打包结果,path定义了输出的文件夹,filename则定义了打包结果文件的名称
- module:定义了对模块的处理逻辑,这里可以用loaders定义了一系列的加载器,以及一些正则。当需要加载的文件匹配test的正则时,就会调用后面的loader对文件进行处理,这正是webpack强大的原因。
如果该项目的增长,编译可能需要更长的时间。所以我们要展示一些进度条。我们想要的颜色…
我们可以这样
webpack--progress--colors
插件可以完成更多 loader 不能完成的功能。
插件的使用一般是在 webpack 的配置信息 plugins 选项中指定。
Webpack 本身内置了一些常用的插件,还可以通过 npm 安装第三方插件。
接下来,我们利用一个最简单的 BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。
修改 webpack.config.js,添加 plugins:
var webpack = require('webpack');
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{test: /\.css$/, loader: 'style!css'}
]
},
plugins: [
new webpack.BannerPlugin('This file is created by mutouren')
]
}
然后运行 webpack,打开 bundle.js,可以看到文件头部出现了我们指定的注释信息
模块别名定义,方便后续直接引用别名,无须多写长长的地址,比如我们现在想要把scripts/jquery.min.jsjquery压缩文件打包.
别名(resolve.alias) 是 Webpack 的一个配置项,它的作用是把用户的一个请求重定向到另一个路径,例如通过修改 webpack.config.js 配置文件,jquery为别名加入
resolve: {
alias: {
jquery: "./scripts/jquery.min.js"
}
}
例如我们之前不用别名,在entry.js中,想要把jquery打包
require('./scripts/jquery.min.js');
设置别名,就可以修改为
require('jquery');
这样待打包的脚本中的 require('jquery'); 其实就等价于 require('./scripts/jquery.min.js'); 。通过别名的使用在本例中可以减少几乎一半的时间。
我们把需要的jquery打包了,但是现在前台页面想要直接用还是不可以的,需要我们把jquery暴露出来。
你可能在全局中使用了一个压缩版本的 jquery,为了修复你可以安装这个暴露全局加载器
npm install expose-loader --save-dev
然后像下面这样修改entry.js:
require('expose?$!jquery');
把$作为别名为jquery的变量暴露到全局上下文中。
现在我们在页面就可以使用$,例如:
$('h1').text();
来源:oschina
链接:https://my.oschina.net/u/2491705/blog/774807