Webpack工程化,从效果看透本质

281 阅读6分钟

概述

Webpack 是一个功能强大的静态模块打包器,它能够分析项目依赖并捆绑各种资源(如JavaScript、CSS、图片等),通过高度定制化的配置选项(mode、entry、output、loaders、plugins和module),让你能够灵活地调整构建流程,从而优化产出,特别是从兼容性角度提高应用上限。

为什么需要工程化?

工程化简单来说就是将项目复杂的的开发过程分解为一系列明确的步骤,提高项目的维护性和拓展性。

  • 自动化构建:工程化工具可以自动完成编译、压缩、测试等一系列繁琐的任务,让开发者专注于业务逻辑。
  • 代码管理:随着项目规模的增长,手动管理依赖和资源变得不可行。工程化可以使得代码更加模块化,易于管理和扩展。
  • 标准化:确保代码风格一致,易于维护。使用工程化工具可以统一编码规范,便于团队协作。

本期内容主要针对开发阶段,说明如何去配置Webpack。

我们需要构建如下界面来理解Webpack配置流程:

image.png

是的,页面很简单,但是里面涉及到的Webpack内容都是在实际开发中需要用到的,而习惯使用Vite的开发者在许多时候都不需要自己配置。

一、初始化项目

1 . 创建项目目录

2 . 创建package.json配置文件 js npm init -y

3. 安装Webpack相关依赖

  • webpack,这是核心打包工具 js npm install webpack --save-dev
  • webpack-cli,这是命令行工具 js npm install webpack-cli --save-dev
  • webpack-dev-server,这是用于开发环境的HTTP服务器 js npm install webpack-dev-server --save-dev

由于webpack这三个工具只需要在开发过程中用于打包流程,所以放在开发依赖模块即可。--save-dev也可以简写为-D

4 . 配置Webpack:

  • 创建webpack.config.js文件,在其内部定义Webpack的行为。这个文件当中有6个部分,分别是:

mode : 指明打包阶段,例如设置为development,表示开发环境打包

entry : 设置一个项目入口,通常是'./src/main.js'

output : 指定文件输出的位置和名称

  output : {
        //打包的文件信息
        filename : 'bundle.js',
        //src开发目录  dist打包目录
        path : path.resolve(__dirname,'dist'),        
  },

devServer : 自定义开发服务器的行为,这里很好地体现了webpack的定制性。

 devServer: {
     //指定开发服务器所在根目录
     contentBase : path.join(__dirname, 'public'),
     //设置为true,表示对客户端的响应启用gzip压缩,提高加载速度
     compress: true,
     //设置开发服务器监听的端口
     port: 5173,
     //表示启动后自动打开浏览器显示
     open: true,
     //启用热模块替换,允许不刷新页面而更新内容
     hot: true,
     //当服务器找不到请求的文件时返回index.html
     historyApiFallback: true,
     
     client: {
       //关闭错误信息显示
       overlay: false,
       //开启进度条
       progress: true,
       //仅记录警告信息
       logging: 'warn',
     },
     //响应头,配置CORS头部,*号表示同意所有请求
     headers: {
       'Access-Control-Allow-Origin': '*',
     },
     // 代理所有以 /api 开头的请求到 http://localhost:3000
     proxy: {
       '/api': 'http://localhost:3000', 
     },
},

loaders : 用于处理不同文件的加载器,例如babel-loader,能够将ES6+的语法转译为ES5的语法,保证代码在不同版本浏览器上稳定运行。

plugins : 执行更复杂的任务,比如生成HTML文件或JS和CSS文件注入到HTML当中。

二、开发流程

这里的页面内容十分简单,我们先下载用于测试的Vue、stylus 模块:

npm i vue
npm i stylus -D

1 . 编写界面 App.vue

<template>
    <div>
        <h3>Theme</h3>
        <p>This is a sentence.</p>
        <button>我是一个按钮</button>
    </div>
</template>

<script setup>
    const a = 18;
    console.log(`今年-${a}-岁`);
</script>

<style lang="stylus" scoped>
    h3{
        color: #42b983;
    }
</style>

2 . p标签单独的CSS样式:

p{
    font-size: 18px;
    color : #333;
}

这个例子就是想说明Webpack会如何去处理这样一份代码,毕竟在没有Webpack的配置下,显示效果需要我们将JS和CSS嵌入到一个HTML中,完成最终显示,而在这里则是通过Vue作为一个桥梁搭建页面。

3 . 挂载根节点

我们继续来到main.js创建根节点,挂载这个Vue组件。

import './style.css';
import App from './App.vue'
import { createApp } from 'vue';

const app = createApp(App);
app.mount('#app');

main.js作为程序入口,index.html作为主页面,在public目录下。

4 . 注入根节点

这里需要我们手动添加id为app的div,作为一个全局注入点。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Webpack</title>
</head>
<body>
    <div id="app">
        <App></App>
    </div>
</body>
</html>

其实到这里,事情都还和我们原来的操作一模一样,不过接下来的操作,由于没有使用Vite,需要手动配置编译Vue、stylus、JS的加载器和插件。

浏览器是一个十分质朴的存在,对于原生HTML JS CSS,它能够很好地识别这些老朋友,但是Vue和stylus这样提高开发效率的产物,浏览器不能直接运行。

配置完善

在第一步初始化时,我们已经将Webpack的三大核心工具安装好了,并且还配置了webpack.config.js,将Webpack工程的框架搭建完毕。接下来我们需要注入灵魂,引入插件还有加载器。

先看插件:

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

HtmlWebpackPlugin是HTML文件打包过程中的重要部分,它能够将打包好的JS与CSS文件注入HTML文件。

VueLoaderPlugin是对Vue工程打包的依赖插件。

再看加载器:

image.png

Webpack官方提供了很多加载器,根据我们编写的页面,我们需要用到以下加载器:

    module : {
        rules : [
            {
                //需要处理的部分,以.js结尾的文件
                test : /\.js$/,
                //需要排出的部分,过滤
                exclude : /node_modules/,
                use : {
                    loader : "babel-loader"
                }
            },
            {
                //需要处理的部分,以.js结尾的文件
                test : /\.css$/,
                use : ["style-loader","css-loader"]
                
            },
            {
                test : /\.vue$/,
                use : {
                    loader : "vue-loader"
                }
            },
            {
                test: /\.styl(us)?$/,
                use : [
                    {
                        loader : "style-loader"
                    },
                    {
                        loader : "css-loader"
                    },
                    {
                        loader : 'stylus-loader'
                    }
                ]
                
            },
        
        ],
    }

具体来说,开发过程需要用到的依赖如下,可以引入package.json后下载即可:

  "devDependencies": {
    "@babel/core": "^7.15.0",
    "@babel/preset-env": "^7.15.0",
    "babel-loader": "^8.2.2",
    "css-loader": "^6.0.0",
    "html-webpack-plugin": "^5.3.2",
    "style-loader": "^3.0.0",
    "stylus": "^0.63.0",
    "stylus-loader": "^8.1.0",
    "vue-loader": "^16.2.0",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^5.36.2",
    "webpack-cli": "^4.6.0",
    "webpack-dev-server": "^3.11.2",
    "vue-style-loader": "^4.1.3"
  },

最后再将scripts部分内容换成 : "dev": "webpack serve"即可。

设置完这些,我们的项目就能够被正确打包,我们来看看效果。

image.png

其中,babel-loader能够将ES6+新语法转换成兼容性更好的ES5语法。

image.png

可以看到,对于let关键字,babel-loader转译成了var,这是一个语法降级,保证兼容性的操作。

还有,vue-loader 将Tempalte里面的内容转换为了HTML上的节点内容,要知道,template的内容实际上就是字符串。

image.png

至于stylus,也自然被style-loaderstylus-loader转译成了CSS代码执行。

至此,完整且结构清晰,兼容性较好的页面就被创建出来,这就是工程化的魅力。

总结

  • Webpack的作用与优势

    • Webpack 是一个静态模块打包器,通过分析项目依赖关系来捆绑多个模块。
    • 它支持多种资源类型(如 JavaScript、CSS、图片等),并可通过配置适应不同的需求。
    • Webpack 能够提高项目的可维护性和可扩展性,通过自动化构建、代码管理和标准化等手段。
  • 项目初始化与配置

    • 初始项目设置包括创建目录、初始化 package.json 文件和安装必要的依赖(如 webpackwebpack-cliwebpack-dev-server)。
    • webpack.config.js 文件用于定义 Webpack 的行为,包括模式设置、入口点、输出配置、开发服务器配置、加载器和插件。
  • 配置中的重点

    • Mode: 设置为 development 或 production,影响打包时的优化级别。
    • Entry: 指定应用的入口文件,通常为 src/main.js
    • Output: 指定输出文件的位置和名称。
    • DevServer: 配置开发服务器,包括内容基础路径、是否启用 gzip 压缩、端口、是否自动打开浏览器、是否启用热模块替换等。
    • Loaders: 用于处理特定类型的文件,例如 babel-loader 用于将 ES6+ 代码转译为 ES5 代码,vue-loader 处理 .vue 文件,stylus-loader 处理 .styl 文件。
    • Plugins: 执行更复杂的任务,如 HtmlWebpackPlugin 用于生成 HTML 文件并自动注入打包后的 JS 和 CSS 文件。

Webpack的生态十分丰富,适合大型定制项目,但是其配置难度和打包速度也一直被人诟病,Vite作为新一代的构建工具,已经成为了越来越多项目的选择。