# webpack 是什么?
Webpack 是一个现代 JavaScript 应用的静态模块打包工具。它通过分析模块依赖关系,将项目中的所有资源(JS、CSS、图片等)转换为浏览器可识别的静态资源,并支持代码优化与扩展功能
# 核心概念
- Entry (入口)
- 定义打包起点,支持单入口(string)、多入口(array 或 object)
- 示例:
| entry: { |
| index: ['./src/index.js', './src/utils.js'], |
| vendor: './src/vendor.js' |
| } |
- Output (输出)
- 指定打包文件的输出路径与命名规则,常用 path 和 filename 配置。
- 示例:
| output: { |
| path: path.resolve(__dirname, 'dist'), |
| filename: '[name].[contenthash].js' |
| } |
- Loader (加载器)
- 处理非 JS 文件(如 CSS、图片),需安装对应 Loader。
- 示例:通过 css-loader 和 style-loader 处理 CSS 文件:
| module: { |
| rules: [{ |
| test: /\.css$/, |
| use: ['style-loader', 'css-loader'] |
| }] |
| } |
- Plugin (插件)
- 扩展 Webpack 功能,如生成 HTML 模板、清理构建目录。
- 常用插件:
- HtmlWebpackPlugin:自动生成 HTML 并注入 JS 文件
- CopyWebpackPlugin:复制静态文件(如无需打包的配置文件)
- Mode (模式)
- 区分开发(development)与生产(production)环境,内置代码压缩等优化
# 核心功能与优化
- 热模块替换 (HMR)
- 开发时仅更新修改的模块,提升构建速度。
- 配置:
| devServer: { |
| hot: true, |
| open: true |
| } |
- 缓存优化
- hash 策略:
- hash: 全局唯一哈希,任一文件变动则全部更新。
- chunkhash: 基于 Chunk 生成,同 Chunk 共享哈希。
- contenthash: 基于文件内容生成,文件内容不变则哈希不变。
- Tree Shaking
- 移除未使用的代码,需要满足 ES6 模块化规范,且使用 tree-shaking 插件
- Source Map
- 映射编译后代码到源码,便于调试。常用配置:
- 开发环境:
cheap-module-eval-source-map
(快速定位行) - 生产环境:
cheap-module-source-map
(不暴露源码)
# 开发与生产环境配置
- 开发服务器
- 启动本地服务并支持代理,HMR:
| devServer: { |
| port: 8080, |
| proxy: { '/api': 'http://localhost:3000' } |
| } |
- 代码分割
- 通过
SplitChunksPlugin
拆分公共代码,减少首屏加载时间
# 常见资源处理示例
- 处理图片与字体
- 使用
url-loader
或 file-loader
: | { |
| test: /\.(png|jpg|gif)$/, |
| use: [{ |
| loader: 'url-loader', |
| options: { limit: 8192 } |
| }] |
| } |
- 处理 Less/Sass
- 安装
less-loader
和 sass-loader
,配置链式 Loader: | { |
| test: /\.less$/, |
| use: ['style-loader', 'css-loader', 'less-loader'] |
| } |
# 实际应用示例
- 安装
webpack
| npm install --save-dev webpack webpack-cli |
- 在项目根目录创建
webpack.config.js
,并添加以下内容:
| const path = require('path') |
| |
| const config = { |
| entry: './src/index.js', |
| output: { |
| path: path.resolve(__dirname, 'build'), |
| filename: 'main.js' |
| } |
| } |
| module.exports = config |
- 添加脚本到
package.json
:方便执行 npm run build
| "scripts": { |
| "build": "webpack --mode=development" |
| }, |
- 把应用变成一个最小的 React 应用
| npm install react react-dom |
- 配置加载器,将 Jxx 脚本转换为浏览器可识别的 JavaScript 代码
| const config = { |
| entry: './src/index.js', |
| output: { |
| path: path.resolve(__dirname, 'build'), |
| filename: 'main.js', |
| }, |
| |
| module: { |
| rules: [ |
| { |
| test: /\.js$/, |
| loader: 'babel-loader', |
| options: { |
| presets: ['@babel/preset-react'], |
| }, |
| }, |
| ], |
| }, |
| } |
把加载器和它所需要的包作为开发依赖项来安装
| npm install @babel/core babel-loader @babel/preset-react --save-dev |
- 把 babel 执行的转置过程设置为预设,并添加一个 babel-loader
| { |
| test: /\.js$/, |
| loader: 'babel-loader', |
| options: { |
| |
| presets: ['@babel/preset-env', '@babel/preset-react'] |
| } |
| } |
用命令安装这个预设
| npm install @babel/preset-env --save-dev |
- 使用 CSS 时,我们必须使用 CSS 和 style 加载器
| { |
| rules: [ |
| { |
| test: /\.js$/, |
| loader: 'babel-loader', |
| options: { |
| presets: ['@babel/preset-react', '@babel/preset-env'], |
| }, |
| }, |
| |
| { |
| test: /\.css$/, |
| use: ['style-loader', 'css-loader'], |
| }, |
| ]; |
| } |
安装加载器
| npm install style-loader css-loader --save-dev |
- 我们需要一个能够对应代码改变的 service,使得不需要从新刷新页面
| npm install --save-dev webpack-dev-server |
定义一个 npm 脚本来启动
| { |
| |
| "scripts": { |
| "build": "webpack --mode=development", |
| |
| "start": "webpack serve --mode=development" |
| }, |
| |
| } |
并且在 webpack.config.js 中添加 devServer 配置
| const config = { |
| entry: './src/index.js', |
| output: { |
| path: path.resolve(__dirname, 'build'), |
| filename: 'main.js', |
| }, |
| |
| devServer: { |
| static: path.resolve(__dirname, 'build'), |
| compress: true, |
| port: 3000, |
| }, |
| |
| }; |
这样我们就可以通过 npm start
命令在 3000 端口启动一个服务了
- 当我们代码出错时,错误位置与源代码的实际位置不一致
我们需要 webpack 为 bundle 生成一个所谓的 source map,使得我们可以知道错误位置
在配置对象中添加一个新的 devtool
属性
| const config = { |
| entry: './src/index.js', |
| output: { |
| |
| }, |
| devServer: { |
| |
| }, |
| |
| devtool: 'source-map', |
| |
| }; |
- 我们可以设置 webpack 在 production 模式下使用一些优化
| { |
| "name": "webpack-part7", |
| "version": "0.0.1", |
| "description": "practising webpack", |
| "scripts": { |
| |
| "build": "webpack --mode=production", |
| "start": "webpack serve --mode=development" |
| }, |
| "license": "MIT", |
| "dependencies": { |
| |
| }, |
| "devDependencies": { |
| |
| } |
| } |