webpack打包工具

1,270 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

webpack是什么?

概念

webpack是一个静态模块打包工具

作用

分析压缩打包代码

功能

  • 提供友好的前端模块化开发支持
  • 代码压缩混淆
  • 处理浏览器端JavaScript的兼容性
  • 性能优化

webpack包的下载

软件

webpack依赖node环境

步骤

1、初始化根目录文件夹

npm  init -y    //初始化后会出现backage.json文件

2、下载webpack包

npm i webpack@版本号 webpack-cli@版本号 -D (全局模块,也就是开发依赖的包)

3、在package.json中, 配置scripts(自定义命令)

scripts: {
    "build": "webpack"   //运行webpack命令  ——》  npm run  build
}

运行webpack命令后,会将入口文件进行压缩打包

webpack基础使用

当webpack的包下载完,并且webpack的命令设置完成后

就可以进行简单的文件打包了

步骤

1、新建src/add/add.js - 定义求和函数导出

export const addFn = (a, b) => a + b

2、新建src/index.js导入使用

// index.js为webpack打包的入口文件
import { addFn } from './add/add'
console.log(addFn(5, 2));

3、运行打包命令

npm run build

效果

  1. src并列处, 生成dist目录和main.js文件
  2. 查看main.js文件, 是打包压缩后的代码
(()=>{"use strict";console.log(7)})();

webpack-插件自动生成html文件

插件html-webpack-plugin,自动生成html文件,自动引入打包后的文件(不安装插件那就必须手动复制html文件到dist文件下,和手动引入打包后的文件)

步骤

1、下载插件

npm i html-webpack-plugin@5.3.1  -D

2、webpack.config.js配置

// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin') 
​
module.exports = {
    // ...省略其他代码
    plugins: [
        new HtmlWebpackPlugin({
            // 以此为基准生成打包后html文件
            template: './public/index.html' 
        })
    ]
}

3、重新打包后观察dist下

  • 自动生成html文件
  • 自动引入打包后js文件

webpack-loader加载器

因为webpack默认只识别js文件,只能打包js类型的文件,所以对于一下几种类型的打包,必须借助加载器

处理css文件问题

1、引入到入口文件中

import "./css/index.css"

2、下载包

yarn add css-loader@5.2.1 style-loader@2.0.0  -D

3、webpack.config.js 配置

module.exports = {
    // ...其他代码
    module: { // 如何处理项目中不同模块文件
        rules: [ // 一个对象表示一个规则
          {
            test: /.css$/i, // 匹配所有的css文件
            // use数组里从右向左运行
            // 先用 css-loader 让webpack能够识别 css 文件的内容并打包
            // 再用 style-loader 将样式, 把css插入到dom中
            use: [ "style-loader", "css-loader"]
          }
        ]
    }
}

4、效果

  1. css代码被打包进了dist/bundle.js中
  2. 运行时, css代码插入到html的style标签中

注意,要打包的CSS文件,一定要导入到入口文件里才会被打包,不然安装加载器也么用。。

处理less文件问题

1、引入到入口文件中

import "./less/index.less"

2、下载包

yarn add less@4.1.1 less-loader@8.1.0 -D

3、webpack.config.js 配置

module: {
  rules: [ 
    // ...省略其他
    {
        test: /.less$/i, // 匹配.less结尾文件
        // 使用less-loader, 让webpack处理less文件, 内置还会用less模块, 翻译less代码成css代码
        use: [ "style-loader", "css-loader", 'less-loader']
    }
  ]
}

4、效果

  1. css代码被打包进了dist/bundle.js中
  2. 运行时, css代码插入到html的style标签中

处理图片文件问题

图片情况有三种

  • html文件里直接引入图片(这时html文件连带图片一起自动打包,无需处理)
  • css样式里将图片作为背景图片
  • js样式里利用src属性引入图片文件

对后面两种情况进行处理:

1、在css里将小图片做背景:

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

2、在main.js - 把大图插入到创建的img标签上, 添加body上显示

import imgUrl from './assets/1.gif'  // 引入图片模块-使用
const theImg = document.createElement("img")
theImg.src = imgUrl
document.body.appendChild(theImg)

3、webpack.config.js 配置

module: {
    rules: [ 
        // ...省略其他
        {
            test: /.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
            type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
            // 小于8kb的, 转成data URI(图片转成base64字符串打包进js中)
            // 大于8kb的, 直接复制文件到dist目录下(因为转base64会体积增30%)
        }
    ]
}
​

4、效果

1. 默认8kb以下图片, 转成base64字符串打包进js中, 减少网络请求次数   
    2.超过8kb的图片, 直接复制到dist下, 转base64会增加30%体积

处理字体图标问题

1、在main.js引入iconfont.css

import './assets/fonts/iconfont.css'  // 引入字体图标文件

2、在public/index.html使用字体图标样式

<i class="iconfont icon-weixin"></i>

3、webpack.config.js 配置

{   
        test: /.(eot|svg|ttf|woff|woff2)$/i,
        type: 'asset/resource', // asset/resource 表示不转成 BASE64, 直接复制到 dist
        // generator: 生成器, 帮我们自动整理输出到指定位置和指定的文件中
        generator: {
          // 占位符: 
          // [name] 原文件名, 表示以前叫什么名字现在就原样输出
          // [ext] 原后缀名(包含.), 原来的后缀名, 包括 ., 例如 .eot
          // [hash] 生成 hash 值, 唯一的标识, 避免重名覆盖
          filename: 'fonts/[name]-[hash:4][ext]'
    }
}

js语法降级处理

1、src/main.js - 编写箭头函数

const fn = () => { // 高级语法
  console.log("你好babel");
}
console.log(fn) // 一定打印函数, 才会被webpack把"函数体"打包起来

2、安装包

npm i babel-loader@8.2.2 @babel/core@7.13.15 @babel/preset-env@7.13.15   -D

3、webpack.config.js 配置

module: {
    rules: [
        {
            test: /.js$/, // 匹配js结尾文件
            exclude: /(node_modules|bower_components)/, // 不转换这2个文件夹里的js
            use: { 
                loader: 'babel-loader', // 使用加载器-处理
                options: {
                    presets: ['@babel/preset-env'] // 预设:转码规则(用bable开发环境本来预设的)
                }
            }
        }
    ]
}

4、打包后观察dist/的js文件, 自动变成普通函数

总结: 只要找到对应的loader加载器, 就能让webpack处理不同类型文件

webpack-直接配置修改

关于webpack配置修改,需要在项目 根目录 新建webpack.config,js文件,并且只要是修改里面配置代码,就必须重新运行打包命令

更改默认入口和出口配置

默认入口: src/index.js

默认出口: dist/main.js

填写配置项:

const path = require("path")
​
module.exports = {
    entry: "./src/main.js", // enter: 默认入口
    output: { 
        path: path.join(__dirname, "dist"), // 出口"文件夹"名
        filename: "bundle.js"               // 出口"文件"名
    }
}

此刻入口出口文件名为:

入口: src/main.js

出口: dist/bundle.js

配置指定开发模式

  • 在项目根目录中,创建名为webpack.config.js的webpack配置文件,并初始化如下的基本配置:
module.exprots={
    mode:'development'   //mode 用来指定构建模式  development 开发期间  production  发布期间
}

mode节点的可选值有两个:

(1)development:

1、开发环境

2、不会对打包生成的文件进行代码压缩和性能 优化

3、打包速度快,适合在开发阶段使用

(2)production:

1、生产环境

2、会对打包生成的文件进行代码压缩和性能优化

3、打包速度很慢,仅适合在发布阶段使用

webpack开发服务器

基本使用

问题:之前我们文件都是从磁盘上读取,所以每次修改了代码,都必须重启打包,再从磁盘上读取,才能看到更改后的页面效果,这样读取时间久,开发效率太低

解决方案:下载webpack-dev-server包

作用:将处理完的内容, 输出到内存里而非磁盘上,以后代码变化, 自动更新打包变化的代码, 显示到浏览器上

步骤:

1、下载包

npm i webpack-dev-server@3.11.2 -D

2、scripts配置自定义命令

scripts: {
    "build": "webpack",
    "serve": "webpack serve" 
}

3、运行命令-启动webpack开发服务器

 npm run serve //修改代码后不会刷新浏览器就直接更新页面了, 代码热更新, 只打包修改了的部分, 以打补丁的形式替换到浏览器上

4、效果:

以后修改src下的代码, 自动打包更新到浏览器上

配置修改

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

module.exports = {
    // ...其他配置
    devServer: {
      port: 3000, // 端口号
      open: true // 启动后自动打开浏览器
    }
}

项目打包发布

步骤

  1. 代码写完执行打包命令 npm run build 产生dist目录

    所有代码, 被整合打包

  2. 把dist目录交给后台/运维, 部署给客户使用即可

    开发环境的代码不用发

  3. 准备一个后端web服务, 把dist放进去, 暴露成静态资源目录供别人访问

    // 准备一个node+express的web服务, 可以部署和启动在一个接入外网的电脑上, 别人都可以访问const express = require('express')
    const app = express()
    ​
    // . 当前文件所在文件夹
    // / 打开文件夹
    // ./当前当前文件夹(也可以省略)
    app.use(express.static('./dist'))
    ​
    app.listen(4005)
    

注意

项目上线的时候一般都会把node_modules删除,如果后期需要运行程序,需要执行npm i将所有包再下载回来