webpack学习笔记一 使用webpack构建应用

117 阅读9分钟

步骤1 创建package.json 文件

  1. 打开命令行工具,进入创建项目的目录
  2. 运行以下命令,初始化一个新的 package.json文件

npm init -y

这会在当前目录下生成一个默认的 package.json文件

Why?

  • 项目管理: package.json 是 Node.js 项目的配置文件,用于定义项目的依赖、脚本、作者等信息。通过运行 npm init 命令,我们可以快速创建一个初始配置。
  • 依赖管理: 在构建现代 Web 应用时,我们通常会使用许多第三方库和工具。package.json 中的 dependenciesdevDependencies 部分用于管理这些依赖项。
  • 脚本定义: 我们可以在 package.json 中定义一些脚本,比如启动应用、构建代码等。这些脚本能够方便地在命令行中运行。

步骤2 安装 Webpack和Webpack CLI

  1. 在命令行中运行以下命令,安装Webpack 和 WebpackCLI

npm install --save-dev webpack webpack-cli

Why?

  • Webpack: Webpack 是一个模块打包工具,它可以将项目中的多个文件(JavaScript、CSS、图片等)打包成一个或多个最终的静态资源文件,以优化加载性能。
  • Webpack CLI: Webpack CLI 是 Webpack 的命令行工具,通过它我们可以在命令行中运行 Webpack

步骤3 创建Webpack配置文件

  1. 在项目根目录下创建一个名为 webpack.config.js的文件
  2. webpack.config.js中,输入以下基本的配置:
const path = require('path');
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

Why?

  • entry 指定 Webpack 的入口文件,即项目的主 JavaScript 文件。
  • output 指定 Webpack 打包后的输出配置。filename 是输出的文件名,path 是输出文件的存放路径。
  • pathpath.resolve 使用 Node.js 内置的 path 模块,确保我们能够在不同操作系统上正确地构建文件路径。

步骤4: 创建实力文件

  1. 在项目根目录下创建一个名为src的文件夹
  2. src文件夹中创建一个名为index.js的文件,这将是我们的主 JavaScript文件
  3. index.js 中输入一些简单的代码
console.log('Hello, Webpack!');

步骤5:运行Webpack。

  1. 在命令行中运行以下命令,使用webpack进行打包
npx webpack

步骤 6: 查看输出

  1. 打开 dist/bundle.js 文件,查看其中的内容。你会注意到,Webpack 已经将 src/index.js 中的代码打包成一个单独的文件。

  2. 在命令行中运行以下命令,启动一个简单的本地服务器(这需要安装 live-server,如果没有安装,可以运行 npm install -g live-server):

    bashCopy code
    live-server
    
  3. 打开浏览器,访问 http://localhost:8080。打开浏览器的控制台,你应该看到输出:'Hello, Webpack!'。

步骤 7: 引入样式加载器

  1. 安装 style-loadercss-loader,用于处理样式文件:

    bashCopy code
    npm install --save-dev style-loader css-loader
    
  2. webpack.config.js 中,修改配置以支持样式加载器:

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

为什么这么做?

  • style-loader 将样式通过 <style> 标签插入到 HTML 中。
  • css-loader 解析 CSS 文件,并处理 @importurl() 等语法。
  • module.rules 在 Webpack 配置中,module.rules 是一个数组,用于定义处理不同类型模块的规则。
  • test 正则表达式,匹配需要使用这些规则的文件。
  • use 指定使用的加载器,按照数组顺序执行。

步骤 8: 创建样式文件

  1. src 文件夹中创建一个名为 styles.css 的样式文件。

  2. styles.css 中输入一些样式:

    cssCopy code
    /* styles.css */
    body {
      background-color: #f0f0f0;
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 20px;
      text-align: center;
    }
    
    h1 {
      color: #333;
    }
    

步骤 9: 引入样式

src/index.js 中引入样式文件:

javascriptCopy code
// src/index.js
import './styles.css';

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

步骤 10: 重新运行 Webpack

在命令行中运行以下命令,重新运行 Webpack:

bashCopy code
npx webpack

为什么这么做?

  • 通过引入样式加载器,我们可以在 JavaScript 文件中引入样式文件,并确保样式文件得以加载和应用。
  • 使用 style-loadercss-loader 配合,我们可以处理样式文件中的样式,并将其插入到 HTML 中。
  • 这样我们可以在项目中愉快地使用 CSS,并且 Webpack 会帮助我们处理这些样式。

你可以通过查看 dist/bundle.js 文件,确认样式文件已经成功地被打包进去。如果一切正常,你的页面背景应该变成了灰色。

步骤 11: 引入图片加载器

  1. 安装 file-loader,用于处理和加载图片文件:

    bashCopy code
    npm install --save-dev file-loader
    
  2. webpack.config.js 中,修改配置以支持图片加载器:

    javascriptCopy code
    const path = require('path');
    
    module.exports = {
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: ['style-loader', 'css-loader'],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
        ],
      },
    };
    

为什么这么做?

  • file-loader 处理文件,主要用于加载图像、字体等文件。
  • test 正则表达式,匹配需要使用这些规则的文件。
  • type: 'asset/resource' 这是 Webpack 5 新增的资源模块类型,用于处理资源文件,包括图像文件。这会将图片文件复制到输出目录,并返回文件路径。

步骤 12: 创建图像文件

  1. src 文件夹中创建一个名为 webpack-logo.png 的图像文件。

    Webpack Logo

步骤 13: 在样式中使用图像

styles.css 文件中,引入图像:

cssCopy code
/* styles.css */
body {
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 20px;
  text-align: center;
}

h1 {
  color: #333;
}

.logo {
  max-width: 100%;
  height: auto;
}

步骤 14: 在 HTML 中使用图像

index.js 文件中,将图像插入到 HTML 中:

javascriptCopy code
// src/index.js
import './styles.css';

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

const logoImg = new Image();
logoImg.src = require('./webpack-logo.png');
logoImg.classList.add('logo');

document.body.appendChild(logoImg);

步骤 15: 重新运行 Webpack

在命令行中运行以下命令,重新运行 Webpack:

bashCopy code
npx webpack

为什么这么做?

  • 通过引入文件加载器,我们可以在样式和 JavaScript 文件中引入和使用图像。
  • 使用 file-loader 处理图像文件,确保它们被正确地复制到输出目录。
  • 使用资源模块类型 asset/resource,Webpack 5 会自动处理图像文件,并返回文件路径。
  • 我们在样式中使用了一个图像,并在 JavaScript 中动态插入到 HTML 中。
  • 运行 Webpack 后,图像应该被正确地加载并显示在页面上。

步骤 16: 安装 Babel 相关工具

  1. 安装 Babel 相关的依赖:

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

为什么这么做?

  • @babel/core Babel 的核心模块,提供了 Babel 转译器的功能。
  • @babel/preset-env Babel 预设,根据目标环境自动选择需要的插件。
  • babel-loader Webpack 加载器,用于在 Webpack 中集成 Babel。

步骤 17: 配置 Babel

  1. 在项目根目录下创建一个名为 .babelrc 的 Babel 配置文件:

    jsonCopy code
    {
      "presets": ["@babel/preset-env"]
    }
    
  2. webpack.config.js 中,修改配置以支持 Babel:

    javascriptCopy code
    const path = require('path');
    
    module.exports = {
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: ['style-loader', 'css-loader'],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
            },
          },
        ],
      },
    };
    

为什么这么做?

  • 我们安装了 Babel 相关的工具,以便支持在项目中使用新的 JavaScript 特性。
  • .babelrc 文件中,我们配置了 Babel 使用 @babel/preset-env 预设,它会根据目标环境自动选择需要的插件。
  • 我们在 Webpack 配置中添加了一个新的规则,使用 babel-loader 处理 JavaScript 文件。这确保了在打包时,我们的 JavaScript 代码会经过 Babel 转译。

步骤 18: 更新 JavaScript 代码

  1. 更新 src/index.js 中的 JavaScript 代码,使用一些新的特性:

    javascriptCopy code
    // src/index.js
    import './styles.css';
    
    const greeting = () => {
      console.log('Hello, Webpack and Babel!');
    };
    
    greeting();
    
    const logoImg = new Image();
    logoImg.src = require('./webpack-logo.png');
    logoImg.classList.add('logo');
    
    document.body.appendChild(logoImg);
    

步骤 19: 重新运行 Webpack

  1. 在命令行中运行以下命令,重新运行 Webpack:

    npx webpack
    

为什么这么做?

  • 我们更新了 JavaScript 代码,使用了箭头函数和模块导入等新特性。
  • 通过配置 Babel,我们确保这些新特性能够在旧版浏览器中正确运行。
  • 运行 Webpack 后,新的 JavaScript 代码应该被成功地转译,并打包到 dist/bundle.js 中。

步骤 20: 安装开发服务器

  1. 安装 webpack-dev-server,用于提供一个简单的开发服务器:

    bashCopy code
    npm install --save-dev webpack-dev-server
    

步骤 21: 配置开发服务器

  1. package.json 文件中,添加一个脚本命令来启动开发服务器:

    jsonCopy code
    "scripts": {
      "start": "webpack-dev-server --open"
    }
    

步骤 22: 运行开发服务器

  1. 在命令行中运行以下命令,启动开发服务器:

    bashCopy code
    npm start
    

步骤 23: 测试开发服务器

  1. src/index.js 中进行一些修改,保存文件后观察浏览器是否自动刷新。

    javascriptCopy code
    // src/index.js
    import './styles.css';
    
    const greeting = () => {
      console.log('Hello, Webpack, Babel, and Dev Server!');
    };
    
    greeting();
    
    const logoImg = new Image();
    logoImg.src = require('./webpack-logo.png');
    logoImg.classList.add('logo');
    
    document.body.appendChild(logoImg);
    

    步骤 24: 添加生产构建

在实际项目中,通常需要生成用于生产环境的优化过的代码。我们将使用mini-css-extract-plugin插件来提取样式文件,并使用terser-webpack-plugin插件来优化JavaScript代码。

  1. 安装插件:

    npm install --save-dev mini-css-extract-plugin terser-webpack-plugin
    
  2. 更新 webpack.config.js 文件:

    javascriptCopy code
    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      mode: 'production',
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
            },
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    
  3. 更新 package.json 中的脚本:

    "scripts": {
      "start": "webpack-dev-server --open",
      "build": "webpack"
    }
    
  4. 运行生产构建:

    npm run build
    

步骤 25: 验证生产构建

  1. 查看 dist 目录中生成的文件。
  2. 打开 index.html,确保引用的文件是优化过的。

步骤 26: 添加文件加载器

在实际项目中,我们可能会遇到其他类型的文件(如字体、数据文件等)。为了处理这些文件,我们需要添加相应的加载器。

  1. 安装文件加载器:

    npm install --save-dev file-loader
    
  2. 更新 webpack.config.js 文件:

    javascriptCopy code
    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      mode: 'production',
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              process.env.NODE_ENV === 'production'
                ? MiniCssExtractPlugin.loader
                : 'style-loader',
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    
  3. 安装额外的加载器:

    npm install --save-dev csv-loader xml-loader
    
  4. 创建一个样式文件 styles.css,并在其中引入字体:

    body {
      font-family: 'Open Sans', sans-serif;
    }
    
  5. 更新 src/index.js 文件,引入样式:

    javascriptCopy code
    // src/index.js
    import './styles.css';
    
    const greeting = () => {
      console.log('Hello, Webpack, Babel, and Dev Server!');
    };
    
    greeting();
    
    const logoImg = new Image();
    logoImg.src = require('./webpack-logo.png');
    logoImg.classList.add('logo');
    
    document.body.appendChild(logoImg);
    

步骤 27: 验证文件加载器

  1. src 目录下创建一个字体文件(如 font.woff)。

  2. styles.css 中引入该字体文件:

    body {
      font-family: 'Open Sans', sans-serif;
      src: url('./font.woff') format('woff');
    }
    
  3. 运行开发服务器:

    npm start
    
  4. 在浏览器中查看效果,确保字体加载成功。

步骤 28: 添加 Source Map

在开发中,如果出现错误,希望能够在源代码而不是转换后的代码中进行调试。为了实现这一点,我们需要添加 source map。

  1. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      mode: 'development', // 切换到开发模式
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      devtool: 'inline-source-map', // 添加 source map 配置
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              process.env.NODE_ENV === 'production'
                ? MiniCssExtractPlugin.loader
                : 'style-loader',
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    

为什么这么做?

  • devtool: 'inline-source-map' 配置添加了 source map,它将以 Data URL 的方式嵌入到生成的 bundle 文件中。这样,当在浏览器中运行代码时,如果发生错误,可以精确定位到源代码的位置进行调试。
  1. 运行开发服务器:

    npm start
    
  2. 在浏览器中打开开发者工具,检查 SourcesDebugger 标签,查看是否能够调试源代码而不是转换后的代码。

步骤 29: 添加 CleanWebpackPlugin 插件

  1. 安装 clean-webpack-plugin 插件:

    npm install --save-dev clean-webpack-plugin
    
  2. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    
    module.exports = {
      mode: 'production',
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              process.env.NODE_ENV === 'production'
                ? MiniCssExtractPlugin.loader
                : 'style-loader',
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
        new CleanWebpackPlugin(), // 添加 CleanWebpackPlugin 插件
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    

为什么这么做?

  • CleanWebpackPlugin 插件用于在每次构建前清理指定目录。这样可以确保每次构建都是从一个干净的状态开始,避免旧文件对新构建的影响。
  1. 运行生产构建:

    npm run build
    
  2. 检查 dist 目录,确保旧文件已被清理。

步骤 30: 添加 HtmlWebpackPlugin 插件

  1. 安装 html-webpack-plugin 插件:

    npm install --save-dev html-webpack-plugin
    
  2. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      mode: 'development',
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      devtool: 'inline-source-map',
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              process.env.NODE_ENV === 'production'
                ? MiniCssExtractPlugin.loader
                : 'style-loader',
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({ // 添加 HtmlWebpackPlugin 插件
          title: 'Webpack Demo', // 设置生成 HTML 文件的标题
        }),
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    

为什么这么做?

  • HtmlWebpackPlugin 插件用于自动生成一个 HTML 文件,并自动引入生成的 bundle 和样式文件。可以通过配置项来设置生成 HTML 文件的标题、模板等信息。
  1. 运行开发服务器:

    npm start
    
  2. 打开浏览器,查看生成的 HTML 文件,确保它自动引入了正确的 bundle 和样式文件。

步骤 31: 添加 Bundle 分析插件

  1. 安装 webpack-bundle-analyzer 插件:

    npm install --save-dev webpack-bundle-analyzer
    
  2. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    module.exports = {
      mode: 'production',
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.css',
        }),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          title: 'Webpack Demo',
        }),
        new BundleAnalyzerPlugin(), // 添加 Bundle 分析插件
      ],
      optimization: {
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    

为什么这么做?

  • webpack-bundle-analyzer 插件可以分析构建结果,以可视化地展示项目中各个模块的大小,帮助开发者找到优化的方向。
  1. 运行生产构建:

    npm run build
    
  2. 打开生成的报告页面,查看各个模块的大小和依赖关系。

步骤 32: 配置代码拆分和懒加载

  1. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      mode: 'development',
      entry: {
        main: './src/index.js',
        vendor: './src/vendor.js', // 添加 vendor 入口
      },
      output: {
        filename: '[name].[contenthash].js', // 使用 contenthash 避免缓存问题
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.[contenthash].css', // 使用 contenthash 避免缓存问题
        }),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          title: 'Webpack Demo',
        }),
      ],
      optimization: {
        splitChunks: {
          chunks: 'all',
        },
        minimizer: [
          new TerserPlugin(),
        ],
      },
    };
    
  2. 创建一个新的入口文件 src/vendor.js

    // src/vendor.js
    import 'lodash';
    
    console.log('Vendor code');
    
  3. 更新 src/index.js 文件,引入懒加载:

    // src/index.js
    import _ from 'lodash';
    
    const greeting = () => {
      console.log('Hello, Webpack, Babel, and Dev Server!');
    };
    
    greeting();
    
    const logoImg = new Image();
    logoImg.src = require('./webpack-logo.png');
    logoImg.classList.add('logo');
    
    document.body.appendChild(logoImg);
    
    // 懒加载
    document.addEventListener('click', () => {
      import(/* webpackChunkName: "lazy-loaded" */ './lazy-loaded.js')
        .then((lazyLoadedModule) => {
          lazyLoadedModule.default();
        })
        .catch((error) => {
          console.error('Lazy loading failed', error);
        });
    });
    
  4. 创建一个新的懒加载文件 src/lazy-loaded.js

    // src/lazy-loaded.js
    const lazyLoaded = () => {
      console.log('Lazy-loaded module');
    };
    
    export default lazyLoaded;
    

为什么这么做?

  • 通过配置 splitChunks,Webpack 将会自动进行代码拆分,将公共模块提取到单独的文件,避免重复加载。
  • 使用 import(/* webpackChunkName: "lazy-loaded" */ './lazy-loaded.js') 语法,实现了懒加载。这会将 lazy-loaded.js 单独打包成一个 chunk,并在需要时动态加载。
  • 使用 [name][contenthash] 等占位符,确保文件名中包含唯一的哈希值,避免缓存问题。
  1. 运行开发服务器:

    npm start
    
  2. 打开浏览器,点击页面,查看控制台输出,确认懒加载模块是否成功加载。

步骤 33: 配置热模块替换(HMR)

  1. 更新 webpack.config.js 文件:

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      mode: 'development',
      entry: {
        main: './src/index.js',
        vendor: './src/vendor.js',
      },
      output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
          },
          {
            test: /.(csv|tsv)$/i,
            use: ['csv-loader'],
          },
          {
            test: /.xml$/i,
            use: ['xml-loader'],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'styles.[contenthash].css',
        }),
        new HtmlWebpackPlugin({
          title: 'Webpack Demo',
        }),
      ],
      optimization: {
        splitChunks: {
          chunks: 'all',
        },
      },
      devServer: {
        contentBase: './dist',
        hot: true, // 开启 HMR
      },
    };
    
  2. src/index.js 文件中使用 HMR:

    // src/index.js
    import _ from 'lodash';
    
    const greeting = () => {
      console.log('Hello, Webpack, Babel, and Dev Server!');
    };
    
    greeting();
    
    const logoImg = new Image();
    logoImg.src = require('./webpack-logo.png');
    logoImg.classList.add('logo');
    
    document.body.appendChild(logoImg);
    
    // 懒加载
    document.addEventListener('click', () => {
      import(/* webpackChunkName: "lazy-loaded" */ './lazy-loaded.js')
        .then((lazyLoadedModule) => {
          lazyLoadedModule.default();
        })
        .catch((error) => {
          console.error('Lazy loading failed', error);
        });
    });
    
    // 热模块替换
    if (module.hot) {
      module.hot.accept('./lazy-loaded.js', () => {
        console.log('Lazy-loaded module updated');
      });
    }
    

为什么这么做?

  • 在配置文件中设置 devServer.hot: true 开启 HMR 功能。
  • 在入口文件中使用 if (module.hot) 来检查模块是否支持 HMR。
  • 使用 module.hot.accept 监听懒加载模块的变化,实现懒加载模块的热更新。
  1. 运行开发服务器:

    npm start
    
  2. 修改 lazy-loaded.js 文件并保存,观察控制台输出,确认热更新是否生效。

总结

  1. 初始化项目: 创建项目文件夹,运行 npm init 初始化 package.json
  2. 安装 Webpack 和相关工具: 运行 npm install --save-dev webpack webpack-cli 安装 Webpack 及其 CLI。
  3. 创建基本文件结构: 在项目根目录下创建 src 文件夹,并添加 index.js 文件作为入口文件。
  4. 配置基本的Webpack配置文件: 创建 webpack.config.js 文件,并配置基本的入口、输出和加载器规则。
  5. 添加 Babel 支持: 安装 Babel 相关依赖,配置 Babel 的 .babelrc 文件,以支持 ES6+ 语法。
  6. 配置开发服务器: 安装 webpack-dev-server,配置 webpack.config.js 中的 devServer 选项。
  7. 添加样式加载器: 安装 style-loadercss-loader,并在 webpack.config.js 中配置。
  8. 添加生产环境构建:webpack.config.js 中添加生产环境的配置,并使用 --mode production 进行构建。
  9. 添加 MiniCssExtractPlugin: 安装并配置 mini-css-extract-plugin,以提取样式到单独的文件。
  10. 添加 HtmlWebpackPlugin: 安装并配置 html-webpack-plugin,以生成 HTML 文件并自动引入打包后的资源。

这些步骤帮助你建立了一个基本的Webpack配置,支持开发环境、生产环境,集成了 Babel、样式加载器、文件加载器,配置了开发服务器。这个基础配置可以根据具体项目的需求进行扩展和优化。