Webpack

117 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

Webpack使用原因:

文件体积大,导致网页打开速度缓慢,通过webpack打包缩减体积从而达到提高网页打开速度的效果。

介绍:

webpack本身是, node的一个第三方模块包, 用于打包代码

其中功能:

  • less/sass -> css
  • ES6/7/8 -> ES5
  • html/css/js -> 压缩合并

前置工作

(1)安装yarn(类似npm但是比它快)

npm install --global yarn

(2)测试

yarn -version

(3)初始化

yarn init (这里可以只写项目名)

(4)安装webpack和webpack工具包

yarn add webpack webpack-cli -D

(5)配置packjosn.js,添加

scripts: { "build": "webpack" }

打包

  1. 在src下创建index.js
  2. 在src下创建要编写的功能模块包
  3. 在文件夹下打开终端
  4. 输入“yarn build”
  5. webpack生成dist文件夹

image.png

webpack入口与出口

  1. 配置webpack.config.js

image.png

webpack自动生成html文件

  1. webpack.docschina.org/plugins/htm…
  2. yarn add html-webpack-plugin -D
  3. 配置webpack.config.js
// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // ...省略其他代码
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html' // 以此为基准生成打包后html文件
        })
    ]
}

_加载器 - 处理css文件问题

webpack默认只认识 js 文件和 json文件

  1. 安装依赖

    yarn add style-loader css-loader -D
    
  2. webpack.config.js 配置

    const HtmlWebpackPlugin = require('html-webpack-plugin'
    module.exports = {
        // ...其他代码
        module: { 
            rules: [ // loader的规则
              {
                test: /.css$/, // 匹配所有的css文件
                // use数组里从右向左运行
                // 先用 css-loader 让webpack能够识别 css 文件的内容并打包
                // 再用 style-loader 将样式, 把css插入到dom中
                use: [ "style-loader", "css-loader"]
              }
            ]
        }
    }
    
  3. 新建src/css/li.css - 去掉li默认样式

    ul, li{
        list-style: none;
    }
    
  4. 引入到main.js (因为这里是入口需要产生关系, 才会被webpack找到打包起来)

    import "./css/index.css"
    
  5. 运行打包后index.html观察效果和css引入情况

总结: 万物皆模块, 引到入口, 才会被webpack打包, css打包进js中, 然后被嵌入在style标签插入dom上

引入 less

  1. 下载 yarn add less less-loader -D
  2. 配置

image.png 要单独写 3. 引入到main.js (因为这里是入口需要产生关系, 才会被webpack找到打包起来)

```
import "./css/index.css"
```

4. 运行打包后index.html观察效果和css引入情况

处理图片文件

webpack5版本:

(1) webpack.config.js 配置

{
    test: /\.(png|jpg|gif|jpeg)$/i,
    type: 'asset'
}

(2)给css加

body{
    background: url(../assets/logo_small.png) no-repeat center;
}

(3)// 引入图片-使用(main.js)

import imgUrl from './assets/1.gif'
const theImg = document.createElement("img")
theImg.src = imgUrl
document.body.appendChild(theImg)

(4)yarn build

(5)可以看见dist下面生成一张图片,而另一个直接被存在js内

image.png

原因是:

小于8kb图片会被转成base64存在dist下的js文件中
大于8kb不转直接打包在dist下存成图片
图片转成 base64 字符串
  • 好处就是浏览器不用发请求了,直接可以读取
  • 坏处就是如果图片太大,再转base64就会让图片的体积增大 30% 左右

webpack4及以前的版本

  1. 下载依赖包
 yarn add url-loader file-loader -D
  1. webpack.config.js 配置

    {
      test: /.(png|jpg|gif|jpeg)$/i,
      use: [
        {
          loader: 'url-loader', // 匹配文件, 尝试转base64字符串打包到js中
          // 配置limit, 超过8k, 不转, file-loader复制, 随机名, 输出文件
          options: {
            limit: 8 * 1024,
          },
        },
      ],
    }
    

处理字体文件

webpack5使用这个配置

{ // webpack5默认内部不认识这些文件, 所以当做静态资源直接输出即可
    test: /.(eot|svg|ttf|woff|woff2)$/,
    type: 'asset/resource',
    generator: {
        filename: 'font/[name].[hash:6][ext]'
    }
}

webpack4及以前使用下面的配置

 { // 处理字体图标的解析
     test: /.(eot|svg|ttf|woff|woff2)$/,
         use: [
             {
                 loader: 'url-loader',
                 options: {
                     limit: 2 * 1024,
                     // 配置输出的文件名
                     name: '[name].[ext]',
                     // 配置输出的文件目录
                     outputPath: "fonts/"
                 }
             }
         ]
 }

2. src/assets/ - 放入字体库fonts文件夹

  1. 在main.js引入iconfont.css

    // 引入字体图标文件
    import './assets/fonts/iconfont.css'
    
  2. 在public/index.html使用字体图标样式

    <i class="iconfont icon-weixin"></i>
    
  3. 执行打包命令-观察打包后网页效果

image.png

总结: url-loader和file-loader 可以打包静态资源文件

处理高版本js语法

目标: 让webpack对高版本 的js代码, 降级处理后打包

写代码演示: 高版本的js代码(箭头函数), 打包后, 直接原封不动打入了js文件中, 遇到一些低版本的浏览器就会报错

原因: webpack 默认仅内置了 模块化的 兼容性处理 import export

babel 的介绍 => 用于处理高版本 js语法 的兼容性 babel官网

解决: 让webpack配合babel-loader 对js语法做处理

babel-loader文档

  1. 安装包

    yarn add -D babel-loader @babel/core @babel/preset-env
    
  2. 配置规则

    module: {
      rules: [
        {
            test: /.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'] // 预设:转码规则(用bable开发环境本来预设的)
                }
            }
        }
      ]
    }
    
  3. 在main.js中使用箭头函数(高版本js)

    // 高级语法
    const fn = () => {
      console.log("你好babel");
    }
    console.log(fn) // 这里必须打印不能调用/不使用, 不然webpack会精简成一句打印不要函数了/不会编译未使用的代码
    // 没有babel集成时, 原样直接打包进lib/bundle.js
    // 有babel集成时, 会翻译成普通函数打包进lib/bundle.js
    
  4. 打包后观察dist/bundle.js - 被转成成普通函数使用了 - 这就是babel降级翻译的功能

image.png

总结: babel-loader 可以让webpack 对高版本js语法做降级处理后打包

webpack 开发服务器

4.0_webpack开发服务器-为何学?

文档地址: webpack.docschina.org/configurati…

抛出问题: 每次修改代码, 都需要重新 yarn build 打包, 才能看到最新的效果, 实际工作中, 打包 yarn build 非常费时 (30s - 60s) 之间

为什么费时?

  1. 构建依赖
  2. 磁盘读取对应的文件到内存, 才能加载
  3. 用对应的 loader 进行处理
  4. 将处理完的内容, 输出到磁盘指定目录

解决问题: 起一个开发服务器, 在电脑内存中打包, 缓存一些已经打包过的内容, 只重新打包修改的文件, 最终运行加载在内存中给浏览器使用

webpack-dev-server自动刷新==

目标: 启动本地服务, 可实时更新修改的代码, 打包变化代码到内存中, 然后直接提供端口和网页访问

  1. 下载包

    yarn add webpack-dev-server -D
    
  2. 配置自定义命令

    scripts: {
        "build": "webpack",
        "serve": "webpack serve"
    }
    
  3. 运行命令-启动webpack开发服务器

    yarn serve
    #或者 npm run serve
    

总结: 以后改了src下的资源代码, 就会直接更新到内存打包, 然后反馈到浏览器上了

webpack-dev-server配置

  1. 在webpack.config.js中添加服务器配置

    更多配置参考这里: webpack.docschina.org/configurati…

    module.exports = {
        // ...其他配置
        devServer: {
          port: 3000 // 端口号
        }
    }
    

警告

image.png

解决webpack.config.js配置文件:加 mode: 'development',

image.png