webpack简明使用教程
试想一下,你有entry.js和add.js文件,然后需要在entry.js中使用add.js中的功能,有人可能会说,直接把add.js中的代码复制到entry.js中不就OK了吗,确实,这样可以达到效果,但是如果还有anotherEntry.js文件需要add.js中的功能呢,明显这样做的结果是导致了大量的代码重复,违背了前端模块化的思想,有人又说了,可以用AMD规范(RequireJs),这个是一个好的解决方法,但是过于复杂,于是webpack运应而生了,webpack,是一种模块打包工具,它可以把多个模块打包成一个完整的模块,因此,webpack也是前端模块化的一种解决方案,你只需要提供一个入口文件,webpack自动帮你把这个入口文件需要的各种依赖包含进来,并生成一个输出文件,我们在html页面中使用的就是这个文件,webpack能处理的模块类型也更为广泛,js,css,sass,es6,图片等等。总之,webpack能把模块1,模块2,模块3...模块n打包成一个js模块(也就是一个js文件),其中模块1可以是一个js文件,模块2可以是一个css文件,模块3可以是一副图片等等,请看下图:
下面全面介绍一下webpack的使用:
一、准备阶段-----安装
我为本文写了一个示例库,webpack-demos,请先安装这个库:
git clone mbjgithub (汪汪) · GitHub
如果没有安装git,请先安装git,Git - Downloads
如果没有全局安装webpack,为了能使用webpack命令,请先全局安装webpack,npm install webpack -g,如果这样安装不了,或者很长时间也没有安装好,请用cnpm install webpack -g,这样一分钟内就可以安装好,如果不知道cnpm是什么,或者在安装cnpm的过程中出现了问题,请参考我的这篇文章,安装webpack缓慢的解决方法
然后进入webpack-demos目录。
二、webpack的使用
1、demo01---------webpack最简单使用
首先进入demo01目录,输入npm install,这样npm会自动读取package.json中内容,给我们安装项目的依赖包,然后执行命令webpack,这样你会发现在public下面多了一个bundle.js文件,在浏览器中打开index.html可以看到效果,index.html中引用的就是webpack打包生成的bundle.js文件。
下面我们来重新走一遍这个流程,自己亲手试试:
(1)demo01项目,切换到demo01目录,然后执行npm init 命令,执行这个命令会让你回答一些问题,不过这些问题你现在全部按enter就行了,然后你会发现demo01中多了一个package.json文件,这个文件时npm标准说明文件,npm可以根据这个文件下载项目的依赖包。然后执行cnpm install --save-dev webpack,在该项目中安装webpack。至于为什么要加--save-dev参数请看安装webpack缓慢的解决方法
(2)新建app和public文件夹,app中放置我们写的模块,public放置webpack打包生成的模块,然后新建webpack.config.js文件,运行webpack命令时会自动读取该文件,然后在app文件夹中新建entry.js和greet.js,在public中新建index.html。
greet.js中的代码
function greet(){
var divEle=document.createElement("div");
divEle.innerHTML="hello,webpack";
return divEle;
}
module.exports=greet;
entry.js中的代码
var greet=require("./greet.js");
document.getElementById("container").appendChild(greet());
index.html中的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" rel="stylesheet" src="./bundle.js"></script>
</body>
</html>
webpack.config.js中的代码
module.exports={
entry:__dirname+"/app/entry.js", //入口文件
output:{
path:__dirname+"/public", //输出文件的存放位置
filename:"bundle.js" //输出文件的名称
}
}
entry指明的是webpack的入口文件,webpack会把这个文件包含的所有模块打包到一个模块中,output指明了打包完成后,这个输出模块的存放位置和文件名。
(3)执行webpack命令,在public下会发现生成了一个bundle.js文件,你可以运行一下index.html,然后查看一下bundle.js。是不是很激动,webpack实现了前端的模块化,你已经成功的将复杂的js拆分为简单的js文件,如果不使用webpack的话,恐怕greet.js中的代码要写在entry.js中。
2、demo02--------webpack最重要的功能,loader的使用
Loaders是webpack中最让人激动人心的功能之一了。通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理,比如说分析JSON文件并把它转换为JavaScript文件,或者说把下一代的JS文件(ES6,ES7)转换为现代浏览器可以识别的JS文件。或者说对React的开发而言,合适的Loaders可以把React的JSX文件转换为JS文件。
Loaders需要单独安装并且需要在webpack.config.js下的modules关键字下进行配置,Loaders的配置选项包括以下几方面:
进入demo02文件夹,安装依赖,cnpm install --save-dev webpack,然后看webpack.config.js中的代码:
module.exports={
entry:__dirname+"/app/entry.js", //入口文件
output:{
path:__dirname+"/public", //输出文件的存放位置
filename:"bundle.js" //输出文件的名称
},
module:{
loaders:[
{
test:/\.json$/, //正则表达式,告诉loader应该加载以.json结尾的文件
loader:"json"
}
]
}
}
和demo01的webpack.config.js相比多了一个module配置,loaders是数组,表明可以使用多个loader,上面的loader是一个json-loader,可以用来处理以.json结尾的文件,通过这个json-loader,才使得入口文件可以像require js文件一样,require json文件。不过首先得安装json-loader,输入cnpm install -save-dev json-loader即可安装,
下面重新梳理一下整个流程,自己在走一遍:
(1)新建demo02文件夹,输入npm init命令,生成package.json文件,输入
cnpm install --save-dev webpack,安装webpack依赖,由于我们要用到json-loader,因此输入cnpm install --save-dev json-loader。
(2)在demo02下,新建app和public文件夹,新建webpack.config.js,在app下,新建config.json,entry.js,greet.js文件,在public下新建index.html文件,
config.json中代码
{
"content":"hello,webpack"
}
greet.js中代码
var config=require("./config.json");
function greet(){
var divEle=document.createElement("div");
// divEle.innerHTML="hello,webpack";
divEle.innerHTML=config.content;
return divEle;
}
module.exports=greet;
entry.js中代码
var greet=require("./greet.js");
document.getElementById("container").appendChild(greet());
index.html中代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" rel="stylesheet" src="./bundle.js"></script>
</body>
</html>
webpack.config.js中代码
module.exports={
entry:__dirname+"/app/entry.js", //入口文件
output:{
path:__dirname+"/public", //输出文件的存放位置
filename:"bundle.js" //输出文件的名称
},
module:{
loaders:[
{
test:/\.json$/, //正则表达式,告诉loader应该加载以.json结尾的文件
loader:"json"
}
]
}
}
(3)运行webpack命令,可以看到public文件夹下多了一个bundle.js文件。这说明webpack成功把config.js,greet.js,entry.js打包成了bundle.js ,
3、demo03--------webpack的style-loader和css-loader的使用
style-loder和css-loader得一起使用才能把css文件也打包到bundle.js文件中,和json-loader差不多,只不过style-loader和css-loader处理的是css文件罢了。下面我i就不具体演示了,详情请看demo03,你可以直接cnpm install,这样会下载好整个项目的依赖包。然后需要注意一点的是用css-loader和style-loader的时候,有时候会报错,报错的最可能的原因就是npm或者cnpm在下载css-loader和style-loader的时候缺胳膊少腿,少下了一下模块,解决的方法就是先卸载css-loader和style-loader然后在重新下载,或者直接重新下载缺少的模块。
4、demo04-----------webpack插件的使用
插件不同与loader,loader时作用于一类文件,而插件是作用于整个项目,比如BannerPlugin,这个插件的功能就是给输出的bundle.js加上版权声明,CommonsChunkPlugin插件是提取依赖的公共部分,全部插件,请看webpack list of plugins
请看demo04的webpack.config.js代码
var webpack=require("webpack");
module.exports={
entry:__dirname+"/app/entry.js", //入口文件
output:{
path:__dirname+"/public", //输出文件的存放位置
filename:"bundle.js" //输出文件的名称
},
module:{
loaders:[
{
test:/\.json$/, //正则表达式,告诉loader应该加载以.json结尾的文件
loader:"json"
},
{
test:/\.css$/,
loader:"style!css" //对css的处理需要style和css两个loader来处理,!用于连接两个loader
}
]
},
plugins:[
new webpack.BannerPlugin("CopyRight wangwang 2016-10") //这个插件的作用是给output的文件添加版权声明
]
}
你可以在bundle.js中看到效果。这里我还做了一点改动,请看package.json中代码
{
"name": "demo01",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack"
},
"author": "wangwang",
"license": "ISC",
"devDependencies": {
"css-loader": "^0.25.0",
"json-loader": "^0.5.4",
"style-loader": "^0.13.1",
"webpack": "^1.13.3"
}
}
注意上面的script属性,我添加了"start":"webpack"这里的意思就是让npm start命令等价于webpack命令,这样,只需要输入npm start就相当于执行webpack命令了。
5、demo05--------webpack多入口文件和CommonsChunkPlugin插件
请看webpack.config.js文件代码
var webpack=require("webpack");
var path=require("path");
module.exports={
entry:{
pageA:__dirname+"/app/pageA.js", //入口文件pageA
pageB:__dirname+"/app/pageB.js" //入口文件pageB
},
output:{
path:path.join(__dirname,"public"), //输出文件目录
filename:"[name].bundle.js", //[name]引用entry的pageA或者pageB属性
chunkFilename:"[id].chunk.js"
},
plugins:[
new webpack.optimize.CommonsChunkPlugin({
filename:"commons.js", //这个插件用于提取多个入口文件共享的模块,并输出到commons.js中,实现模块复用
name:"commons"
}),
new webpack.optimize.UglifyJsPlugin()
]
}
demo05的效果时在public下会生成pageA.bundle.js,pageB.bundle.js和commons.js文件,commons.js文件中包含入口文件pageA.js和pageB.js都使用的模块,这是CommonsChunkPlugin插件的功劳。
三、总结
webpack确实一个很好用的模块化打包工具,小项目其实没有什么感觉,但是到了大项目,webpack的优势就越来越明显了。由于篇幅限制,webpack的很多功能都没有一一列出,比如,压缩,分离css,js等等,想要继续深入了解的请看webpack官网
四、gulp使用教程(看到别人写的已经很好了,就不自己写了)