当前位置: 首页 > news >正文

Webpack基础学习-Day01

Webpack基础学习-Day01

1.1 webpack 是什么

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。

在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。

它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。

1.2 webpack 核心概念

1.2.1 Entry

入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。

在 Webpack 中,entry 属性指定了 Webpack 用来构建其内部依赖图的起点或入口点。换句话说,entry 告诉 Webpack 从哪里开始打包代码。

entry 属性的用法

entry 属性的值可以是以下几种类型:

  1. 字符串:单个入口文件。
  2. 数组:多个入口文件,这些文件的内容会被打包到一个 bundle 中。
  3. 对象:多个入口点,每个入口点会生成一个独立的 bundle。
1. 字符串类型的 entry

这是最简单的用法,指定一个单一的入口文件:

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

在这种情况下,Webpack 从 ./src/index.js 开始构建依赖图,并将所有模块打包到 bundle.js 文件中。

2. 数组类型的 entry

如果你有多个文件需要作为入口,但希望将它们打包到一个 bundle 中,可以使用数组:

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

这种情况下,index.jsanotherModule.js 会被打包到同一个 bundle.js 文件中。

3. 对象类型的 entry

对象类型的 entry 允许你定义多个独立的入口点,每个入口点会生成一个独立的 bundle:

module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},
};

在这种情况下,会生成两个独立的 bundle 文件:app.bundle.jsadmin.bundle.js[name] 是一个占位符,会被 entry 对象的键替换。

高级用法

动态入口

可以通过函数返回一个对象来动态生成入口点:

module.exports = {entry: () => {const entries = {main: './src/main.js',};if (process.env.NODE_ENV === 'development') {entries.dev = './src/dev.js';}return entries;},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},
};

这种方式允许根据环境或其他条件动态配置入口点。

使用多个入口和 SplitChunks 插件

通过配合 SplitChunksPlugin,可以将共享代码提取到一个独立的 chunk 中:

module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},optimization: {splitChunks: {chunks: 'all',},},
};

这种配置会将 app.jsadmin.js 中的共享模块提取到一个公共的 bundle 中,从而减少重复代码。

配置示例

以下是一个更完整的 Webpack 配置示例,展示了不同类型的 entry 配置和一些常见的插件配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: 'production',module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: 'babel-loader',},{test: /\.css$/,use: ['style-loader', 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',chunks: ['app'], // 仅包含 app chunk}),new HtmlWebpackPlugin({template: './src/admin-template.html',filename: 'admin.html',chunks: ['admin'], // 仅包含 admin chunk}),],optimization: {splitChunks: {chunks: 'all',},},
};

总结

entry 属性是 Webpack 配置中的一个重要部分,它定义了 Webpack 构建的入口点。通过灵活使用字符串、数组和对象类型的 entry,你可以实现不同的构建策略和优化代码拆分。结合 Webpack 的其他特性(如插件和优化选项),可以构建高效、可维护的前端项目。

1.2.2 Output

输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。

output 属性是 Webpack 配置中的一个关键部分,它定义了打包后输出文件的相关设置。通过配置 output,你可以指定打包文件的名称、路径、公共路径等。

基本配置

1. filename

filename 用于指定输出文件的名称。可以使用占位符来生成动态文件名。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js', // 输出文件名path: path.resolve(__dirname, 'dist'), // 输出路径},
};

常用的占位符包括:

  • [name]: 入口点名称
  • [id]: chunk ID
  • [hash]: 编译时的唯一 hash
  • [chunkhash]: chunk 的 hash
  • [contenthash]: 文件内容的 hash
module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].js', // 动态生成文件名path: path.resolve(__dirname, 'dist'),},
};
2. path

path 用于指定输出目录的绝对路径。通常使用 Node.js 的 path 模块来生成绝对路径。

const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'), // 使用绝对路径},
};
3. publicPath

publicPath 用于指定输出解析文件的公共 URL 地址。通常用于配置 CDN 地址或开发服务器地址。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/', // 公共路径,通常用于配置 CDN 地址},
};

高级配置

1. chunkFilename

chunkFilename 用于指定按需加载的 chunk 文件的名称模板。类似于 filename,可以使用占位符。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),chunkFilename: '[name].[contenthash].js', // 按需加载的 chunk 文件名},
};
2. assetModuleFilename

assetModuleFilename 用于指定通过资源模块(如图像、字体等)处理的文件的输出文件名模板。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),assetModuleFilename: 'assets/[name].[hash][ext]', // 资源模块文件名},
};
3. librarylibraryTarget

librarylibraryTarget 用于将你的 bundle 输出为一个库。

  • library 指定库的名称。
  • libraryTarget 指定导出库的方式(如 var, umd, commonjs2 等)。
module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),library: 'MyLibrary', // 库名称libraryTarget: 'umd', // 输出库的方式},
};

常见示例

示例 1:简单的单入口点配置
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};
示例 2:多入口点配置
const path = require('path');module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].js',path: path.resolve(__dirname, 'dist'),},
};
示例 3:配置公共路径
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: 'https://cdn.example.com/assets/', // 使用 CDN 地址},
};
示例 4:配置资源模块输出
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),assetModuleFilename: 'images/[name].[hash][ext]', // 资源模块文件名},module: {rules: [{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},
};

详细解释

  • filename:指定输出文件的名称,可以使用占位符动态生成文件名。
  • path:指定输出目录的绝对路径,通常使用 Node.js 的 path.resolve 方法。
  • publicPath:指定公共路径,通常用于配置 CDN 地址或开发服务器地址。
  • chunkFilename:指定按需加载的 chunk 文件的名称模板。
  • assetModuleFilename:指定资源模块处理的文件输出名称模板。
  • librarylibraryTarget:用于将你的 bundle 输出为一个库,指定库的名称和导出方式。

通过配置 output 属性,可以灵活地控制 Webpack 打包输出文件的名称、路径和其他相关设置,以满足各种需求。

1.2.3 Loader

Loader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自 身 只 理 解

JavaScript)

在 Webpack 中,Loader 是一种用于转换模块的机制。在 Webpack 中,一切文件都是模块,而 Loader 则用于告诉 Webpack 如何处理那些非 JavaScript 文件(例如,CSS、图片、字体、TypeScript 等)。通过使用 Loader,你可以在 importrequire 模块时预处理文件,并将它们转换为 JavaScript 模块。

使用 Loader 的步骤

  1. 安装 Loader:通过 npm 安装所需的 Loader。
  2. 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则。

常用 Loader 示例

1. 处理 CSS 文件的 Loader

安装 style-loadercss-loader

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

配置 Webpack:

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

这个配置会使用 css-loader 将 CSS 文件解析成 JavaScript 可以理解的模块,然后使用 style-loader 将 CSS 注入到 DOM 中。

2. 处理图像文件的 Loader

安装 file-loaderurl-loader

npm install file-loader url-loader --save-dev

配置 Webpack:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource', // 使用内置资源模块},],},
};

asset/resource 会将图像文件单独输出到指定目录,并返回图像的 URL。

3. 处理字体文件的 Loader

字体文件可以使用与图像文件类似的 file-loaderurl-loader,这里使用 Webpack 5 内置的资源模块:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.(woff|woff2|eot|ttf|otf)$/i,type: 'asset/resource', // 使用内置资源模块},],},
};
4. 处理 Sass 文件的 Loader

安装 sass-loadersass(Dart Sass)、style-loadercss-loader

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

配置 Webpack:

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

这个配置会使用 sass-loader 将 Sass 文件编译成 CSS,然后使用 css-loaderstyle-loader 处理 CSS。

5. 处理 Babel 的 JavaScript 文件

安装 babel-loader 和 Babel 的相关包:

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

配置 Webpack 和 Babel:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],},},},],},
};
6. 处理 TypeScript 文件

安装 ts-loader 和 TypeScript:

npm install ts-loader typescript --save-dev

配置 Webpack 和 TypeScript:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.ts',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},resolve: {extensions: ['.ts', '.js'],},module: {rules: [{test: /\.ts$/,use: 'ts-loader',exclude: /node_modules/,},],},
};

Loader 配置详解

每个 Loader 规则通常包含以下几个属性:

  • test: 一个正则表达式,匹配文件路径。
  • use: 定义使用的 loader,可以是字符串或对象,或 loader 和选项的数组。
  • exclude: 排除某些文件路径。
  • include: 仅处理某些文件路径。

例如,下面是一个更复杂的 Loader 配置示例:

module.exports = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],},},},{test: /\.css$/i,use: ['style-loader', 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},{test: /\.scss$/i,use: ['style-loader', 'css-loader', 'sass-loader'],},{test: /\.ts$/,exclude: /node_modules/,use: 'ts-loader',},{test: /\.(woff|woff2|eot|ttf|otf)$/i,type: 'asset/resource',},],},
};

总结

  • Loader 是 Webpack 用来转换模块的工具,可以将非 JavaScript 文件转换为 JavaScript 模块。
  • 安装 Loader:通过 npm 安装所需的 Loader。
  • 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则,使用 testuseexcludeinclude 等属性来配置 Loader。
  • 常见的 Loadercss-loaderstyle-loaderfile-loaderurl-loadersass-loaderbabel-loaderts-loader 等。

通过合理使用 Loader,可以让 Webpack 处理各种类型的文件,从而实现更复杂和灵活的构建过程。

1.2.4 Plugins

插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,

在 Webpack 中,插件(Plugins)用于执行更广泛的任务,比如打包优化、资源管理和环境变量注入等。插件的功能比 Loader 更强大和灵活,Loader 主要用于转换单个文件,而插件可以直接操作整个构建过程。

使用插件的基本步骤

  1. 安装插件:通过 npm 安装所需的插件。
  2. 引入插件:在 Webpack 配置文件中引入插件。
  3. 配置插件:在 Webpack 配置文件的 plugins 数组中配置插件。

常用插件及其示例

1. HtmlWebpackPlugin

HtmlWebpackPlugin 用于简化 HTML 文件的创建,以便为 Webpack 打包后的文件提供服务。它可以自动生成一个 HTML 文件,并将打包后的文件自动插入其中。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new HtmlWebpackPlugin({template: './src/template.html', // 使用的 HTML 模板文件filename: 'index.html', // 生成的 HTML 文件名}),],
};
2. CleanWebpackPlugin

CleanWebpackPlugin 在每次构建前清理输出目录,确保输出目录只包含生产文件。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new CleanWebpackPlugin(), // 默认会清理 output.path 目录],
};
3. MiniCssExtractPlugin

MiniCssExtractPlugin 用于将 CSS 提取到单独的文件中。它支持按需加载 CSS 和 SourceMaps。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.css$/i,use: [MiniCssExtractPlugin.loader, 'css-loader'],},],},plugins: [new MiniCssExtractPlugin({filename: '[name].css', // 输出的 CSS 文件名}),],
};
4. DefinePlugin

DefinePlugin 允许你在编译时创建配置的全局常量。它非常有用,可以根据不同的环境定义不同的变量值。

安装插件:

DefinePlugin 是 Webpack 内置的插件,不需要安装。

配置 Webpack:

// webpack.config.js
const path = require('path');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production'),}),],
};
5. HotModuleReplacementPlugin

HotModuleReplacementPlugin 启用模块热替换,允许在运行时更新各种模块,而无需进行完全刷新。

安装插件:

HotModuleReplacementPlugin 是 Webpack 内置的插件,不需要安装。

配置 Webpack:

// webpack.config.js
const path = require('path');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: true, // 启用热模块替换},plugins: [new webpack.HotModuleReplacementPlugin(),],
};
6. CopyWebpackPlugin

CopyWebpackPlugin 用于将单个文件或整个目录复制到构建目录中。

安装插件:

npm install copy-webpack-plugin --save-dev

配置 Webpack:

// webpack.config.js
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new CopyWebpackPlugin({patterns: [{ from: 'src/assets', to: 'assets' }, // 将 src/assets 目录复制到 dist/assets],}),],
};

配置示例

以下是一个更完整的 Webpack 配置示例,展示了不同插件的组合使用:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: '[name].[contenthash].js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: 'production',module: {rules: [{test: /\.css$/i,use: [MiniCssExtractPlugin.loader, 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',filename: 'index.html',}),new MiniCssExtractPlugin({filename: '[name].[contenthash].css',}),new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production'),}),new CopyWebpackPlugin({patterns: [{ from: 'src/assets', to: 'assets' },],}),],
};

总结

  • 插件 是 Webpack 中非常强大和灵活的工具,用于执行打包优化、资源管理和环境变量注入等任务。
  • 安装插件:通过 npm 安装所需的插件。
  • 引入插件:在 Webpack 配置文件中引入插件。
  • 配置插件:在 Webpack 配置文件的 plugins 数组中配置插件。

通过合理使用插件,可以极大地增强 Webpack 的功能,满足各种复杂的构建需求。

1.2.5 Mode

模式(Mode)指示 webpack 使用相应模式的配置。

在 Webpack 中,mode 是一个重要的配置项,它可以设置 Webpack 在不同的模式下运行。mode 参数有三个可选值:

  1. development:开发模式,设置为该模式会启用有用的开发工具和优化构建速度。
  2. production:生产模式,设置为该模式会启用各种优化,如代码压缩、作用域提升和去除未使用代码。
  3. none:不使用任何默认优化或开发工具,提供最大程度的配置灵活性。

mode 配置

你可以在 Webpack 配置文件中设置 mode,或者在命令行参数中传递。

在配置文件中设置 mode
// webpack.config.js
module.exports = {mode: 'development', // 'development' or 'production' or 'none'entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};
在命令行参数中设置 mode
webpack --mode development
webpack --mode production
webpack --mode none

各模式下的默认配置

development

开发模式下启用的一些默认配置:

  • process.env.NODE_ENV 被设置为 development
  • 启用 NamedChunksPlugin 和 NamedModulesPlugin
  • devtool 被设置为 eval,生成原始源代码 (没有对 module 进行优化)
  • 输出未被压缩的构建

示例:

// webpack.config.js
module.exports = {mode: 'development',entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},devtool: 'eval', // 快速生成 source maps
};
production

生产模式下启用的一些默认配置:

  • process.env.NODE_ENV 被设置为 production
  • 启用模块连接优化 (module concatenation) 和压缩输出
  • devtool 被设置为 source-map,生成映射到原始源代码的 source maps
  • 启用各种优化,例如 tree shaking、代码压缩(TerserPlugin)

示例:

// webpack.config.js
module.exports = {mode: 'production',entry: './src/index.js',output: {filename: 'bundle.[contenthash].js',path: path.resolve(__dirname, 'dist'),},devtool: 'source-map', // 生成 source maps 以便调试
};
none

不使用任何默认优化或开发工具,可以最大程度地自定义配置。

示例:

// webpack.config.js
module.exports = {mode: 'none',entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};

mode 对构建结果的影响

mode 的值会影响到构建结果的大小、性能和调试体验。例如:

  • 开发模式 (development)

    • 启用 source maps,帮助开发者调试代码
    • 输出未被压缩的代码,构建速度快,利于快速迭代
    • 启用详细的错误信息和警告,帮助发现问题
  • 生产模式 (production)

    • 进行代码压缩和优化,减少输出文件的大小
    • 启用 tree shaking,去除未使用的代码
    • 生成高质量的 source maps,帮助生产环境下的调试

示例

以下是一个完整的 Webpack 配置示例,展示了如何根据不同的模式进行配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');module.exports = (env, argv) => {const isProduction = argv.mode === 'production';return {entry: './src/index.js',output: {filename: isProduction ? 'bundle.[contenthash].js' : 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: argv.mode || 'development',devtool: isProduction ? 'source-map' : 'eval',module: {rules: [{test: /\.css$/i,use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader','css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',filename: 'index.html',}),new MiniCssExtractPlugin({filename: '[name].[contenthash].css',}),new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify(argv.mode),}),],devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: !isProduction,},};
};

这个配置示例展示了如何根据不同的模式来调整构建输出、开发工具和插件配置。通过设置 mode,你可以方便地在开发模式和生产模式之间切换,从而提高开发效率和构建质量。

1.2.6 devServer

devServer 是 Webpack 提供的一个开发服务器选项,主要用于提升开发体验。它可以提供一个本地服务器,自动重新加载浏览器,支持热模块替换(Hot Module Replacement, HMR),方便开发者在开发过程中实时查看代码更改效果。

使用 devServer

要使用 devServer,你需要安装 webpack-dev-server

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

配置 devServer

devServer 配置项需要添加到 Webpack 配置文件中。下面是一些常用的配置选项:

基本配置
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {contentBase: path.resolve(__dirname, 'dist'),compress: true, // 启用 gzip 压缩port: 9000, // 服务器端口号},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),],
};
热模块替换(HMR)

热模块替换允许在不刷新整个页面的情况下更新应用程序中的模块。这对于保持应用程序状态非常有用。

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: true, // 启用 HMR},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),new webpack.HotModuleReplacementPlugin(), // 启用 HMR 插件],
};

在你的 JavaScript 文件中,你需要添加一些代码来处理模块更新:

if (module.hot) {module.hot.accept('./module.js', function () {console.log('Accepting the updated module!');// 使用新的模块进行重新渲染等操作});
}
配置示例

以下是一个更完整的 Webpack 配置示例,包括了各种 devServer 配置项:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {static: {directory: path.join(__dirname, 'dist'), // 提供内容的目录},compress: true, // 启用 gzip 压缩port: 9000, // 服务器端口号open: true, // 自动打开浏览器hot: true, // 启用 HMRhistoryApiFallback: true, // 适用于单页面应用程序proxy: { // 代理 API 请求'/api': 'http://localhost:3000',},},module: {rules: [{test: /\.css$/i,use: ['style-loader', 'css-loader'],},],},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),new webpack.HotModuleReplacementPlugin(), // 启用 HMR 插件],
};

常用的 devServer 配置选项

  • static.directory:指定静态文件所在的目录。
  • compress:是否启用 gzip 压缩。
  • port:指定开发服务器运行的端口。
  • open:是否在服务器启动后自动打开浏览器。
  • hot:是否启用热模块替换(HMR)。
  • historyApiFallback:是否启用 HTML5 历史记录 API 回退功能,适用于单页面应用。
  • proxy:设置代理,将特定请求代理到另一个服务器。

总结

devServer 是 Webpack 中一个非常强大的工具,它可以极大地提升开发体验。通过使用 devServer,开发者可以快速启动一个本地服务器,实时查看代码修改效果,甚至在不刷新页面的情况下更新模块。通过合理配置 devServer,可以更高效地进行前端开发。# Webpack基础学习-Day01

1.1 webpack 是什么

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。

在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。

它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。

1.2 webpack 核心概念

1.2.1 Entry

入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。

在 Webpack 中,entry 属性指定了 Webpack 用来构建其内部依赖图的起点或入口点。换句话说,entry 告诉 Webpack 从哪里开始打包代码。

entry 属性的用法

entry 属性的值可以是以下几种类型:

  1. 字符串:单个入口文件。
  2. 数组:多个入口文件,这些文件的内容会被打包到一个 bundle 中。
  3. 对象:多个入口点,每个入口点会生成一个独立的 bundle。
1. 字符串类型的 entry

这是最简单的用法,指定一个单一的入口文件:

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

在这种情况下,Webpack 从 ./src/index.js 开始构建依赖图,并将所有模块打包到 bundle.js 文件中。

2. 数组类型的 entry

如果你有多个文件需要作为入口,但希望将它们打包到一个 bundle 中,可以使用数组:

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

这种情况下,index.jsanotherModule.js 会被打包到同一个 bundle.js 文件中。

3. 对象类型的 entry

对象类型的 entry 允许你定义多个独立的入口点,每个入口点会生成一个独立的 bundle:

module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},
};

在这种情况下,会生成两个独立的 bundle 文件:app.bundle.jsadmin.bundle.js[name] 是一个占位符,会被 entry 对象的键替换。

高级用法

动态入口

可以通过函数返回一个对象来动态生成入口点:

module.exports = {entry: () => {const entries = {main: './src/main.js',};if (process.env.NODE_ENV === 'development') {entries.dev = './src/dev.js';}return entries;},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},
};

这种方式允许根据环境或其他条件动态配置入口点。

使用多个入口和 SplitChunks 插件

通过配合 SplitChunksPlugin,可以将共享代码提取到一个独立的 chunk 中:

module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},optimization: {splitChunks: {chunks: 'all',},},
};

这种配置会将 app.jsadmin.js 中的共享模块提取到一个公共的 bundle 中,从而减少重复代码。

配置示例

以下是一个更完整的 Webpack 配置示例,展示了不同类型的 entry 配置和一些常见的插件配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: 'production',module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: 'babel-loader',},{test: /\.css$/,use: ['style-loader', 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',chunks: ['app'], // 仅包含 app chunk}),new HtmlWebpackPlugin({template: './src/admin-template.html',filename: 'admin.html',chunks: ['admin'], // 仅包含 admin chunk}),],optimization: {splitChunks: {chunks: 'all',},},
};

总结

entry 属性是 Webpack 配置中的一个重要部分,它定义了 Webpack 构建的入口点。通过灵活使用字符串、数组和对象类型的 entry,你可以实现不同的构建策略和优化代码拆分。结合 Webpack 的其他特性(如插件和优化选项),可以构建高效、可维护的前端项目。

1.2.2 Output

输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。

output 属性是 Webpack 配置中的一个关键部分,它定义了打包后输出文件的相关设置。通过配置 output,你可以指定打包文件的名称、路径、公共路径等。

基本配置

1. filename

filename 用于指定输出文件的名称。可以使用占位符来生成动态文件名。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js', // 输出文件名path: path.resolve(__dirname, 'dist'), // 输出路径},
};

常用的占位符包括:

  • [name]: 入口点名称
  • [id]: chunk ID
  • [hash]: 编译时的唯一 hash
  • [chunkhash]: chunk 的 hash
  • [contenthash]: 文件内容的 hash
module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].js', // 动态生成文件名path: path.resolve(__dirname, 'dist'),},
};
2. path

path 用于指定输出目录的绝对路径。通常使用 Node.js 的 path 模块来生成绝对路径。

const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'), // 使用绝对路径},
};
3. publicPath

publicPath 用于指定输出解析文件的公共 URL 地址。通常用于配置 CDN 地址或开发服务器地址。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/', // 公共路径,通常用于配置 CDN 地址},
};

高级配置

1. chunkFilename

chunkFilename 用于指定按需加载的 chunk 文件的名称模板。类似于 filename,可以使用占位符。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),chunkFilename: '[name].[contenthash].js', // 按需加载的 chunk 文件名},
};
2. assetModuleFilename

assetModuleFilename 用于指定通过资源模块(如图像、字体等)处理的文件的输出文件名模板。

module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),assetModuleFilename: 'assets/[name].[hash][ext]', // 资源模块文件名},
};
3. librarylibraryTarget

librarylibraryTarget 用于将你的 bundle 输出为一个库。

  • library 指定库的名称。
  • libraryTarget 指定导出库的方式(如 var, umd, commonjs2 等)。
module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),library: 'MyLibrary', // 库名称libraryTarget: 'umd', // 输出库的方式},
};

常见示例

示例 1:简单的单入口点配置
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};
示例 2:多入口点配置
const path = require('path');module.exports = {entry: {app: './src/app.js',admin: './src/admin.js',},output: {filename: '[name].[contenthash].js',path: path.resolve(__dirname, 'dist'),},
};
示例 3:配置公共路径
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: 'https://cdn.example.com/assets/', // 使用 CDN 地址},
};
示例 4:配置资源模块输出
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),assetModuleFilename: 'images/[name].[hash][ext]', // 资源模块文件名},module: {rules: [{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},
};

详细解释

  • filename:指定输出文件的名称,可以使用占位符动态生成文件名。
  • path:指定输出目录的绝对路径,通常使用 Node.js 的 path.resolve 方法。
  • publicPath:指定公共路径,通常用于配置 CDN 地址或开发服务器地址。
  • chunkFilename:指定按需加载的 chunk 文件的名称模板。
  • assetModuleFilename:指定资源模块处理的文件输出名称模板。
  • librarylibraryTarget:用于将你的 bundle 输出为一个库,指定库的名称和导出方式。

通过配置 output 属性,可以灵活地控制 Webpack 打包输出文件的名称、路径和其他相关设置,以满足各种需求。

1.2.3 Loader

Loader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自 身 只 理 解

JavaScript)

在 Webpack 中,Loader 是一种用于转换模块的机制。在 Webpack 中,一切文件都是模块,而 Loader 则用于告诉 Webpack 如何处理那些非 JavaScript 文件(例如,CSS、图片、字体、TypeScript 等)。通过使用 Loader,你可以在 importrequire 模块时预处理文件,并将它们转换为 JavaScript 模块。

使用 Loader 的步骤

  1. 安装 Loader:通过 npm 安装所需的 Loader。
  2. 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则。

常用 Loader 示例

1. 处理 CSS 文件的 Loader

安装 style-loadercss-loader

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

配置 Webpack:

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

这个配置会使用 css-loader 将 CSS 文件解析成 JavaScript 可以理解的模块,然后使用 style-loader 将 CSS 注入到 DOM 中。

2. 处理图像文件的 Loader

安装 file-loaderurl-loader

npm install file-loader url-loader --save-dev

配置 Webpack:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource', // 使用内置资源模块},],},
};

asset/resource 会将图像文件单独输出到指定目录,并返回图像的 URL。

3. 处理字体文件的 Loader

字体文件可以使用与图像文件类似的 file-loaderurl-loader,这里使用 Webpack 5 内置的资源模块:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.(woff|woff2|eot|ttf|otf)$/i,type: 'asset/resource', // 使用内置资源模块},],},
};
4. 处理 Sass 文件的 Loader

安装 sass-loadersass(Dart Sass)、style-loadercss-loader

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

配置 Webpack:

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

这个配置会使用 sass-loader 将 Sass 文件编译成 CSS,然后使用 css-loaderstyle-loader 处理 CSS。

5. 处理 Babel 的 JavaScript 文件

安装 babel-loader 和 Babel 的相关包:

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

配置 Webpack 和 Babel:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],},},},],},
};
6. 处理 TypeScript 文件

安装 ts-loader 和 TypeScript:

npm install ts-loader typescript --save-dev

配置 Webpack 和 TypeScript:

// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.ts',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},resolve: {extensions: ['.ts', '.js'],},module: {rules: [{test: /\.ts$/,use: 'ts-loader',exclude: /node_modules/,},],},
};

Loader 配置详解

每个 Loader 规则通常包含以下几个属性:

  • test: 一个正则表达式,匹配文件路径。
  • use: 定义使用的 loader,可以是字符串或对象,或 loader 和选项的数组。
  • exclude: 排除某些文件路径。
  • include: 仅处理某些文件路径。

例如,下面是一个更复杂的 Loader 配置示例:

module.exports = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],},},},{test: /\.css$/i,use: ['style-loader', 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},{test: /\.scss$/i,use: ['style-loader', 'css-loader', 'sass-loader'],},{test: /\.ts$/,exclude: /node_modules/,use: 'ts-loader',},{test: /\.(woff|woff2|eot|ttf|otf)$/i,type: 'asset/resource',},],},
};

总结

  • Loader 是 Webpack 用来转换模块的工具,可以将非 JavaScript 文件转换为 JavaScript 模块。
  • 安装 Loader:通过 npm 安装所需的 Loader。
  • 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则,使用 testuseexcludeinclude 等属性来配置 Loader。
  • 常见的 Loadercss-loaderstyle-loaderfile-loaderurl-loadersass-loaderbabel-loaderts-loader 等。

通过合理使用 Loader,可以让 Webpack 处理各种类型的文件,从而实现更复杂和灵活的构建过程。

1.2.4 Plugins

插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,

在 Webpack 中,插件(Plugins)用于执行更广泛的任务,比如打包优化、资源管理和环境变量注入等。插件的功能比 Loader 更强大和灵活,Loader 主要用于转换单个文件,而插件可以直接操作整个构建过程。

使用插件的基本步骤

  1. 安装插件:通过 npm 安装所需的插件。
  2. 引入插件:在 Webpack 配置文件中引入插件。
  3. 配置插件:在 Webpack 配置文件的 plugins 数组中配置插件。

常用插件及其示例

1. HtmlWebpackPlugin

HtmlWebpackPlugin 用于简化 HTML 文件的创建,以便为 Webpack 打包后的文件提供服务。它可以自动生成一个 HTML 文件,并将打包后的文件自动插入其中。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new HtmlWebpackPlugin({template: './src/template.html', // 使用的 HTML 模板文件filename: 'index.html', // 生成的 HTML 文件名}),],
};
2. CleanWebpackPlugin

CleanWebpackPlugin 在每次构建前清理输出目录,确保输出目录只包含生产文件。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new CleanWebpackPlugin(), // 默认会清理 output.path 目录],
};
3. MiniCssExtractPlugin

MiniCssExtractPlugin 用于将 CSS 提取到单独的文件中。它支持按需加载 CSS 和 SourceMaps。

安装插件:

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

配置 Webpack:

// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.css$/i,use: [MiniCssExtractPlugin.loader, 'css-loader'],},],},plugins: [new MiniCssExtractPlugin({filename: '[name].css', // 输出的 CSS 文件名}),],
};
4. DefinePlugin

DefinePlugin 允许你在编译时创建配置的全局常量。它非常有用,可以根据不同的环境定义不同的变量值。

安装插件:

DefinePlugin 是 Webpack 内置的插件,不需要安装。

配置 Webpack:

// webpack.config.js
const path = require('path');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production'),}),],
};
5. HotModuleReplacementPlugin

HotModuleReplacementPlugin 启用模块热替换,允许在运行时更新各种模块,而无需进行完全刷新。

安装插件:

HotModuleReplacementPlugin 是 Webpack 内置的插件,不需要安装。

配置 Webpack:

// webpack.config.js
const path = require('path');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: true, // 启用热模块替换},plugins: [new webpack.HotModuleReplacementPlugin(),],
};
6. CopyWebpackPlugin

CopyWebpackPlugin 用于将单个文件或整个目录复制到构建目录中。

安装插件:

npm install copy-webpack-plugin --save-dev

配置 Webpack:

// webpack.config.js
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},plugins: [new CopyWebpackPlugin({patterns: [{ from: 'src/assets', to: 'assets' }, // 将 src/assets 目录复制到 dist/assets],}),],
};

配置示例

以下是一个更完整的 Webpack 配置示例,展示了不同插件的组合使用:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: '[name].[contenthash].js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: 'production',module: {rules: [{test: /\.css$/i,use: [MiniCssExtractPlugin.loader, 'css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',filename: 'index.html',}),new MiniCssExtractPlugin({filename: '[name].[contenthash].css',}),new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production'),}),new CopyWebpackPlugin({patterns: [{ from: 'src/assets', to: 'assets' },],}),],
};

总结

  • 插件 是 Webpack 中非常强大和灵活的工具,用于执行打包优化、资源管理和环境变量注入等任务。
  • 安装插件:通过 npm 安装所需的插件。
  • 引入插件:在 Webpack 配置文件中引入插件。
  • 配置插件:在 Webpack 配置文件的 plugins 数组中配置插件。

通过合理使用插件,可以极大地增强 Webpack 的功能,满足各种复杂的构建需求。

1.2.5 Mode

模式(Mode)指示 webpack 使用相应模式的配置。

在 Webpack 中,mode 是一个重要的配置项,它可以设置 Webpack 在不同的模式下运行。mode 参数有三个可选值:

  1. development:开发模式,设置为该模式会启用有用的开发工具和优化构建速度。
  2. production:生产模式,设置为该模式会启用各种优化,如代码压缩、作用域提升和去除未使用代码。
  3. none:不使用任何默认优化或开发工具,提供最大程度的配置灵活性。

mode 配置

你可以在 Webpack 配置文件中设置 mode,或者在命令行参数中传递。

在配置文件中设置 mode
// webpack.config.js
module.exports = {mode: 'development', // 'development' or 'production' or 'none'entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};
在命令行参数中设置 mode
webpack --mode development
webpack --mode production
webpack --mode none

各模式下的默认配置

development

开发模式下启用的一些默认配置:

  • process.env.NODE_ENV 被设置为 development
  • 启用 NamedChunksPlugin 和 NamedModulesPlugin
  • devtool 被设置为 eval,生成原始源代码 (没有对 module 进行优化)
  • 输出未被压缩的构建

示例:

// webpack.config.js
module.exports = {mode: 'development',entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},devtool: 'eval', // 快速生成 source maps
};
production

生产模式下启用的一些默认配置:

  • process.env.NODE_ENV 被设置为 production
  • 启用模块连接优化 (module concatenation) 和压缩输出
  • devtool 被设置为 source-map,生成映射到原始源代码的 source maps
  • 启用各种优化,例如 tree shaking、代码压缩(TerserPlugin)

示例:

// webpack.config.js
module.exports = {mode: 'production',entry: './src/index.js',output: {filename: 'bundle.[contenthash].js',path: path.resolve(__dirname, 'dist'),},devtool: 'source-map', // 生成 source maps 以便调试
};
none

不使用任何默认优化或开发工具,可以最大程度地自定义配置。

示例:

// webpack.config.js
module.exports = {mode: 'none',entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
};

mode 对构建结果的影响

mode 的值会影响到构建结果的大小、性能和调试体验。例如:

  • 开发模式 (development)

    • 启用 source maps,帮助开发者调试代码
    • 输出未被压缩的代码,构建速度快,利于快速迭代
    • 启用详细的错误信息和警告,帮助发现问题
  • 生产模式 (production)

    • 进行代码压缩和优化,减少输出文件的大小
    • 启用 tree shaking,去除未使用的代码
    • 生成高质量的 source maps,帮助生产环境下的调试

示例

以下是一个完整的 Webpack 配置示例,展示了如何根据不同的模式进行配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');module.exports = (env, argv) => {const isProduction = argv.mode === 'production';return {entry: './src/index.js',output: {filename: isProduction ? 'bundle.[contenthash].js' : 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/',},mode: argv.mode || 'development',devtool: isProduction ? 'source-map' : 'eval',module: {rules: [{test: /\.css$/i,use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader','css-loader'],},{test: /\.(png|svg|jpg|jpeg|gif)$/i,type: 'asset/resource',},],},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './src/template.html',filename: 'index.html',}),new MiniCssExtractPlugin({filename: '[name].[contenthash].css',}),new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify(argv.mode),}),],devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: !isProduction,},};
};

这个配置示例展示了如何根据不同的模式来调整构建输出、开发工具和插件配置。通过设置 mode,你可以方便地在开发模式和生产模式之间切换,从而提高开发效率和构建质量。

1.2.6 devServer

devServer 是 Webpack 提供的一个开发服务器选项,主要用于提升开发体验。它可以提供一个本地服务器,自动重新加载浏览器,支持热模块替换(Hot Module Replacement, HMR),方便开发者在开发过程中实时查看代码更改效果。

使用 devServer

要使用 devServer,你需要安装 webpack-dev-server

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

配置 devServer

devServer 配置项需要添加到 Webpack 配置文件中。下面是一些常用的配置选项:

基本配置
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {contentBase: path.resolve(__dirname, 'dist'),compress: true, // 启用 gzip 压缩port: 9000, // 服务器端口号},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),],
};
热模块替换(HMR)

热模块替换允许在不刷新整个页面的情况下更新应用程序中的模块。这对于保持应用程序状态非常有用。

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {contentBase: path.resolve(__dirname, 'dist'),hot: true, // 启用 HMR},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),new webpack.HotModuleReplacementPlugin(), // 启用 HMR 插件],
};

在你的 JavaScript 文件中,你需要添加一些代码来处理模块更新:

if (module.hot) {module.hot.accept('./module.js', function () {console.log('Accepting the updated module!');// 使用新的模块进行重新渲染等操作});
}
配置示例

以下是一个更完整的 Webpack 配置示例,包括了各种 devServer 配置项:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},mode: 'development',devServer: {static: {directory: path.join(__dirname, 'dist'), // 提供内容的目录},compress: true, // 启用 gzip 压缩port: 9000, // 服务器端口号open: true, // 自动打开浏览器hot: true, // 启用 HMRhistoryApiFallback: true, // 适用于单页面应用程序proxy: { // 代理 API 请求'/api': 'http://localhost:3000',},},module: {rules: [{test: /\.css$/i,use: ['style-loader', 'css-loader'],},],},plugins: [new HtmlWebpackPlugin({template: './src/index.html',}),new webpack.HotModuleReplacementPlugin(), // 启用 HMR 插件],
};

常用的 devServer 配置选项

  • static.directory:指定静态文件所在的目录。
  • compress:是否启用 gzip 压缩。
  • port:指定开发服务器运行的端口。
  • open:是否在服务器启动后自动打开浏览器。
  • hot:是否启用热模块替换(HMR)。
  • historyApiFallback:是否启用 HTML5 历史记录 API 回退功能,适用于单页面应用。
  • proxy:设置代理,将特定请求代理到另一个服务器。

总结

devServer 是 Webpack 中一个非常强大的工具,它可以极大地提升开发体验。通过使用 devServer,开发者可以快速启动一个本地服务器,实时查看代码修改效果,甚至在不刷新页面的情况下更新模块。通过合理配置 devServer,可以更高效地进行前端开发。

相关文章:

Webpack基础学习-Day01

Webpack基础学习-Day01 1.1 webpack 是什么 webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。 在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。 它将根据模块的依赖关系进行静态分析,打包生成…...

如何防止热插拔烧坏单片机

大家都知道一般USB接口属于热插拔,实际任意带电进行连接的操作都可以属于热插拔。我们前面讲过芯片烧坏的原理,那么热插拔就是导致芯片烧坏的一个主要原因之一。 在电子产品的整个装配过程、以及产品使用过程经常会面临接口热插拔或者类似热插拔的过程。…...

JQuery+HTML+JavaScript:实现地图位置选取和地址模糊查询

本文详细讲解了如何使用 JQueryHTMLJavaScript 实现移动端页面中的地图位置选取功能。本文逐步展示了如何构建基本的地图页面,如何通过点击地图获取经纬度和地理信息,以及如何实现模糊查询地址并在地图上标注。最后,提供了完整的代码示例&…...

ArcGIS Pro SDK (九)几何 13 多部件

ArcGIS Pro SDK (九)几何 13 多部件 文章目录 ArcGIS Pro SDK (九)几何 13 多部件1 获取多部分要素的各个部分2 获取多边形的最外层环 环境:Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 1 获取多部分要素的各个部分…...

【Node】npm i --legacy-peer-deps,解决依赖冲突问题

文章目录 🍖 前言🎶 一、问题描述✨二、代码展示🏀三、运行结果🏆四、知识点提示 🍖 前言 npm i --legacy-peer-deps,解决依赖冲突问题 🎶 一、问题描述 node执行安装指令时出现报错&#xff…...

h5点击电话号跳转手机拨号

需要使用到h5的 <a>标签 我们首先在<head>标签中添加代码 <meta name"format-detection" content"telephoneyes"/>然后再想要的位置添加代码 <a href"tel:10086"> 点击拨打&#xff1a;10086 </a> 这样功能就实现…...

从数据湖到湖仓一体:统一数据架构演进之路

文章目录 一、前言二、什么是湖仓一体&#xff1f;起源概述 三、为什么要构建湖仓一体&#xff1f;1. 成本角度2. 技术角度 四、湖仓一体实践过程阶段一&#xff1a;摸索阶段(仓、湖并行建设)阶段二&#xff1a;发展阶段方式一、湖上建仓(湖在下、仓在上)方式二&#xff1a;仓外…...

Electron 渲染进程直接调用主进程的API库@electron/remote引用讲解

背景 remote是个老库&#xff0c;早期Electron版本中有个remote对象&#xff0c;这个对象可以横跨所有进程&#xff0c;随意通信&#xff0c;后来官方认为不安全&#xff0c;被干掉了&#xff0c;之后有人利用Electron的IPC通信&#xff0c;底层通过Promise的await能力&#x…...

在python中使用正则表达式

正则表达式是什么&#xff1f;就是要寻找的数据的规律&#xff0c;使用正则表达式的步骤有三 第一&#xff0c;寻找规律&#xff0c;第二使用正则符号表示规律&#xff0c;第三&#xff0c;提取信息 看下面的代码 import re wenzhang (小草偷偷地从土里钻出来&#xff0c;嫩…...

华清数据结构day4 24-7-19

链表的相关操作 linklist.h #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h> typedef int datatype; typedef struct Node {union{int len;datatype data;};struct Node *next; } Node, *NodePtr;NodePtr list_create(); NodePtr apply_node(datatype e); …...

【深度学习图像】拼接图的切分

用户常常将多张图拼成一张图。 如果将这张图拆为多个子图&#xff0c;下面是一种opencv的办法&#xff0c;后面要训练一个模型来识别边缘更为准确。 import osimport cv2 import numpy as npdef detect_lines(image_path):# 读取图片image cv2.imread(image_path)if image i…...

Covalent(CXT)运营商网络规模扩大 42%,以满足激增的需求

Covalent Network&#xff08;CXT&#xff09;是领先的人工智能模块化数据基础设施&#xff0c;网络集成了超过 230 条链并积累了数千名客户&#xff0c;目前 Covalent Network&#xff08;CXT&#xff09;网络迎来了五位新运营商的加入&#xff0c;包括 Graphyte Labs、PierTw…...

Java 集合框架:HashMap 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 020 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…...

单周期CPU(三)译码模块(minisys)(verilog)(vivado)

timescale 1ns / 1ps //module Idecode32 (input reset,input clock,output [31:0] read_data_1, // 输出的第一操作数output [31:0] read_data_2, // 输出的第二操作数input [31:0] Instruction, // 取指单元来的指令input [31:0] …...

理想化相机模型的相机内参

文章目录 理想化相机模型的相机内参计算1. 相机内参定义2. 根据视角和图像分辨率计算相机内参2.1 计算焦距 fx 和 fy2.2 计算主点 cx 和 cy3. 示例计算3.1 计算 fx3.2 假设 fy = fx(因为没有垂直视场角的信息)3.3 计算主点4. 相机内参矩阵理想化相机模型的相机内参计算 在理…...

【数据脱敏】⭐️SpringBoot 整合 Jackson 实现隐私数据加密

目录 &#x1f378;前言 &#x1f37b;一、Jackson 序列化库 &#x1f37a;二、方案实践 2.1 环境准备 2.2 依赖引入 2.3 代码编写 &#x1f49e;️三、接口测试 &#x1f379;四、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;最近也是很忙啊&#xff0c;上次的文章…...

骑砍2霸主MOD开发(18)-多人联机模式开发环境搭建

一.多人联机模式网络拓扑图 二.专用服务器搭建(DedicatedServer) <1.Token生成(用于LobbyServer的校验): 进入多人联机大厅,ALT~打开RGL控制台,输入customserver.gettoken Token文件路径:C:\Users\taohu\Documents\Mount and Blade II Bannerlord\Tokens <2.启动专用服务…...

【HZHY-AI300G智能盒试用连载体验】在华为IoTDA平台上建立设备

目录 华为IoTDA平台 注册IoTDA实例 创建产品 添加设备 本文首发于&#xff1a;【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! 在上一篇博文中介绍了如何在HZHY-AI300G智能盒创建南向设备&a…...

【LLM】-05-提示工程-部署Langchain-Chat

目录 1、软硬件要求 1.1、软件要求 1.2、硬件要求 1.3、个人配置参考 2、创建cuda环境 3、下载源码及模型 4、配置文件修改 5、初始化知识库 5.1、训练自己的知识库 6、启动 7、API接口调用 7.1、使用openai 参考官方wiki&#xff0c;本文以Ubuntu20.04_x64&#xf…...

【漏洞复现】Next.js框架存在SSRF漏洞(CVE-2024-34351)

0x01 产品简介 ZEIT Next.js是ZEIT公司的一款基于Vue.js、Node.js、Webpack和Babel.js的开源Web应用框架。 0x02 漏洞概述 ZEIT Next.js 13.4版本至14.1.1之前版本存在代码问题漏洞&#xff0c;该漏洞源于存在服务器端请求伪造 (SSRF) 漏洞 0x03 搜索引擎 body"/_nex…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...