Post

Webpack 构建配置

Webpack 构建配置

Webpack 核心概念

  • 入口(Entry):打包的起点。
  • 输出(Output):生成的文件。
  • 加载器(Loaders):处理非 JavaScript 文件。
  • 插件(Plugins):扩展功能,如优化、压缩。

1:基础配置 - entry、output

初始化项目

1
2
3
4
mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

创建文件结构

1
2
3
4
5
webpack-demo/
├── src/
│   └── index.js
├── package.json
└── webpack.config.js

简单配置

webpack.config.js 中:

1
2
3
4
5
6
7
8
9
10
const path = require('path');

module.exports = {
  entry: './src/index.js', // 入口文件
  output: {
    path: path.resolve(__dirname, 'dist'), // 输出目录
    filename: 'bundle.js' // 输出文件名
  },
  mode: 'development' // 开发模式
};

测试运行

src/index.js 中:

1
console.log('Hello, Webpack!');

添加脚本到 package.json

1
2
3
"scripts": {
  "build": "webpack"
}

运行 npm run build,检查 dist/bundle.js 是否生成。

2:加载器配置 - loader

Webpack 默认只处理 JavaScript,需要加载器处理其他文件类型。

处理 CSS

安装:

1
npm install style-loader css-loader --save-dev

更新 webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
  // ...其他配置
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'] // 从右到左执行
      }
    ]
  }
};

处理图片

安装:

1
npm install file-loader --save-dev

添加规则:

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
  // ...其他配置
  module: {
    rules: [
      // ...CSS 规则
      {
        test: /\.(png|jpg|gif)$/,
        use: ['file-loader']
      }
    ]
  }
};

3:插件配置 - plugins

插件是 Webpack 的强大扩展点。

自动生成 HTML

安装:

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

配置:

1
2
3
4
5
6
7
8
9
10
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...其他配置
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html' // 模板文件
    })
  ]
};

创建 src/index.html

1
2
3
4
5
6
<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
  </body>
</html>

清理输出目录

安装:

1
npm install clean-webpack-plugin --save-dev

配置:

1
2
3
4
5
6
7
8
9
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  // ...其他配置
  plugins: [
    new CleanWebpackPlugin(),
    // ...其他插件
  ]
};

4:开发优化

热更新

安装:

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

更新 package.json

1
2
3
4
"scripts": {
  "start": "webpack-dev-server --open",
  "build": "webpack"
}

配置:

1
2
3
4
5
6
7
module.exports = {
  // ...其他配置
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 8080
  }
};

5:打包优化

模式切换

mode 改为 'production',启用内置优化(如代码压缩)。

分离 CSS

安装:

1
npm install mini-css-extract-plugin --save-dev

配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  // ...其他配置
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css'
    })
    // ...其他插件
  ]
};

代码分割

配置动态导入:

1
2
3
4
5
6
7
8
module.exports = {
  // ...其他配置
  optimization: {
    splitChunks: {
      chunks: 'all' // 自动分割 vendor 和公共代码
    }
  }
};

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: ['file-loader']
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css'
    })
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 8080
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};
This post is licensed under CC BY 4.0 by the author.