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/[email protected]/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',
    },
  },
});
相关推荐
郑祎亦6 分钟前
CSS 实现 文本垂直居中
前端·css
zhongshizhi919 分钟前
CSS元素层叠顺序规则
前端·css
申朝先生1 小时前
用CSS画一条0.5px的线
前端·javascript·css
雪碧聊技术2 小时前
element-plus中Autocomplete自动补全输入框组件的使用
前端·javascript·vue.js·自动补全输入框·autocomplete
浪遏2 小时前
当你向面试官朗诵单例模式时 ,ta说talk is cheep , show me the code🤡
前端·设计模式·面试
六个点3 小时前
关于vue的面试考点总结🤯
前端·vue.js·面试
浪遏4 小时前
今晚揭开单例模式的面纱~
前端·设计模式·面试
驯龙高手_追风4 小时前
谷歌Chrome或微软Edge浏览器修改网页任意内容
前端·chrome·edge
luckyext4 小时前
Postman发送GET请求示例及注意事项
前端·后端·物联网·测试工具·小程序·c#·postman