webpack介绍

entry与output

入口是 Webpack 开始构建依赖图的起点,Webpack 会从入口文件开始,递归地分析项目的依赖图。输出指定 Webpack 打包后的文件存放位置和文件名。

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
};

依赖图如下所示 :

loader

Webpack 支持使用 loader 对文件进行预处理。这允许你bundle JavaScript 之外的任何静态资源。

css-loader与style-loader

css-loader 是 Webpack 中的一个加载器(loader),它允许你在 JavaScript 中直接导入 CSS 文件,并将这些 CSS 文件打包到最终的 bundle 中。这种方式与传统的通过 <link> 标签在 HTML 中引入 CSS 文件的方式不同。

实验结构如下:

如果只是单纯的在index.js中引入style.css:

css 复制代码
#header {
  color: blue;
}

.button {
  background-color: yellow;
}
javascript 复制代码
import _ from "lodash";
import "./style.css";

document.getElementById("button1").addEventListener("click", function () {
  const el = document.getElementById("header");
  el.innerHTML = "Hey i have updated the code !";

  const listItems = ["Apple", "orange", "Banana"];
  const ul = document.getElementById("shoppingList");
  _.forEach(listItems, function (item) {
    const tempEl = document.createElement("li");
    tempEl.innerHTML = item;
    ul.appendChild(tempEl);
  });
});

会报错如下:

首先下载npm install --save-dev css-loader style-loader,并且在webpack.config.js中进行配置:

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["css-loader", "style-loader"],
      },
    ],
  },
};

module 是一个关键配置项,用于定义 如何处理项目中不同类型的模块(如 JavaScript、CSS、图片、字体等),其中rules可以设置多种资源的loader,test匹配文件名,use调用对应loader。

为了匹配文件名使用正则表达式,其中/正表示则表达式的开始和结束符号,\. 表示匹配字符 .(因为 . 在正则中有特殊含义,所以需要用 \ 转义),css表示匹配字符串 css,``$表示匹配字符串的结尾。)

成功bundle如下:

webpack会隐式插入:

但以上内容还存在问题

我们接着引入clearButton.js与clearButton.css,如下:

javascript 复制代码
import "./clearButton.css";

const el = document.createElement("button");
el.innerHTML = "Clear";
el.classList.add("button");
el.onclick = function () {
  alert("Clear clicked");
};

document.body.appendChild(el);
css 复制代码
.button {
  background-color: red;
}

index.js与index.html如下:

javascript 复制代码
import _ from "lodash";
import "./style.css";
import "./clearButton";

document.getElementById("button1").addEventListener("click", function () {
  console.log("-----------");
  const el = document.getElementById("header");
  el.innerHTML = "Hey i have updated the code !";

  const listItems = ["Apple", "orange", "Banana"];
  const ul = document.getElementById("shoppingList");
  _.forEach(listItems, function (item) {
    const tempEl = document.createElement("li");
    tempEl.innerHTML = item;
    ul.appendChild(tempEl);
  });
});
html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1 id="header">Hey this is my first webpack application !!</h1>
    <ul id="shoppingList"></ul>
    <button id="button1" class="button">Click me</button>
  </body>
  <script src="/dist/bundle.js"></script>
</html>

会存在以下问题

后面.button覆盖了前面的 !

要解决这个问题修改webpack.config.js, 在 css-loader 中启用了 modules: true,这会将 CSS 文件中的类名局部化。如下:

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader", options: { modules: true } },
        ],
      },
    ],
  },
};

如此类名将会发生变化

但是这样仍然存在问题------直接import "xxx".css将会找不到类名。

需要用 这种方式导入css,

javascript 复制代码
import { button } from "./index.css";
javascript 复制代码
import { button } from "./clearButton.css";

并且以此种方式对元素进行添加。

javascript 复制代码
btn1.classList.add([button]);
javascript 复制代码
el.classList.add([button]);

另外,还能将css类名定义为全局类名,保持其原有的名称

css 复制代码
:global(.button) {
  background: yellow;
}

img-loader

webpack.config.js中设置如下,在 Webpack 中,type: "asset/resource" 是一种用于处理静态资源(如图片、字体等)的配置方式。如下所示:

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    assetModuleFilename: "images/[hash][ext]",
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.(css)$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader", options: { modules: true } },
        ],
      },
      {
        test: /.(png|jpeg|gif|svg)$/,
        type: "asset/resource",
      },
    ],
  },
};

图片生成如下:

在代码中,导入这些文件时会返回文件的 URL。

javascript 复制代码
import logo from "./assets/webpack_logo.png";
javascript 复制代码
logoEl.src = logo;

补充:

1.assetModuleFilename:资源文件输出路径
  • 作用

    全局定义通过资源模块(Asset Modules)处理的文件(如图片、字体、视频等)的输出路径和文件名格式。

  • 配置位置

    位于 output 配置对象中。

路径格式说明
  • [hash]: 文件内容的哈希值(避免缓存问题)

  • [ext]: 原始文件扩展名(如 .png

2.clean:清理输出目录
  • 作用

    在每次构建前自动清理 output.path 目录(默认是 dist),删除旧文件,避免残留文件干扰。

  • 配置位置

    直接作为顶级配置项。

font-loader

webpack.config.js配置如下:

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    assetModuleFilename: "images/[hash][ext]",
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.(css)$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader", options: { modules: true } },
        ],
      },
      {
        test: /.(png|jpeg|gif|svg)$/,
        type: "asset/resource",
      },
      {
        test: /.(ttf|woff|woff2)$/,
        type: "asset/resource",
      },
    ],
  },
};

其中字体文件可以放置于asset/font目录下

引入字体文件

javascript 复制代码
import "./assets/fonts/Redressed-Regular.ttf";

这样就可以使用该字体了

css 复制代码
.header {
  text-decoration: underline;
  color: blue;
  font-family: 'Redressed', cursive;
}

其余loader可在官网查看!

plugin

multiple entry

在 Webpack 中,多入口允许你定义多个入口文件,Webpack 会分别处理这些入口,并为每个入口生成独立的打包文件。

javascript 复制代码
module.exports = {
  entry: {
    index: "./src/index.js",
    product: "./src/products.js",
  },
  output: {
    filename: "[name].bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
}
1. 多入口 (entry 对象)
  • 作用:允许将代码拆分为多个独立的入口文件,每个入口生成一个独立的依赖关系图和打包结果。

  • 适用场景

    • 多页面应用(MPA):每个页面有独立的入口和资源。

    • 按功能拆分代码:如管理后台和用户端分离。

2. 输出占位符 [name]
  • 动态替换[name] 会被替换为入口对象的键名(如 indexproduct)。

  • 生成的文件

    • dist/index.bundle.js

    • dist/product.bundle.js

有问题:现在还需再html中手动链接bundle.js:

Plugin有什么作用

增强webpack

HTML WebpackPlugin

HtmlWebpackPlugin 是 Webpack 生态中一个核心插件,用于 自动化生成 HTML 文件自动注入打包后的 JavaScript/CSS 资源路径

核心功能

  1. 自动生成 HTML 文件

    基于模板(或默认模板)生成 HTML,自动插入 <script><link> 标签。

  2. 多入口适配

    为每个入口生成独立的 HTML 文件,并精准注入对应的资源。

  3. 资源路径管理

    自动处理带哈希的文件名(如 bundle.[contenthash].js),避免缓存问题。

  4. HTML 优化

    支持压缩 HTML、移除注释、排序属性等优化操作。

基础用法

先下载插件

javascript 复制代码
npm install --save-dev html-webpack-plugin

引入插件

javascript 复制代码
const htmlWebpackPlugin = require("html-webpack-plugin");

基本配置

javascript 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
};

高级配置

多页面应用

javascript 复制代码
module.exports = {
  entry: {
    index: './src/index.js',
    product: './src/product.js'
  },
  plugins: [
    // 首页
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      chunks: ['index']  // 只注入 index 入口的 JS
    }),
    // 商品页
    new HtmlWebpackPlugin({
      template: './src/product.html',
      filename: 'product.html',
      chunks: ['product']  // 只注入 product 入口的 JS
    })
  ]
};
  • template : 用于 指定生成 HTML 文件的模板
  • chunks : 用于 控制哪些 chunk 会被注入到生成的 HTML 文件中
  • filename : 指定生成的 HTML 文件名。

产物如下所示:

这样还存在问题:

css和其他资源文件都不在生成的dist中。 我们当然可以手动的移动这些文件到dist目录下,但是我们也可以配置服务器热更新

首先安装

javascript 复制代码
npm i --save-dev webpack-dev-server

进行配置

javascript 复制代码
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    // 确保资源文件路径正确(可选)
    assetModuleFilename: "assets/[hash][ext][query]",
  },
  module: {
    rules: [
      // 处理 CSS 文件
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"], // 顺序从右到左执行
      },
      // 处理图片、字体等资源文件
      {
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/,
        type: "asset/resource", // Webpack 5+ 原生资源模块
        // 或使用 file-loader(Webpack 4)
        // use: "file-loader",
      },
    ],
  },
  // 配置开发服务器(热更新)
  devServer: {
    static: {
      directory: path.join(__dirname, "dist"), // 服务 dist 目录
    },
    hot: true, // 启用热更新
    open: true, // 自动打开浏览器
  },
};

在node脚本中进行配置

javascript 复制代码
  "scripts": {
    "build": "webpack --config webpack.config.js --mode development",
    "dev": "webpack serve --mode development --open"
  },

代码拆分

1. 提取公共代码(SplitChunksPlugin)

javascript 复制代码
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all', // 提取所有类型的 chunk(包括异步和同步)
      minSize: 20000, // 文件大于 20KB 才提取
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/, // 提取 node_modules 中的代码
          name: 'vendors', // 输出文件名
          priority: 10 // 优先级
        },
        default: {
          minChunks: 2, // 至少被引用 2 次才提取
          name: 'common',
          priority: 5
        }
      }
    }
  }
};

生成的文件

2. 动态导入(Dynamic Imports)

使用 import() 语法动态加载模块,Webpack 会自动将其拆分为单独的 chunk,它不会在初始加载时立即请求模块,而是延迟到实际需要时才加载。其饭返回一个promise:

javascript 复制代码
// 动态加载模块
button.addEventListener('click', () => {
  import('./module.js').then(module => {
    module.default();
  });
});

生成的文件

自定义 chunk 名称

使用 webpackChunkName 注释:

javascript 复制代码
import(/* webpackChunkName: "my-chunk" */ './module.js');

这段代码是 Webpack 的动态导入语法 ,结合了 魔法注释(Magic Comments) ,用于实现 代码拆分(Code Splitting) 。它的核心作用是将 module.js 文件单独打包成一个独立的代码块(chunk),并赋予其一个自定义名称 my-chunk

魔法注释:

应用场景 :

在用户交互时加载特定组件:

javascript 复制代码
button.addEventListener('click', () => {
  import('./Modal.js').then(module => {
    const Modal = module.default;
    Modal.show();
  });
});

路由懒加载:

在单页面应用(SPA)中,按需加载路由组件:

javascript 复制代码
const Home = () => import(/* webpackChunkName: "home" */ './Home.vue');
const About = () => import(/* webpackChunkName: "about" */ './About.vue');

为bundle添加hash

在 Webpack 中,为打包后的文件(如 JavaScript、CSS、图片等)添加 哈希值(Hash) 是一种常见的优化策略。

1. 哈希类型

Webpack 支持以下几种哈希类型:

2. 配置哈希文件名

webpack.config.js 中,通过 output.filenameoutput.chunkFilename 配置哈希文件名。

javascript 复制代码
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].[contenthash].js', // 入口文件使用 contenthash
    chunkFilename: '[name].[contenthash].js', // 动态导入的 chunk 使用 contenthash
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/[name].[contenthash][ext]', // 图片文件使用 contenthash
        },
      },
    ],
  },
};

3. 生成的文件结构

4. 哈希值的稳定性

  • [hash]:每次构建都会变化,即使文件内容没有变化。

  • [chunkhash]:只有 chunk 内容变化时才会变化。

  • [contenthash]:只有文件内容变化时才会变化。

推荐使用 [contenthash],因为它更精确地反映了文件内容的变化。

从js中提取css

将CSS从JavaScript中提取出来并单独作为CSS文件,可以对浏览器加载HTML带来以下好处:

  • 缓存和性能改善

    • 当HTML、CSS和JavaScript分离时,浏览器可以缓存CSS文件,从而在访问其他页面时减少加载时间,提高性能。
  • 渲染速度提升

    • CSS文件是渲染阻塞资源,浏览器必须下载并解析CSS后才能渲染页面。

    • 通过提取关键CSS(critical CSS)并内联到HTML头部,可以减少初始渲染时间,特别是在网络条件较差的情况下3

1. 核心思路

  1. 提取 CSS :将 CSS 从 JavaScript 中分离,生成独立的 .css 文件。

  2. 自动注入 :在 HTML 中自动插入 <link> 标签引用生成的 CSS 文件。

2. 安装依赖

复制代码
npm install --save-dev mini-css-extract-plugin html-webpack-plugin

3. 配置 Webpack

webpack.config.js 中配置以下内容:

javascript 复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    clean: true, // 自动清理 dist 目录
  },
  module: {
    rules: [
      // 处理 CSS 文件
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader, // 提取 CSS 到独立文件
          'css-loader', // 解析 CSS 语法
        ],
      },
      // 处理图片、字体等资源文件(可选)
      {
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource', // Webpack 5+ 原生资源模块
        generator: {
          filename: 'assets/[name].[contenthash][ext]', // 资源文件输出路径
        },
      },
    ],
  },
  plugins: [
    // 提取 CSS 到独立文件
    new MiniCssExtractPlugin({
      filename: 'styles.[contenthash].css', // 输出的 CSS 文件名(带哈希)
    }),
    // 自动生成 HTML 并注入 CSS/JS
    new HtmlWebpackPlugin({
      template: './src/index.html', // HTML 模板文件
    }),
  ],
};

4. 项目结构示例

src/index.js
javascript 复制代码
import './styles.css'; // 导入 CSS 文件
src/styles.css
css 复制代码
body {
  background: #f0f0f0;
  font-family: Arial;
}
src/index.html
html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My App</title>
    <!-- 不需要手动写 <link>,HtmlWebpackPlugin 会自动注入 -->
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

5. 构建结果

运行 npm run build 后,生成的 dist 目录如下:

生成的 dist/index.html:
html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My App</title>
    <link href="styles.5a6b7c8d.css" rel="stylesheet"> <!-- 自动注入 CSS -->
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.3f9a8b7e.js"></script> <!-- 自动注入 JS -->
  </body>
</html>

Shimming

Webpack Shimming 是一种在 Webpack 中处理全局依赖或模块兼容性问题的技术。它的核心作用是为代码提供缺失的依赖项,或者修改模块的行为,使其能够在 Webpack 构建的环境中正常运行。

为什么需要 Shimming?

  1. 处理全局变量 :某些库依赖全局变量(如 jQuery$),但 Webpack 默认不会将这些变量暴露给模块。

  2. 兼容旧代码:一些老旧的库可能不符合模块化规范(如 CommonJS、ES Module),需要手动处理。

  3. 提供缺失的依赖:某些模块可能依赖特定的全局变量或模块,但这些依赖在 Webpack 中不存在。

Shimming 的实现方式

Webpack 提供了多种方式来实现 Shimming:

1. 使用 ProvidePlugin

ProvidePlugin 是 Webpack 内置的插件,用于自动加载模块,并将其注入到每个模块中。

示例:自动加载 jQuery

假设项目中使用了 jQuery,但不想在每个模块中手动 import $ from 'jquery',可以通过 ProvidePlugin 自动注入 $jQuery

javascript 复制代码
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery', // 当模块中使用 $ 时,自动加载 jquery
      jQuery: 'jquery', // 当模块中使用 jQuery 时,自动加载 jquery
    }),
  ],
};

效果

  • 在任何模块中使用 $jQuery 时,Webpack 会自动引入 jquery 模块。

  • 例如:

javascript 复制代码
// 不需要手动 import $ from 'jquery';
$(document).ready(() => {
  console.log('jQuery is ready!');
});

2.使用 externals

externals 是 Webpack 的一个配置选项,用于将某些依赖项排除在打包之外。它的核心作用是告诉 Webpack:"这些依赖项不需要打包到最终的输出文件中,因为它们已经在运行环境中存在了。"

1) 使用 CDN 加载库

在 HTML 中引入 jQuery

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My App</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

在 Webpack 中配置 externals

javascript 复制代码
module.exports = {
  externals: {
    jquery: 'jQuery', // 将 jquery 映射为全局变量 jQuery
  },
};

在代码中使用 jQuery

javascript 复制代码
import $ from 'jquery'; // 从全局变量中获取 jQuery

$(document).ready(() => {
  console.log('jQuery is ready!');
});
效果
  • Webpack 不会将 jQuery 打包到 bundle.js 中。

  • 代码中通过 import $ from 'jquery' 获取全局变量 jQuery

2) 排除第三方库
javascript 复制代码
module.exports = {
  externals: {
    react: 'React', // 排除 React
    'react-dom': 'ReactDOM', // 排除 ReactDOM
    lodash: '_', // 排除 Lodash
  },
};

**3.**resolve.alias

resolve.alias 是 Webpack 的一个配置选项,用于为模块路径创建别名(Alias)。它的核心作用是简化模块的导入路径,避免在代码中编写冗长的相对路径,同时也可以解决模块路径冲突的问题。

基本配置

webpack.config.js 中配置 resolve.alias

javascript 复制代码
const path = require('path');

module.exports = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // 将 @ 映射为 src 目录
      components: path.resolve(__dirname, 'src/components'), // 将 components 映射为 src/components 目录
    },
  },
};
效果
  • 在代码中可以使用别名代替完整路径:
javascript 复制代码
import MyComponent from '@/components/MyComponent'; // 相当于 src/components/MyComponent
import Button from 'components/Button'; // 相当于 src/components/Button

常见使用场景

1. 简化路径

将常用的目录映射为简短的别名:

javascript 复制代码
resolve: {
  alias: {
    '@': path.resolve(__dirname, 'src'),
    components: path.resolve(__dirname, 'src/components'),
    utils: path.resolve(__dirname, 'src/utils'),
  },
}
2. 解决模块冲突

如果项目中安装了多个版本的库(如 lodashlodash-es),可以通过别名指定使用哪个版本:

javascript 复制代码
resolve: {
  alias: {
    lodash: path.resolve(__dirname, 'node_modules/lodash-es'), // 强制使用 lodash-es
  },
}
3. 替换模块

如果某个模块需要替换为自定义实现,可以通过别名指定:

javascript 复制代码
resolve: {
  alias: {
    'original-module': path.resolve(__dirname, 'src/custom-module'), // 替换为自定义模块
  },
}

结合 TypeScript 使用

如果项目使用 TypeScript,需要在 tsconfig.json 中配置路径映射,以确保 TypeScript 能够正确解析别名。

tsconfig.json 配置
javascript 复制代码
{
  "compilerOptions": {
    "baseUrl": ".", // 基础路径
    "paths": {
      "@/*": ["src/*"], // 将 @ 映射为 src 目录
      "components/*": ["src/components/*"] // 将 components 映射为 src/components 目录
    }
  }
}
Webpack 配置
javascript 复制代码
{
  "compilerOptions": {
    "baseUrl": ".", // 基础路径
    "paths": {
      "@/*": ["src/*"], // 将 @ 映射为 src 目录
      "components/*": ["src/components/*"] // 将 components 映射为 src/components 目录
    }
  }
}

Tree shaking

Tree shaking(摇树优化) 是前端构建工具(如 Webpack、Rollup)中的一种优化技术,用于在打包时 移除未被使用的代码(Dead Code),比如不用。它的名字来源于"摇晃一棵树,让枯叶(无用代码)落下"的比喻。

Tree shaking 生效的条件

配置方式

1. 配置生产模式

javascript 复制代码
// webpack.config.js
module.exports = {
  mode: 'production', // 生产模式自动启用 Tree shaking 和代码压缩
};
2. 标记无副作用的模块

package.json 中声明:

javascript 复制代码
{
  "sideEffects": false // 所有文件均无副作用(默认值)
}

Tree shaking 的局限性

  1. 动态导入无法优化

    动态导入(如 import('module'))的代码可能无法被静态分析。

  2. 第三方库的兼容性

    未使用 ES6 模块的库(如 Lodash)需配合插件(如 babel-plugin-lodash)或按需引入。

  3. 副作用代码需手动标记

    未正确标记副作用的代码可能被误删,导致运行时错误。

Production vs Development Build

webpack配置文件拆分

在大型项目中,Webpack 配置文件可能会变得非常复杂和冗长。为了提升可维护性和灵活性,通常会将 Webpack 配置文件拆分为多个文件,分别用于不同的环境(如开发环境、生产环境)。

webpack-merge:用于合并多个配置文件。

webpack.common.js(公共配置)
javascript 复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, '../dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        type: 'asset/resource',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
};
webpack.dev.js(开发环境配置)
javascript 复制代码
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    static: './dist',
    hot: true,
  },
});
webpack.prod.js(生产环境配置)
javascript 复制代码
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
});
相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax