写在前面

webpack 的 loader 和 plugin 太多了,在项目开发过程中可以根据功能需要去 webpack 官网搜索配置。

这里只介绍自己目前用到的,以后会继续补充。

1. 引入 scss

scss 是 sass 语言的另个语法,详细可见 Sass简介

引入 scss 的方法详细见官网 sass-loadergithub

sass-loader 的内部实现肯定依赖 sass ,所以安装 sass-loader 的同时也要安装 sass

安装 sass 和 sass-loader

  1. yarn add sass-loader sass --dev // 使用默认配置就行,当前默认配置就是 dart-sass
  2. yarn add sass-loader dart-sass --dev // 使用 dart-sass 时要有一些配置
  3. yarn add sass-loader node-sass --dev //不推荐使用 node-sass,会有一些问题

使用 sass 的配置信息:

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.s[ac]ss$/i,
  6. use: [
  7. 'style-loader',
  8. 'css-loader',
  9. 'sass-loader',
  10. ],
  11. },
  12. ],
  13. },
  14. };

使用 dart-sass 的配置信息,node-sass 同理

  1. module: {
  2. rules: [
  3. {
  4. test: /\.s[ac]ss$/i,
  5. use: [
  6. 'style-loader',
  7. 'css-loader',
  8. {
  9. loader: 'sass-loader',
  10. options: {
  11. implementation: require('dart-sass'),
  12. },
  13. },
  14. ],
  15. },
  16. ],

2. 引入 less

less-loader 的内部实现肯定依赖 less ,所以安装 less-loader 的同时也要安装 less

安装 less 和 less-loader

  1. yarn add less less-loader --dev

配置信息

  1. module: {
  2. rules: [
  3. {
  4. test: /\.less$/,
  5. loader: ['style-loader', 'css-loader', 'less-loader'],
  6. }
  7. ],
  8. }

3. 引入 stylus

安装 stylus 和 stylus-loader

  1. yarn add stylus stylus-loader --dev

配置信息

  1. module: {
  2. rules: [
  3. {
  4. test: /\.styl$/,
  5. loader: ['style-loader', 'css-loader', 'stylus-loader'],
  6. }
  7. ],
  8. }

通过上述三种 css 语言的变种的引入可以看出,都是需要先将其转化为 css,再由 css 转化为 <style> 或抽离成 css 文件。

4. 引入图片

由于我们使用 webpack 开发项目时,代码编辑目录和运行代码目录是两个完全独立的文件夹,因此,在使用图片资源时,不能直接使用相对路径,会出错。需要对图片进行转化,得到其在打包后的真正相对路径和带有 hash 的文件名。

file-loader 的作用就是将文件变成文件路径。

安装 file-loader

  1. yarn add file-loader --dev

配置信息

  1. module: {
  2. rules: [
  3. {
  4. test: /\.(png|jpe?g|gif)$/i,
  5. use: ['file-loader'],
  6. },
  7. ]
  8. }

引入 svg

svg 图片与 jep/png 等普通的图片资源存在一定的差别。当你下载一个 svg 图片在编辑器中打开看的时候会发现其是一段 xml 语言的代码。并且 svg 图片是矢量图,怎么放大都不会失真。jep/png等是位图,放大会失真。

因此 svg 图片在前端工程中有着不同于普通图片的使用方式。

直接使用 svg 代码

在工程中直接使用 svg 标签嵌入 svg 图片。

  1. <svg version="1.1"
  2. baseProfile="full"
  3. width="300" height="200"
  4. xmlns="http://www.w3.org/2000/svg">
  5. <rect width="100%" height="100%" fill="red" />
  6. <circle cx="150" cy="100" r="80" fill="green" />
  7. <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
  8. </svg>

把 svg 当普通图片使用

使用 file-loader 或者 url-loader 加载 svg 图片,将 svg 图片当作普通图片使用 img 标签使用。

制作 svg 雪碧图

还有一种使用 svg 图片的方法是使用 svg + use 的方式,像 iconfont 里使用 svg 图标的方式一样。示例如下:

  1. <svg class="icon" aria-hidden="true">
  2. <use xlink:href="#icon-xxx"></use>
  3. </svg>

这种使用方式的原理是将全部的 svg 图片放到一个 svg 中,以 symbol 标签的方式进行定位,在使用的时候直接传递 symbol 标签对应的 id 名字即可渲染对应的图标。

这种方式用到的相关 loader 为 svg-sprite-loadersvgo-loader

webpack 的配置如下:

  1. module: {
  2. rules: [
  3. {
  4. test: /\.svg$/,
  5. use: [
  6. {
  7. loader: "svg-sprite-loader",
  8. options: {
  9. symbolId: "icon-[name]" // 指定 symbol 的 id,在使用时的名字
  10. }
  11. }
  12. ]
  13. }
  14. ]
  15. }

使用 svg-sprite-loader 后我们再 import svg 图片的时候,就不再像 file-loader 一样是一个图片路径了,而是一个 BrowserSpriteSymbol 对象。

通常情况下,我们下载下来的 svg 图片自带颜色,外部无法再给其指定颜色,这是因为其 svg 标签里的 path 带有 fill 属性,写死了颜色。如果我们想通过外部改变 svg 图片的颜色,需要将 fill 字段去掉后使用 css 的 fill 属性设置颜色。

svgo-loader 可以对 svg 图片的源代码进行处理,比如删除不必要的属性,优化其大小。因此可以用 svgo-loader 来对 svg 图片统一去除 fill 属性进行去色处理。

svgo-loader 使用 svgo 工具处理 svg 图片。

  1. module: {
  2. rules: [
  3. {
  4. test: /\.svg$/,
  5. use: [
  6. {
  7. loader: "svg-sprite-loader",
  8. options: {
  9. symbolId: "icon-[name]"
  10. }
  11. },
  12. {
  13. loader: "svgo-loader",
  14. options: {
  15. plugins: [
  16. {
  17. name: "removeAttrs",
  18. params: {
  19. attrs: "fill"
  20. }
  21. }
  22. ]
  23. }
  24. }
  25. ]
  26. }
  27. ]
  28. }

这样一来,所有引入的 svg 就没有颜色了,通过添加类名,使用 css 的 fill 属性指定颜色。如下:

  1. <svg class="icon">
  2. <use xlink:href="#icon-test"></use>
  3. </svg>
  4. <style>
  5. .icon {
  6. width: 2em;
  7. height: 2em;
  8. fill: red;
  9. }
  10. </style>

如果想更进一步封装组件和批量加载,详见 封装 svg-icon 组件

6. webpack 懒加载

在 webpack 中,模块的导入导出使用的是 import 和 export。但是如果将所有的模块在一开始就全都 import 进来,会大大降级页面的加载速度。因此懒加载就是在模块需要的时候才加载出来,使用的是 import()函数。

import() 函数接收一个加载模块的路径,返回一个 Promise 对象。

lazy.js

  1. export default function () {
  2. console.log('我是懒加载')
  3. }

index.js

  1. button.onclick = ()=>{
  2. import('./lazy.js').then((module)=>{
  3. module.default()
  4. })
  5. }