Webpack学习总结
此文只是自己学习webpack的一些总结,方便自己查阅,阅读不变,非常抱歉!!
下载安装:
Win10
打开命令行工具创建文件夹:mkdir webpack-test(文件名不能叫webpack,不然会报错无法下载webpack)
进入文件夹:cd webpack-test
初始化init:npm init;(生成一个package.json文件)
下载安装webpack:npm install webpack --save-dev;(依赖注入)
尝试使用:
在webpack-test目录下新建一个hello.js文件,随便输入一些代码,如:
在命令行中输入webpack hello.js hello.boudle.js:
看到如上结果说明已经打包成功,文件目录下会生成一个hello.boudle.js文件:
Hash:Hash值;
Version:webpack版本号;
Time:打包所花费的时间;
Asset:生成的文件;
Size:文件大小;
Chunks:打包的分块;
Chunk Names:打包的块名称;
下一步,新建一个world.js文件,然后在hello.js中对其引用,webpack支持ES6、Commonjs、AMD模块语法:
输入webpack hello.js hello.boudle.js:
在hello.boudle.js中,/* 0 */,/* 1 */为模块编号,webpack将打包前文件的引用替换为webpack内置的require:
新建一个style.css文件,在hello.js中对其引用,然后再次运行打包命令:
发现css文件打包失败,提示你需要一个loader来处理这个(css)文件类型;
使用npm install css-loader style-loader --save-dev 安装处理css文件的loader,然后运行
webpack hello.js hello.boudle.js:
它还是说你需要一个loader来处理这个类型的文件,因为虽然你安装了loader,但是在文件中没有去制定要使用这个loader来处理这种类型的文件:
css-loader!就是说这个文件需要经过css-loader的处理,然后再次运行打包:
这样就完成了css文件的打包;
新建一个hello.html文件,引入打包后的文件:
修改hello.js,执行hello函数:
执行打包,浏览器中打开html文件:
在css文件中加上背景色,然后重新打包运行:
你会发现并没有生成红色背景,这时你需要使用style-loader对引入的css文件进行处理:
然后打包运行,就可以了:
你会发现浏览器中head标签中多了一个style标签,这是因为css-loader是用来处理css文件,style-loader是将css-loader处理后的文件新建一个style标签插入到html里面;
css-loader也可以在命令行中指定,命令行输入webpack --help可以看到webpack的一些参数,删除require时指定的loader ,打包时将命令改为:webpack hello.js hello.boudle.js --module-bind “css=style-loader!css-loader”,发现也可以成功,并没有报错,注意windows下只能使用双引号,不然会报错,webpack是从右往左解析,所以要先使用css-loader处理然后再交给style-loader;
加上--watch参数可以使每次文件改变的时候自动执行打包;
--progress可以看到打包过程;
--display-modules可以看到打包模块,会列出每个文件通过哪个loader处理;
--display-reasons为告诉你为什么要打包这个模块;
配置webpack
新建一个webpack-test2文件,init初始化,npm install webpack --save-dev依赖安装webpack,新建一个src文件,新建一个dist文件,根目录下创建一个html文件,引入boudle.js(打包后的文件名):
src目录下创建一个script文件夹一个style文件夹用于放置js,css文件,根目录下创建一个webpack.config.js(官网上有对config的详细说明)文件:
entry:打包入口,从哪个文件开始,假设为上述文件;
output:打包后的文件;
filename:打包后的文件名(加上路径);
output中还有一个path和一个publicPath属性:
path代表路径,publicPath为要替换的路径,如上线网址:
webpack会将path替换为publicPath:
script文件夹中新建一个main.js,写一个空函数,然后命令行输入webpack打包:
这样就打包成功了;
如果将webpack.config.js文件名修改webpack.dev.config.js(或其他),可使用命令webpack --config webpack.dev.config.js;
也可以在package.json文件中的scripts下进行配置:
然后命令行使用npm run webpack:
entry
entry接受字符串(单个文件),数组和对象三种方式;
在script目录下新建一个a.js,写一个a的空函数,然后修改config.js中的entry:
运行npm run webpack:
打包成功;
将entry改为对象方式:
运行npm run webpack:
提示多个资源打包成了相同的文件名,然后前面的被覆盖,这个时候要使用output中的占位符,[name]指entry对象中的key,[hash]打包的Hash值,[chunkhash]每一个chunk的hash值;
修改config文件:
改为chunkhash,运行:
和上面不同的是两个文件hash值不同,chunkhash可以认为是版本号,只有当文件有改变的时候hash值才会改变,下面改变a.js文件,再运行打包:
可以发现a.js打包后的文件hash值变化了;
index.html中引入的文件是boudle.js,但是我们打包后的文件名可能是不确定的,所以我们需要引入webpack的插件:html-webpack-plugin,首先还是依赖注入:npm install html-webpack-plugin --save-dev,然后引入html-webpack-plugin,在module-exports中配置plugins:
之后运行npm run webpack:
可以看到已经生成了一个html文件,并且引用了生成的文件路径:
也可以对plugin进行配置,参数为一个对象:
filename:生成后的文件名;
template:模板;
Inject:需要将标签放在html哪个位置,如head、body;
title:html中的title内容;
minify:压缩文件(removeComments删除注释,collapseWhitespace删除空格);
可以在html中通过ejs模板引擎在htmlWebpackPlugin对象中获取config.js中的配置:
Html中:
config.js中:
生成的html文件:
htmlWebpackPlugin有一个files和一个options属性,可以在ejs模板中将其遍历出来查看所有属性;
多页面打包
plugins参数为一个数组,所以可以接收多个参数,如果需要生成多个html,只需要重新调用new htmlWebpackPlugin();
新建一个b.js c.js,在entry中配置如下
在plugins中:
chunks为要引入的打包后的文件路径,参数为一个数组,excludeChunks参数接收一个数组,意思为排除数组中的文件之外其他全部引入;然后npm run webpack:
然后可以看到不同的文件通过设置chunks达到了引用不同文件的效果;
通过指定chunks的方式引用的文件都是通过src引入,如果希望将一些初始化的脚本通过inline的方式插入到页面,从而减少http请求数,可以通过plugin的compilation.assets实现将script脚本通过inline的方式插入到html:
这样main.js就插入到了html中,而a、b、c.js分别通过src引用到文件中,这里要注意,将inject参数改为false,并且main作为通用模板,所有文件中chunks里面都必须包含main,不然会报错;
Loader的使用
修改目录文件:
Src根目录下有一个app.js:
src下一个conponents文件夹,下面一个layer文件夹,里面一个layer.html,一个layer.less,一个layer.js,配置一次如下:
修改config.js:
Loader的使用有三种方式,第一种是require(‘css-loader!./a.js’),通过require的方式直接在引入文件时指定loader,第二种是使用cli,就是在npm中 “style=style-loader!css-loader”,前面也有提到过,现在主要在config.js配置文件中使用loader;
在配置文件的配置中新增一个module项,此项表示使用’babel’的loader来处理已.js结尾的文件,babel是将es6语法解析为浏览器可以读取的js语法(如果报错,请参考后面的配置方式):
首先要在命令行中安装babel,npm install babel-loader babel-core babel-preset-env webpack --save-dev,配置:
注释掉html引用,不然会报错,因为没有指定处理html文件的loader:
然后运行npm run webpack,就可以看到打包成功了;
注意你的node和npm版本必须要高于某个版本,具体哪个版本不知道,安装最新的就可以了,更新node可以在官网下载最新版本,然后安装路径和之前的路径保持一致就可以了,node中带有npm,所有安装最新的node后,npm也会是最新版本;
可以看到打包成功了,打开页面也会有console的layer函数;
虽然打包的文件很少,但是打包花费的时间还是很长,因为它会把node_modules文件一起处理,可以在rules中指定include(包含范围)和exclude(排除)使打包速度加快,再运行一次打包,可以看到时间从之前的4s多变成了0.6s:
这里exclude要用正则,不然不能正确匹配,include要加上__dirname,这里只处理src下面的文件;
exclude可以的参数可以是字符串也可以是一个数组接收多个参数,参数可以是正则、字符串或者是一个函数,这个路径必须是绝对路径,这个时候需要引用node中的path:
可以达到一样的效果;
经过尝试,include使用之前的方式会快很多,所以这里include还是使用之前的方式匹配;
CSS的处理
安装css-loader和style-loader:npm install css-loader style-loader --save-dev
根目录下新建一个css文件夹用于放置css文件,新建一个common.css文件,用于公共部分css;
在app.js中引用common.css;
配置css-loader:
注意这里要指定2个loader,一个style-loader和一个css-loader,并且style-loader在前,不然会报错,无法正常解析;
在一些css属性需要浏览器兼容的时候,可以借助postcss-loader自动为这些需要兼容的属性加上前缀,比如我们在css文件中加上一个flex属性,安装postcss-loader并配置:
npm install postcss-loader --save-dev
npm install autoprefixer --save-dev(这个是postcss的插件,用于添加前缀);
browsers为要兼容的浏览器版本,’last 5 versions’为最近的5个版本;
如果一个文件是通过@import的方式引入,这种方式就不会生成前缀,新建一个flex.css,并设置一个flex属性,然后从common.css 中@import flex.css:
可以看到这是并没有被正确的添加前缀:
新建一个postcss.config.js:
webpack.config.js配置如下:
这是通过@import引入的文件也会被正确的添加上前缀了;
less-loader
首先还是安装less-loader:npm install less-loader --save-dev
如果没有安装less,还要安装less:npm install less --save-dev
layer.js中引入layer.less,config.js中配置如下:
webpack2和1配置有点不一样,1.x可以直接使用
{
test:/\.less$/,
loader:’style-loader!css-loader!postcss-loader!less-loader’
}
注意两种配置的顺序都不能变,相当于从下往上解析,先处理less,然后postcss添加前缀,然后处理css,最后style标签插入,顺序不能变;
在使用@import时,上面箭头处可以省略css-loader中的importLoaders属性,less-loader会自动处理,不需要添加处理css时的importLoaders属性;
打包成功后再浏览器中可以看到多了一个style标签,里面就是less文件解析出来的内容;
@import less文件时,不加importLoaders,也会正确的加上前缀;
sass同理,test属性值为/\.scss$/,因为sass是scss文件,其他配置和less相同;
处理模板文件
安装loader:npm install html-loader --save-dev
修改文件:
Index.html中添加一个div,id为app:
layer.js:
app.js:
layer.html:
config.js:
然后运行npm run webpack,页面可以正常显示了;
使用模板引擎
ejs为例,修改layer.html为layer.ejs,修改代码:
安装ejs-loader:npm install ejs-loader --save-dev
config.js,这里不一定要叫ejs,也可以取见名知意的tpl代表template,因为可以是其他模板引擎:
app.js中:
在tpl中传入需要的参数,运行打包命令,刷新页面,可以看到页面被正确的解析了;
图片的处理
在src目录下新建一个assets文件夹,放入一张图片,在layer.less中的div下使用相对路径设置背景图片,安装file-loader,配置config.js:
运行npm run webpack:
可以看到图片已经被打包了;
在index.html中添加一张图片,打包,可以看到图片也可以被正确的解析:
然后再.ejs文件中同样添加一张图片,打包,刷新页面;
可以看到图片没有被正确的显示,并且控制台报错没有找到文件,可以看到css和html中的图片路径是经过webpack处理替换掉了,但是模板中的图片路径没有被正确的替换导致找不到文件;
这是可以使用传参的方式,${}为es6的模板字符串传参方式,可以在{}中写简单的逻辑运算:
重新打包,刷新页面,可以看到图片可以正常显示,并且路径也被替换;
file-loader中也有一些参数可以配置,比如:
使用以上配置,图片会被保存在dist文件夹下新建的一个assets文件目录下,[name]为文件名,[hash:5]表示hash值得前5位,[ext]表示文件的后缀名:
url-loader
url-loader有一个limit配置项,表示当你的文件或图片大于指定大小的时候,它会交给file-loader去处理,如果文件或图片小于这个值,它会将其转换为base64的格式:
npm安装url-loader,并配置,先将前面的file-loader修改,并配置limit属性为300k,因为我前面图片的大小为290k多,打包并运行:
前面为之前打包后文件大小,可以看到打包后文件明显变大了很多,是因为文件类型发生了改变,图片也被打包到了html ejs文件中,页面上可以看到鼠标移入图片路径时会显示一段base64编码,但是页面效果没有任何变化;
图片压缩
安装image-webpack-loader,配置:
运行打包:
可以看到文件明显变小了,我们换回file-loader:
可以看到图片从之前的296k被压缩到只有103k;
image-webpack-loader对每一种图片格式都有具体的参数进行优化,具体可以参考官网。
最后附一张package.json和config.js图: