做营销网站那个好/百度指数怎么下载
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
属性的值可以是以下几种类型:
- 字符串:单个入口文件。
- 数组:多个入口文件,这些文件的内容会被打包到一个 bundle 中。
- 对象:多个入口点,每个入口点会生成一个独立的 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.js
和 anotherModule.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.js
和 admin.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.js
和 admin.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. library
和 libraryTarget
library
和 libraryTarget
用于将你的 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
:指定资源模块处理的文件输出名称模板。library
和libraryTarget
:用于将你的 bundle 输出为一个库,指定库的名称和导出方式。
通过配置 output
属性,可以灵活地控制 Webpack 打包输出文件的名称、路径和其他相关设置,以满足各种需求。
1.2.3 Loader
Loader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自 身 只 理 解
JavaScript)
在 Webpack 中,Loader
是一种用于转换模块的机制。在 Webpack 中,一切文件都是模块,而 Loader
则用于告诉 Webpack 如何处理那些非 JavaScript 文件(例如,CSS、图片、字体、TypeScript 等)。通过使用 Loader
,你可以在 import
或 require
模块时预处理文件,并将它们转换为 JavaScript 模块。
使用 Loader 的步骤
- 安装 Loader:通过 npm 安装所需的 Loader。
- 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则。
常用 Loader 示例
1. 处理 CSS 文件的 Loader
安装 style-loader
和 css-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-loader
或 url-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-loader
或 url-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-loader
、sass
(Dart Sass)、style-loader
和 css-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-loader
和 style-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 规则,使用
test
、use
、exclude
、include
等属性来配置 Loader。 - 常见的 Loader:
css-loader
、style-loader
、file-loader
、url-loader
、sass-loader
、babel-loader
、ts-loader
等。
通过合理使用 Loader,可以让 Webpack 处理各种类型的文件,从而实现更复杂和灵活的构建过程。
1.2.4 Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,
在 Webpack 中,插件(Plugins)用于执行更广泛的任务,比如打包优化、资源管理和环境变量注入等。插件的功能比 Loader 更强大和灵活,Loader 主要用于转换单个文件,而插件可以直接操作整个构建过程。
使用插件的基本步骤
- 安装插件:通过 npm 安装所需的插件。
- 引入插件:在 Webpack 配置文件中引入插件。
- 配置插件:在 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
参数有三个可选值:
development
:开发模式,设置为该模式会启用有用的开发工具和优化构建速度。production
:生产模式,设置为该模式会启用各种优化,如代码压缩、作用域提升和去除未使用代码。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
属性的值可以是以下几种类型:
- 字符串:单个入口文件。
- 数组:多个入口文件,这些文件的内容会被打包到一个 bundle 中。
- 对象:多个入口点,每个入口点会生成一个独立的 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.js
和 anotherModule.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.js
和 admin.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.js
和 admin.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. library
和 libraryTarget
library
和 libraryTarget
用于将你的 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
:指定资源模块处理的文件输出名称模板。library
和libraryTarget
:用于将你的 bundle 输出为一个库,指定库的名称和导出方式。
通过配置 output
属性,可以灵活地控制 Webpack 打包输出文件的名称、路径和其他相关设置,以满足各种需求。
1.2.3 Loader
Loader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自 身 只 理 解
JavaScript)
在 Webpack 中,Loader
是一种用于转换模块的机制。在 Webpack 中,一切文件都是模块,而 Loader
则用于告诉 Webpack 如何处理那些非 JavaScript 文件(例如,CSS、图片、字体、TypeScript 等)。通过使用 Loader
,你可以在 import
或 require
模块时预处理文件,并将它们转换为 JavaScript 模块。
使用 Loader 的步骤
- 安装 Loader:通过 npm 安装所需的 Loader。
- 配置 Webpack:在 Webpack 配置文件中定义 Loader 规则。
常用 Loader 示例
1. 处理 CSS 文件的 Loader
安装 style-loader
和 css-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-loader
或 url-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-loader
或 url-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-loader
、sass
(Dart Sass)、style-loader
和 css-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-loader
和 style-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 规则,使用
test
、use
、exclude
、include
等属性来配置 Loader。 - 常见的 Loader:
css-loader
、style-loader
、file-loader
、url-loader
、sass-loader
、babel-loader
、ts-loader
等。
通过合理使用 Loader,可以让 Webpack 处理各种类型的文件,从而实现更复杂和灵活的构建过程。
1.2.4 Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,
在 Webpack 中,插件(Plugins)用于执行更广泛的任务,比如打包优化、资源管理和环境变量注入等。插件的功能比 Loader 更强大和灵活,Loader 主要用于转换单个文件,而插件可以直接操作整个构建过程。
使用插件的基本步骤
- 安装插件:通过 npm 安装所需的插件。
- 引入插件:在 Webpack 配置文件中引入插件。
- 配置插件:在 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
参数有三个可选值:
development
:开发模式,设置为该模式会启用有用的开发工具和优化构建速度。production
:生产模式,设置为该模式会启用各种优化,如代码压缩、作用域提升和去除未使用代码。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执行安装指令时出现报错ÿ…...

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

从数据湖到湖仓一体:统一数据架构演进之路
文章目录 一、前言二、什么是湖仓一体?起源概述 三、为什么要构建湖仓一体?1. 成本角度2. 技术角度 四、湖仓一体实践过程阶段一:摸索阶段(仓、湖并行建设)阶段二:发展阶段方式一、湖上建仓(湖在下、仓在上)方式二:仓外…...
Electron 渲染进程直接调用主进程的API库@electron/remote引用讲解
背景 remote是个老库,早期Electron版本中有个remote对象,这个对象可以横跨所有进程,随意通信,后来官方认为不安全,被干掉了,之后有人利用Electron的IPC通信,底层通过Promise的await能力&#x…...

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

华清数据结构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); …...

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

Covalent(CXT)运营商网络规模扩大 42%,以满足激增的需求
Covalent Network(CXT)是领先的人工智能模块化数据基础设施,网络集成了超过 230 条链并积累了数千名客户,目前 Covalent Network(CXT)网络迎来了五位新运营商的加入,包括 Graphyte Labs、PierTw…...

Java 集合框架:HashMap 的介绍、使用、原理与源码解析
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 020 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…...

单周期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 实现隐私数据加密
目录 🍸前言 🍻一、Jackson 序列化库 🍺二、方案实践 2.1 环境准备 2.2 依赖引入 2.3 代码编写 💞️三、接口测试 🍹四、章末 🍸前言 小伙伴们大家好,最近也是很忙啊,上次的文章…...

骑砍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实例 创建产品 添加设备 本文首发于:【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,本文以Ubuntu20.04_x64…...

【漏洞复现】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之前版本存在代码问题漏洞,该漏洞源于存在服务器端请求伪造 (SSRF) 漏洞 0x03 搜索引擎 body"/_nex…...

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 小区小朋友统计(100分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…...

Vuex看这一篇就够了
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

Kafka集群创建
这样就创建好了docker4个镜像,三个node,一个manager。 其中,浏览器访问的是manager对应的那个url,直接在里面加Cluster...

2024.7.22 作业
1.将双向链表和循环链表自己实现一遍,至少要实现创建、增、删、改、查、销毁工作 循环链表 looplinklist.h #ifndef LOOPLINKLIST_H #define LOOPLINKLIST_H#include <myhead.h>typedef int datatype;typedef struct Node {union {int len;datatype data;}…...

如何使用aiohttp或requests-async等库并发地执行多个HTTP请求
在Python中,要并发地执行多个HTTP请求,可以使用aiohttp这样的异步HTTP客户端库,因为它支持异步编程,能够显著提高IO密集型任务的性能,比如网络请求。requests-async并不是一个广泛认知的库(虽然可能存在类似…...

Golang | Leetcode Golang题解之第257题二叉树的所有路径
题目: 题解: func binaryTreePaths(root *TreeNode) []string {paths : []string{}if root nil {return paths}nodeQueue : []*TreeNode{}pathQueue : []string{}nodeQueue append(nodeQueue, root)pathQueue append(pathQueue, strconv.Itoa(root.V…...

关于css中flex布局垂直居中失效问题的原因
项目中遇到用flex进行页面布局后,使用上下居中设置:align-item: center; 目标效果如下: 但是失效,不起作用,如下图所示: 各种排查过后发现设置了子模块 align-self 属性,这会覆盖容器上的 al…...

用Redisson写一个库存扣减的方法
使用Redisson来处理库存操作可以确保在高并发环境下库存数据的一致性和完整性。以下是使用Redisson实现库存管理的一些通用方法,包括获取库存、扣减库存、设置库存等。我们将使用Redisson的ReentrantLock来确保并发安全。 首先,确保你已经正确设置了Red…...

第2节课:文本内容与格式化——HTML中的文本处理技巧
目录 文本内容与格式化:段落和标题:构建文本基础段落 <p>标题 <h1> 到 <h6> 格式化:强调和样式加粗 <b>斜体 <i>下划线 <u> 列表:组织内容无序列表 <ul>有序列表 <ol>定义列表 &…...

temu平台电池/锂电池UN38.3资质合规解析
UN38.3资质合规解析 为满足相关法律法规和商品运输安全需求含锂电池商品需要提供对应的UN38.3资质。截至7月29日,相关类目下UN38.3资质待上传或上传失败的商品可能面临下架。 -01什么是UN38.3- 1)UN38.3是指由联合国危险货物运输专家委员会编写的《试验…...