1. Webpack的loader

1.1 问题引入

之前的我的项目中咱们打包的对象都是JS文件,那假如咱们须要import一个图片应该怎么做呢,如果依然应用之前的形式进行打包就会报错:

Module parse failed:Unpexpected character ...

很显著webpack不能辨认图片文件,这里就须要借助loader来通知webpack如何打包图片文件了

1.2 loader是什么

Loader就是一种打包计划,对于某一种类型文件他晓得如何打包,帮忙webpack实现打包工作。

如果你写过vue,必定写过相似的语句

import Header from './header.vue'

1.3 配置文件批改以引入loader

咱们须要给之前的webpack配置文件中退出一个module字段,并新增一个rules数组来减少规定:

 const path = required('path')  module.exports = {     mode:'development',     entry:{         main:'./src/index.js'     },     module:{         rules:[{             test:/\.jpg$/,             use:{                 loader:'file-loader             }         }]     },     output:{...} }

上述其实就是制订了一个规定,通知webpack遇到以.jpg结尾的文件时候应用file-loader去解决。

这里别忘了先把file-loader装置到我的项目中:

npm install file-loader -D

这样从新npm run bundle就能够看到dist目录上面多出了一个图片文件。

file-loader底层做了这些:当他发现你这边图片文件要打包,首先会把图片挪动到dist目录上面去 并改一个名字(名字能够本人定义),而后会失去图片绝对于dist目录的一个名称,而后返回给引入模块的变量之中。

file-loader实践上能够解决任何动态资源,例如excel,jpg,png,他实际上就是挪动地位而后把新地址返回给变量,只有你的test字段写好就能够。
借助这一点咱们尝试把动态资源放到网页上:

import avatar from './avatar.jpg'const img = new Image();img.src = avatar;....root.append(img)

1.4 loader打包动态资源-图片

这里咱们持续扩大之前的内容,理解如何对loader进行一些自定义配置和应用。

放弃图片原名

默认应用file-loader会更改图片文件名称,然而咱们心愿放弃原名该怎么做呢?

这里能够通过对该loader进行配置解决:

...module:{    rules:[{        test:/\.jpg$/,        use:{            loader:'file-loader',            options:{                name:'[name].[ext]' // 记得包单引号            }        }    }]}...

这里的[name],[ext]是loader提供的占位符,具体value能够参考对应loader的文档,上述name和ext别离示意解决文件的名称和后缀

打包其余类型图片

大家应该联想到解决办法了,间接批改test字段匹配到更多的图片类型即可:

test:/\.(jpg|png|gif)$/

心愿图片资源打包后寄存在一个独自目录

这里能够再增加一个outputPath配置项:

use:{    loader:'file-loader',    options:{        name:...        outputPath:'images/'    }}

url-loader与file-loader区别

这里你可能会在其余webpack材料外面看到应用url-loader来对图片进行打包。

这里目前来说url-loader是能够代替file-loader来打包图片文件。

区别在于url-loader是将图片转换为base64寄存在bundle.js文件中,而非放到dist目录下。

file-loader的特点:

  • 能够指定要复制和搁置资源文件的地位,以及如何应用版本哈希命名以取得更好的缓存。
  • 你能够就近治理图片文件,能够应用相对路径而不必放心部署时 URL 的问题。
  • 应用正确的配置,webpack 将会在打包输入中主动重写文件门路为正确的 URL。

url-loader的特点:

  • 容许你有条件地将文件转换为内联的 base-64 URL (当文件小于给定的阈值),这会缩小小文件的 HTTP 申请数。
  • 如果文件大于该阈值,会主动的交给 file-loader 解决。

最佳实际

目前的最佳工夫就是应用url-loader将一些几KB的小图片打包到JS文件中,而大图片挪动到dist目录下,保障bundle.js尽快加载实现。

这里你须要配置的就是一个阈值,保障不同区间应用不同策略:

use:{    loader:'url-loader',    options:{        ...        limit:2048    }}

上述示意小于2KB的会打包到bundle,否则就利用file-loader挪动到dist目录

1.5 loader打包动态资源-款式

我的项目中通常都会有css文件负责管理款式,间接webpack打包同样无奈解析,须要利用loader来解决。

应用style-loader与css-loader

这里咱们针对css文件新增一个rule并应用对应loader来解析

module:{    rules:[{...},{        test:/\.css$/,        use:['style-loader','css-loader']    }]}

而后npm装置一下之后浏览器就能够失常显示了。

接着咱们阐明一下这两个loader的作用。

css-loader会帮忙咱们剖析多个css文件之间的关系,而后把多个css文件合并成一个css。

style-loader会将上述合并后的css文件挂载在文件的header下面:

<head>    ...    <style>.avatar{        width:150px;    }    </style>    ...</head>

所以在应用css-loader时候须要配合style-loader来应用才行

款式中前缀的补足

咱们能够应用postcss-loader来补足款式中诸如webkit这种前缀,默认打包是没有的:

transform: webkit-translate(100px,100px)

这个loader还要求咱们在目录下创立一个postcss.config.js文件,这里对其进行一些配置:

//postcss.config.jsmodule.exports = {    plugins:[        require('autoprefixer')    ]        //应用了一些插件}

须要执行npm install autoprefixer -D来装置插件。而后从新进行一次打包

scss的解决

这里咱们能够先写一个有scss非凡语法的文件:

body{    .avatar{        ...    }}

这里间接批改test匹配规定也是没用的,最终会发现页面挂在的还是scss语法的style,没有进行解析:

<style>    body{        .avatar{            ...        }    }</style>

这里还须要借助sass-loader来解决,这里还须要装置node-sass模块来进行解析(这部分官网文档有阐明):

npm install sass-loader node-sass -D

less的解决

less须要应用less-loader,具体应用形式和上述相似

1.6 css-loader的进阶配置

这里持续扩大讲一下css-loader

importLoaders

该配置参数用于css中的一些间接援用的状况:

{    test:/\.scss$/,    use:[        'style-loader',        {            loader:'css-loader',            options:{                importLoaders:2            }        },        'sass-loader',        'postcss-loader'    ]}

咱们在一个index.scss文件外面引入一个新的scss文件:

// index.scss@import './avatar.scss'...

这个时候其实是index.js援用了index.scss,间接援用了avatar.scss,这个时候你引入的scss就有可能不会应用上面的postcss-loader和sass-loader了,如果你心愿间接援用的也实用这些loaders,就须要这个配置项,importLoaders:2意味着无论间接援用还是间接援用都会从下到上再应用2个loader!

CSS模块化

上述配置的CSS其实是全局共享的,这样很容易导致款式抵触,咱们能够配置来保障CSS只在import引入的JS文件中起作用:

{    test:/\.scss$/,    use:[        'style-loader',        {            loader:'css-loader',            options:{                importLoaders:2,                modules:true            }        },        'sass-loader',        'postcss-loader'    ]}

1.7 loader打包动态资源-字体

这里有时候咱们心愿我的项目能展现一些第三方字体,就须要引入字体文件,基于上述打包图片和款式的思路,咱们其实间接借助file-loader就行了:

{    test:/\.(eot|ttf|svg)$/,    use:{        loader:'file-loader'    }}

1.8 loader的程序

module:{    rules:[{...},{        test:/\.css$/,        use:['style-loader','css-loader','sass-loader']    }]}

留神webpack外面use的loader是有先后顺序的,从下倒上,从右到左,例如下面的例子当中咱们是先执行sass-loader,把scss转成css,而后css-loader打包为一个css,最初style-loader进行挂载

2.Webpack的plugin

loader次要是解析不同类型的文件,而plugin则是提供一些额定的性能。

其实plugin能够在webpack运行到某个时刻的时候帮你主动做一些事件,有些相似React或vue生命周期函数的概念~

官网举荐的webpack插件有几十个,还有很多第三方插件也有很多性能,没必要一个个学,当咱们想实现一些性能能够先搜寻,找找有没有不便的插件或者配置

2.1 HtmlWebpackPlugin介绍

这里咱们心愿解决一个理论问题,之前咱们的dist目录下的HTML文件其实都是手动拷贝过来的,有没有工具能主动实现这个。

这里就能够借助html-webpack-plugin,首先npm install一下:

npm install html-webpack-plugin -D

接着咱们在配置文件中引入plugin:

module.exports = {    mode:'development',    entry:{...},    module:{        rules:[...]    },    plugins:[new HtmlWebpackPlugin()],    output:{...}}

接着咱们从新打包,该插件会在打包完结之后主动生成一个html文件,并主动蕴含对应的JS文件。

然而咱们会发现界面下面啥也没有,这是因为咱们之前的代码逻辑是找到id为root的DOM节点,而后插入一个div节点,然而打包生成的没有这个root。

配置plugin

这里咱们能够通过编写一个template文件,来用作插件主动生成的HTML文件的模板:

...<body>    <div id='root'></div></body>

而后咱们配置:

plugins:[new HtmlWebpackPlugin({    template:'src/index.html'})]

接着从新打包就会生成蕴含root节点的的index.html

2.2 CleanWebpackPlugin介绍

有时候咱们批改了一下output的文件名,然而打包之后咱们发现有新的dist.js文件了,然而bundle.js文件还在,没有删除,咱们心愿可能把dist目录删除而后再执行打包工作,这时候就能够用这个插件。

留神这个插件不是官网举荐插件,官网搜不到,这里间接装置:

npm install --save-dev clean-webpack-plugin

而后增加到plugins数组:

plugins:[    new HtmlWebpackPlugin({...}),    new CleanWebpackPlugin(['dist'])]

参数是要删除的目录名