JDWA 技术文档
首页
  • 数据库
  • 前端开发
  • 后端开发
  • 开发工具
  • 虚拟化技术
  • KVM显卡直通
  • FPGA仿真固件
  • 项目实战
  • 踩坑记录
  • 开发心得
  • 软件工具
  • 学习资料
  • 开发环境
更新日志
关于我
Gitee
GitHub
首页
  • 数据库
  • 前端开发
  • 后端开发
  • 开发工具
  • 虚拟化技术
  • KVM显卡直通
  • FPGA仿真固件
  • 项目实战
  • 踩坑记录
  • 开发心得
  • 软件工具
  • 学习资料
  • 开发环境
更新日志
关于我
Gitee
GitHub
  • 数据库

    • 数据库教程
    • MySQL免安装版使用指南
    • MySQL性能优化实践
    • Redis入门与实践
    • MinIO快速部署指南
    • MinIO基础使用教程
  • 前端开发

    • 前端开发教程
    • Vue.js开发最佳实践
    • CSS常用技巧与解决方案
    • JavaScript实用技巧与编程模式
    • CSS Grid布局教程
  • 后端开发

    • 后端开发教程
    • Spring Boot实战指南
    • Node.js Express 框架开发实战指南
    • Python Flask 框架开发指南
  • 开发工具

    • 开发工具教程
    • Git 基础教程
    • Git工作流实践指南
    • VS Code 全面使用指南
    • VS Code必装插件推荐
    • Docker基础入门
    • IntelliJ IDEA 使用技巧
    • Eclipse配置与优化
    • Sublime Text 高级技巧
    • Vim 从入门到精通
    • Maven 详解
    • Gradle 入门与进阶
    • Webpack 配置指南
    • npm 与 yarn 使用技巧
    • Makefile 编写指南
    • Navicat 使用指南
    • MCP本地部署教程
  • 虚拟化技术

    • JDWA虚拟化技术专题
    • KVM虚拟机去虚拟化技术详解
  • KVM显卡直通

    • KVM显卡GPU直通教程
  • FPGA仿真固件

    • FPGA仿真固件开发指南
    • 基础-完整设备仿真定制固件开发指南
    • 中级-完整设备仿真定制固件开发指南
    • 高级-完整设备仿真定制固件开发指南

Webpack 配置指南

Tips

本教程全面介绍Webpack构建工具的使用方法,从基础配置到高级应用,适用于Webpack 5及更高版本。

1. Webpack简介

Webpack是一个现代JavaScript应用程序的静态模块打包工具。它将项目中的所有资源(JavaScript文件、CSS文件、图片等)视为模块,根据模块的依赖关系进行静态分析,打包生成对应的静态资源。

1.1 Webpack的核心概念

  • 入口(Entry):指定webpack开始构建的起点
  • 输出(Output):指定webpack打包后的资源输出位置和命名
  • 加载器(Loader):处理非JavaScript文件的转换器
  • 插件(Plugin):扩展webpack功能的工具
  • 模式(Mode):指定构建模式(development、production或none)
  • 模块(Module):项目中的各种资源文件
  • 依赖图(Dependency Graph):webpack内部维护的模块间依赖关系图

1.2 为什么选择Webpack

  • 模块化:支持多种模块系统(CommonJS、ES Modules等)
  • 强大生态:丰富的loader和plugin生态系统
  • 高度可配置:几乎所有方面都可定制
  • 代码分割:智能分割代码,实现按需加载
  • 开发体验:热模块替换(HMR)提升开发效率
  • 资源优化:内置优化功能,如代码压缩、tree-shaking等

2. 安装与基本配置

2.1 安装Webpack

项目本地安装(推荐):

# 创建新项目
mkdir jdwa-webpack-demo && cd jdwa-webpack-demo
npm init -y

# 安装webpack和命令行工具
npm install webpack webpack-cli --save-dev

全局安装(不推荐):

npm install -g webpack webpack-cli

2.2 基本配置文件

在项目根目录创建webpack.config.js:

const path = require('path');

module.exports = {
  // 入口文件
  entry: './src/index.js',
  
  // 输出配置
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true // 每次构建前清理输出目录
  },
  
  // 构建模式
  mode: 'development' // 开发模式,不压缩代码
};

2.3 项目结构

jdwa-webpack-demo/
├── node_modules/
├── src/
│   └── index.js
├── dist/
│   └── bundle.js (构建后生成)
├── package.json
└── webpack.config.js

2.4 首次构建

  1. 创建入口文件 src/index.js:
console.log('Hello JDWA Webpack!');
  1. 添加npm脚本到package.json:
"scripts": {
  "build": "webpack",
  "dev": "webpack --watch"
}
  1. 运行构建:
npm run build

3. 处理各类资源

3.1 JavaScript处理

安装Babel转译ES6+代码:

npm install --save-dev babel-loader @babel/core @babel/preset-env

配置webpack.config.js:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
};

3.2 样式处理

安装样式相关loader:

npm install --save-dev style-loader css-loader sass-loader sass postcss-loader postcss postcss-preset-env

配置webpack.config.js:

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.s[ac]ss$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  }
};

创建postcss.config.js:

module.exports = {
  plugins: [
    require('postcss-preset-env')()
  ]
};

3.3 资源文件处理

Webpack 5内置资源模块(Asset Modules),无需额外loader:

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024 // 8kb以下转为内联
          }
        },
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[hash][ext][query]'
        }
      }
    ]
  }
};

3.4 HTML处理

安装HTML插件:

npm install --save-dev html-webpack-plugin

配置webpack.config.js:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      title: 'JDWA Webpack Demo',
      favicon: './src/favicon.ico'
    })
  ]
};

4. 开发环境配置

4.1 配置开发服务器

安装webpack-dev-server:

npm install --save-dev webpack-dev-server

配置webpack.config.js:

module.exports = {
  // ...
  devServer: {
    static: './dist',
    hot: true, // 启用HMR
    open: true, // 自动打开浏览器
    port: 8080,
    compress: true, // 启用gzip压缩
    historyApiFallback: true // SPA应用路由支持
  }
};

添加npm脚本:

"scripts": {
  "build": "webpack",
  "dev": "webpack serve --mode development"
}

4.2 源码映射(Source Maps)

为方便调试,配置源码映射:

module.exports = {
  // ...
  mode: 'development',
  devtool: 'eval-source-map' // 开发环境推荐
};

不同环境推荐的source-map类型:

  • 开发环境:eval-source-map(快速重建,提供行映射)
  • 生产环境:source-map(或不使用,减小文件体积)

4.3 模块热替换(HMR)

配置模块热替换,提升开发体验:

const webpack = require('webpack');

module.exports = {
  // ...
  devServer: {
    // ...
    hot: true
  },
  plugins: [
    // ...
    new webpack.HotModuleReplacementPlugin()
  ]
};

5. 生产环境优化

5.1 拆分配置文件

创建三个配置文件实现环境隔离:

  1. webpack.common.js:共享配置
  2. webpack.dev.js:开发环境配置
  3. webpack.prod.js:生产环境配置

安装合并工具:

npm install --save-dev webpack-merge

webpack.common.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    clean: true
  },
  module: {
    rules: [
      // loaders配置
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
};

webpack.dev.js:

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'eval-source-map',
  output: {
    filename: '[name].bundle.js'
  },
  devServer: {
    static: './dist',
    hot: true,
    open: true
  }
});

webpack.prod.js:

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  output: {
    filename: '[name].[contenthash].js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
      },
      {
        test: /\.s[ac]ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'styles/[name].[contenthash].css'
    })
  ],
  optimization: {
    minimizer: [
      new TerserPlugin(),
      new CssMinimizerPlugin()
    ]
  }
});

更新package.json:

"scripts": {
  "start": "webpack serve --config webpack.dev.js",
  "build": "webpack --config webpack.prod.js"
}

5.2 代码分割

利用代码分割优化加载性能:

module.exports = {
  // ...
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};

5.3 缓存优化

通过文件名哈希实现缓存优化:

module.exports = {
  // ...
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
    // ...
    runtimeChunk: 'single' // 提取runtime代码
  }
};

5.4 压缩资源

安装并配置相关插件:

npm install --save-dev mini-css-extract-plugin css-minimizer-webpack-plugin terser-webpack-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    // ...
    new MiniCssExtractPlugin({
      filename: 'styles/[name].[contenthash].css'
    })
  ],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true // 移除console
          }
        }
      }),
      new CssMinimizerPlugin()
    ]
  }
};

6. 高级配置

6.1 多页面应用配置

配置多个入口和HTML页面:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    main: './src/index.js',
    about: './src/about.js'
  },
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      chunks: ['main']
    }),
    new HtmlWebpackPlugin({
      template: './src/about.html',
      filename: 'about.html',
      chunks: ['about']
    })
  ]
};

6.2 环境变量配置

使用环境变量定制构建:

const webpack = require('webpack');

module.exports = {
  // ...
  plugins: [
    // ...
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      'process.env.API_URL': JSON.stringify(process.env.API_URL || 'https://api.jdwa.com')
    })
  ]
};

在代码中使用:

if (process.env.NODE_ENV === 'development') {
  console.log('开发环境');
}
console.log(`API地址: ${process.env.API_URL}`);

6.3 模块联邦(Module Federation)

Webpack 5的模块联邦特性,实现跨应用共享模块:

主应用 webpack.config.js:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  // ...
  plugins: [
    // ...
    new ModuleFederationPlugin({
      name: 'host',
      filename: 'remoteEntry.js',
      remotes: {
        remote: 'remote@http://localhost:8081/remoteEntry.js'
      },
      shared: ['react', 'react-dom']
    })
  ]
};

远程应用 webpack.config.js:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  // ...
  plugins: [
    // ...
    new ModuleFederationPlugin({
      name: 'remote',
      filename: 'remoteEntry.js',
      exposes: {
        './Button': './src/components/Button'
      },
      shared: ['react', 'react-dom']
    })
  ]
};

6.4 自定义解析

配置路径别名和扩展名解析:

module.exports = {
  // ...
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components'),
      '@styles': path.resolve(__dirname, 'src/styles')
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
  }
};

7. 框架专用配置

7.1 React项目配置

安装依赖:

npm install --save react react-dom
npm install --save-dev @babel/preset-react

配置webpack.config.js:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              '@babel/preset-env',
              ['@babel/preset-react', { runtime: 'automatic' }]
            ]
          }
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  }
};

7.2 Vue项目配置

安装依赖:

npm install --save vue
npm install --save-dev vue-loader vue-template-compiler

配置webpack.config.js:

const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    // ...
    new VueLoaderPlugin()
  ],
  resolve: {
    extensions: ['.js', '.vue']
  }
};

7.3 TypeScript配置

安装依赖:

npm install --save typescript
npm install --save-dev ts-loader

配置webpack.config.js:

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.ts', '.tsx']
  }
};

创建tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "strict": true,
    "noImplicitAny": true,
    "module": "esnext",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

8. 性能优化最佳实践

8.1 减小打包体积

  • Tree Shaking:移除未使用代码
  • 代码分割:拆分大型依赖
  • 按需加载:使用动态import()
  • 压缩代码:使用TerserPlugin
  • 压缩图片:使用image-webpack-loader
  • 分析包:使用webpack-bundle-analyzer

8.2 提高构建速度

  • DLL:将固定依赖预构建
  • 缓存:使用持久化缓存
  • 多线程:使用thread-loader
  • 限制loader作用范围:使用include/exclude
  • 使用最新版本:保持webpack和Node.js更新

8.3 包分析与优化

安装分析工具:

npm install --save-dev webpack-bundle-analyzer

配置webpack.config.js:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  // ...
  plugins: [
    // ...
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      openAnalyzer: false,
      reportFilename: 'bundle-report.html'
    })
  ]
};

9. 常见问题与解决方案

9.1 构建太慢

问题:webpack构建时间过长 解决方案:

  1. 启用缓存
module.exports = {
  // ...
  cache: {
    type: 'filesystem'
  }
};
  1. 使用thread-loader实现多线程构建
npm install --save-dev thread-loader
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          'thread-loader',
          'babel-loader'
        ]
      }
    ]
  }
};

9.2 打包文件过大

问题:打包后JS文件体积过大 解决方案:

  1. 使用生产模式启用优化
module.exports = {
  mode: 'production'
};
  1. 使用externals排除大型库
module.exports = {
  // ...
  externals: {
    jquery: 'jQuery',
    react: 'React',
    'react-dom': 'ReactDOM'
  }
};
  1. 使用动态导入实现按需加载
// 使用动态导入
import('./module').then(module => {
  // 使用模块
});

9.3 浏览器兼容性

问题:代码在旧浏览器中不兼容 解决方案:

  1. 使用Babel和core-js
npm install --save core-js regenerator-runtime
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', {
                useBuiltIns: 'usage',
                corejs: 3
              }]
            ]
          }
        }
      }
    ]
  }
};

10. Webpack 5新特性

10.1 持久化缓存

Webpack 5引入持久化缓存,显著提升构建速度:

module.exports = {
  // ...
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename] // 配置文件变更时使缓存失效
    }
  }
};

10.2 资源模块

内置资源模块类型处理静态资源:

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.png/,
        type: 'asset/resource' // 生成单独文件
      },
      {
        test: /\.svg/,
        type: 'asset/inline' // 转为DataURL
      },
      {
        test: /\.txt/,
        type: 'asset/source' // 导入源代码
      },
      {
        test: /\.jpg/,
        type: 'asset', // 自动选择
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb
          }
        }
      }
    ]
  }
};

10.3 更好的Tree Shaking

Webpack 5改进了Tree Shaking算法,提供更细粒度的优化:

module.exports = {
  // ...
  optimization: {
    usedExports: true,
    sideEffects: true
  }
};

在package.json中标记无副作用模块:

{
  "name": "jdwa-module",
  "sideEffects": false
}

结语

Webpack是现代前端开发中不可或缺的工具,它的灵活性和强大功能能够满足各种构建需求。本教程介绍了Webpack的核心概念和常见配置,帮助你更好地理解和使用Webpack进行前端工程化开发。随着项目的成长,合理的Webpack配置能够显著提升开发体验和产品性能。

Prev
Gradle 入门与进阶
Next
npm 与 yarn 使用技巧