Webpack 2024 前前端架构老鸟的分享(一)

Webpack 2024 前端架构老鸟的分享(一)

简述

嘿,各位!作为一个Webpack的老用户,我得吐槽一句,这玩意儿一开始真是够折腾人的!别说配置文件了,就像是在写某种古老的神秘仪式的咒语。刚开始的时候,我简直是摸不着头脑啊!但是别慌,慢慢来,慢慢琢磨,你会发现Webpack这个家伙,虽然有点拗口,但一旦掌握了它的精髓,就像是驾驭了一匹烈马一样,带你疾驰在前端的征途上!

你可能收货

关于webpack暂时计划是出三期,你将会学到基本的配置,和常用的插件的使用,以及一些基础原理和生命周期的流转,第三篇会教大家如何编写一个自己的loader,以及深入理解loader的原理。

读白

当然说到这里,很多人会说:"现在vite这么火为什么我不直接去用Vite呢?🙄"

统一回复:"新鲜事物赞成积极尝试,且Vite后面我们也会单独说,但是旧的事物必然有存在的意义,😄且企业并不希望你用什么新技术炫技或者变动太大,所有我们温故,遂而知新,认同这种观点你可以继续看下去 第一章也比较简单,但是如果你的动手能力强直接去官网研究是最好的,好了废话有点多,不影响大家继续学习🌹。"

一、Webpack 概念和基础知识

1.1 Webpack 简介

Webpack 不仅是一个模块打包工具,更是一个强大的构建工具。它可以充分利用现代 JavaScript 的优势,并将其内置的丰富功能发挥到极致。Webpack 的主要应用场景有:

  • 单页面应用程序(SPA)
  • 与框架如 React、Vue 等配合使用
  • 适用于需要对代码、资源进行复杂处理的大型项目

Webpack 优势:

  • 代码拆分 自动化资源文件的拆分,有利于减少首次加载时间和提高文件缓存利用率。
  • Loader Webpack 本身只能处理 JavaScript 模块,通过 Loader 可以使它支持其他格式的文件。
  • 智能解析 能够解析常用的模块化方案,例如 CommonJS、AMD、ES Module。
  • 插件系统 通过插件系统可以实现更加复杂、自动化的功能。
  • 环境支持 既可以运行在开发环境,又可以供生产环境使用。

1.2 Webpack 核心概念

  • 入口(Entry) 指定 Webpack 构建的入口模块文件,可以是单个文件,也可以是多个文件组成的数组或对象。

示例:

js 复制代码
module.exports = {
  entry: './src/index.js' // 单入口
  entry: ['./src/index.js', './src/app.js'] // 多入口数组
  entry: {
    main: './src/index.js', 
    app: './src/app.js'
  } // 多入口对象
}
  • 输出(Output) 指定 Webpack 构建后的资源输出位置和输出文件名称。

示例:

js 复制代码
const path = require('path');
module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'), // 输出目录
    filename: 'bundle.js' // 输出文件名
  }
}
  • Loader Loader 用于对模块的源代码进行转换,扩展 Webpack 的能力。

示例:

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader'] 
      }
    ]
  }
}
  • 插件(Plugins) 插件用于执行更广泛的任务,例如打包优化、资源管理等。

示例:

js 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin');
​
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

二、Webpack 配置文件详解

2.1 入口(Entry)

入口是 Webpack 构建的起点,可以按需配置单个或多个入口。

单入口语法

js 复制代码
module.exports = {
  entry: './src/index.js'  
}

多入口语法

js 复制代码
module.exports = {  
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
}

以上示例中,Webpack 会为每个入口构建一个 Chunk(输出文件)。

动态入口语法

什么是动态入口?

动态入口是指在 Webpack 构建过程中动态生成入口模块路径的一种机制。与传统的静态入口不同,动态入口可以根据不同的条件或环境生成不同的入口模块路径,从而实现更灵活的构建配置。

基础配置:

js 复制代码
entry: () => './src/index.js'

动态入口的优势

动态入口具有以下优势:

  • 提高可扩展性: 可以根据不同的需求或环境动态生成入口模块路径,从而提高 Webpack 配置的可扩展性。
  • 简化配置: 可以避免重复的配置,使 Webpack 配置更加简洁易懂。
  • 提高代码复用: 可以将通用的代码提取到单独的模块中,并在不同的入口模块中进行复用。

动态入口的实现

动态入口可以通过以下两种方式实现:

  • 使用函数: 可以使用函数返回一个入口模块路径字符串或数组。
  • 使用 webpack.DefinePlugin 插件: 可以使用 webpack.DefinePlugin 插件定义一个全局变量,并使用该变量来动态生成入口模块路径。

使用函数实现动态入口

js 复制代码
entry: () => {
  const env = process.env.NODE_ENV;
  if (env === 'development') {
    return './src/index.dev.js';
  } else {
    return './src/index.prod.js';
  }
}

上述代码根据 NODE_ENV 环境变量来动态生成入口模块路径。在开发环境下,入口模块路径为 ./src/index.dev.js;在生产环境下,入口模块路径为 ./src/index.prod.js

使用 webpack.DefinePlugin 插件实现动态入口

js 复制代码
module.exports = {
  entry: './src/index.js',
  plugins: [
    new webpack.DefinePlugin({
      'process.env.ENTRY_MODULE': JSON.stringify('./src/index.dev.js'),
    }),
  ],
};

上述代码使用 webpack.DefinePlugin 插件定义了一个全局变量 process.env.ENTRY_MODULE,并将其值设置为 ./src/index.dev.js。然后,可以在入口模块中使用该变量来动态生成入口模块路径。

小结

动态入口是一种灵活的 Webpack 构建机制,可以根据不同的需求或环境生成不同的入口模块路径,从而提高 Webpack 配置的可扩展性、简化配置和提高代码复用。

2.2 输出(Output)

output 选项用于控制 Webpack 构建后的资源输出位置和文件名称。

js 复制代码
const path = require('path');
​
module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'), // 输出路径
    filename: 'bundle.js', // 输出文件名
    publicPath: '/', // 公共路径 
    chunkFilename: '[name].bundle.js', // 代码分割后的命名
    libraryTarget: 'var', // 库导出方式
    library: 'MyLibrary' // 库名称
  }
}

2.3 模式(Mode)

mode 用于指定当前的构建环境,可选值有 production、development 或 none。

js 复制代码
module.exports = {
  mode: 'production' // 生产环境
  mode: 'development' // 开发环境
}

2.4 模块(Module)

module 选项用于配置模块的解析规则,例如使用哪些 Loader。

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader' 
      }
    ]
  }
}

2.5 解析(Resolve)

resolve 选项用于设置模块解析规则,例如别名、扩展名等。

js 复制代码
module.exports = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    },
    extensions: ['.js', '.jsx', '.json'], 
    modules: ['node_modules']
  }
}

2.6 插件(Plugins)

plugins 选项用于应用各种 Webpack 插件。

js 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
​
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new CleanWebpackPlugin(['dist'])
  ]
}

2.7 优化(Optimization)

optimization 选项用于优化构建结果。

js 复制代码
module.exports = {
  optimization: {
    minimize: true, // 开启代码压缩
    splitChunks: {
      chunks: 'all' // 代码分割
    }
  }
}

2.8 devServer

devServer 选项用于配置 Webpack 开发服务器。

js 复制代码
module.exports = {
  devServer: {
    contentBase: './dist', 
    hot: true, // 热更新
    open: true, // 自动打开浏览器
    port: 8080, // 端口号
    proxy: { // 代理设置
      '/api': 'http://localhost:3000'
    }
  }
}

基础小节

示例:

为了演示三级标题提到的Webpack配置,我们将创建一个简单的项目结构,并添加一个入口文件和一个HTML模板文件。然后,我们将使用Webpack进行打包,并通过Webpack DevServer在开发服务器上进行实时预览。

首先,创建一个名为webpack-demo的新目录,并在其中创建以下文件和目录结构:

bash 复制代码
webpack-demo/        // 项目根目录
  |- src/            // 存放项目的源代码
  |   |- index.js    // 项目的入口文件
  |- dist/           // Webpack 构建后的输出目录
  |- index.html      // 项目的 HTML 模板文件
  |- package.json    // npm 包的配置文件
  |- webpack.config.js   // Webpack 的配置文件

接下来,我们按照以下步骤编辑这些文件:

  1. src/index.js - 这是我们的入口文件,内容可以是简单的JavaScript代码,作为演示,我们将在这里输出一条简单的日志信息:
js 复制代码
console.log("Hello from webpack!");
  1. index.html - 这是我们的HTML模板文件,Webpack会根据配置在dist目录中生成一个新的HTML文件,并注入打包后的JavaScript文件。这里我们简单写一个HTML框架:
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Webpack Demo</title>
</head>
<body>
    <div id="app">Hello Webpack </div>
</body>
</html>
  1. webpack.config.js - 这是我们的Webpack配置文件,我们按照之前提到的配置内容来编写:
js 复制代码
const path = require('path');  // 引入 Node.js 的 path 模块,用于处理文件路径
const HtmlWebpackPlugin = require('html-webpack-plugin');  // 引入 HtmlWebpackPlugin 插件,用于生成 HTML 文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');  // 引入 CleanWebpackPlugin 插件,用于清理构建目录
module.exports = {
  mode: 'development',  // 指定构建模式为开发模式
  entry: './src/index.js',  // 指定入口文件为 src 目录下的 index.js 文件
  output: {
    path: path.resolve(__dirname, 'dist'),  // 指定输出目录为当前目录下的 dist 文件夹
    filename: 'bundle.js',  // 指定输出文件名为 bundle.js
  },
  module: {
    rules: [  // 配置 Loader 规则
      {
        test: /.js$/,  // 匹配以 .js 结尾的文件
        exclude: /node_modules/,  // 排除 node_modules 目录下的文件
        use: {  // 使用 babel-loader 进行转译
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']  // 使用 @babel/preset-env 进行转译
          }
        }
      }
    ]
  },
  plugins: [  // 配置插件
    new CleanWebpackPlugin(),  // 在每次构建前清理 dist 目录
    new HtmlWebpackPlugin({  // 生成 HTML 文件
      template: './index.html'  // 指定 HTML 模板文件
    })
  ],
  devServer: {  // 配置开发服务器
    static: {
      directory: path.resolve(__dirname, 'dist'), // 指定服务器内容的基础目录
    },
      port: 8080,  // 指定端口号为 8080
     open: true,  // 自动在浏览器中打开
     hot:true //开启热更新
  }
};
  1. package.json - 添加必要的依赖和脚本:
js 复制代码
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "A simple webpack demo",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve --open",
    "build": "webpack"
  },
  "keywords": [
    "webpack",
    "demo"
  ],
  "author": "Your Name",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.16.0",
    "@babel/preset-env": "^7.16.0",
    "babel-loader": "^8.2.3",
    "clean-webpack-plugin": "^4.0.0",
    "html-webpack-plugin": "^5.5.0",
    "webpack": "^5.66.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.8.0"
  }
}

安装所需的依赖:

bash 复制代码
npm install //安装所有依赖  这里就不一一安装了直接使用我的package.json就好了

现在,我们已经准备好了我们的Webpack配置和项目文件。要执行打包并启动开发服务器,请运行以下命令:

bash 复制代码
npm start

Webpack将开始构建项目,并在浏览器中打开一个新的选项卡,显示我们的页面。你可以在控制台中看到来自Webpack的输出信息,以及我们在src/index.js中添加的日志信息。

这样就完成了简单的Webpack配置和项目设置。你自己可以根据需要扩展配置,并添加更多的功能和插件来满足项目的需求。

下篇:Webpack 2024 前端架构老鸟的分享(二)

相关推荐
Nan_Shu_6146 小时前
学习: Threejs (2)
前端·javascript·学习
G_G#6 小时前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界6 小时前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路6 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug6 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121386 小时前
React面向组件编程
开发语言·前端·javascript
学历真的很重要6 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
持续升级打怪中7 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路7 小时前
GDAL 实现矢量合并
前端
hxjhnct7 小时前
React useContext的缺陷
前端·react.js·前端框架