初始化阶段:读取配置文件、创建complier实例
编译阶段:解析入口点、模块加载(loader)
打包阶段:模块合并与优化、代码分割
输出阶段:生成输出文件
Webpack读取并解析webpack.config.js文件,获取构建所需的配置信息。
Webpack从入口文件开始,构建模块依赖图。
使用加载器处理不同类型的模块,如CSS、图片等,将它们转换为JavaScript模块。
插件在特定的生命周期钩子上运行,执行诸如优化、资源管理等任务。
代码分割、Tree Shaking等优化手段被应用,以减少文件大小并提高性能。
打包后的文件根据配置输出到指定目录。
Webpack是一个强大的模块打包工具,它可以通过配置来实现代码压缩、代码分割、模块热替换等多种功能。以下是一些Webpack的常用配置项:
entry
作用:指定Webpack的入口文件。
示例:
entry: './src/index.js',
output
作用:定义输出文件的配置,包括输出文件的名称、路径等。
示例:
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode
作用:设置Webpack的运行模式,可以是development
(开发模式)或production
(生产模式)。
示例:
mode: 'production',
development模式:提供开发时的必要功能,如source map、错误提示等。
module
作用:配置模块的加载器和转换规则,用于处理不同类型的文件。
module.rules
:配置各类文件的处理规则,test属性用户匹配文件路径,use属性指定使用的loader;
示例:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
resolve
作用:配置模块解析规则,可以设置别名、扩展名等,方便引入模块。
示例:
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
extensions: ['.js', '.json'],
},
plugins
作用:使用插件来增强Webpack功能,例如压缩代码、拷贝文件等。
示例:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
devServer
Webpack DevServer 是一个开发工具,它可以提供一个简单的 web 服务器,并且能够实时重新加载
contentBase
:告诉服务器从哪里提供内容,默认情况下,服务器会使用当前执行目录。
compress
:告诉服务器启用 gzip 压缩。
port
:指定要监听请求的端口号。
open
:告诉服务器自动打开浏览器。
hot
:启用模块热替换(Hot Module Replacement)。
optimization
:代码分割、压缩作用:控制构建过程中的优化行为,如代码分割、压缩等。
示例:
optimization: {
splitChunks: {
chunks: 'all',
},
minimize: true,
},
在 Webpack 中,optimization
配置用于控制构建过程中的优化行为。它可以帮助你实现代码分割、代码压缩、树摇(tree shaking)等功能,从而减小输出文件的大小和提高应用程序的性能。
以下是一些常用的 optimization
配置选项:
splitChunks
splitChunks
用于将公共代码(如第三方库、公共组件等)提取到单独的文件中,以实现代码分割和缓存复用。optimization: {
splitChunks: {
chunks: 'all', // 对所有类型的代码进行分割
minSize: 20000, // 生成 chunk 的最小体积(以字节为单位)
maxSize: 0, // 生成 chunk 的最大体积(以字节为单位),0 表示不限制
minChunks: 1, // 模块被引用的最小次数
maxAsyncRequests: 30, // 按需加载时的最大并行请求数
maxInitialRequests: 30, // 入口点的最大并行请求数
automaticNameDelimiter: '~', // 文件名的连接符
name: true, // 是否根据模块和缓存组的名称自动生成文件名
cacheGroups: {
// 定义缓存组,用于控制代码分割的规则
vendors: {
test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 中的模块
priority: -10, // 优先级,值越大优先级越高
filename: 'vendors.[contenthash].js', // 输出文件名
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则将复用它,而不是生成新的模块
filename: 'common.[contenthash].js', // 输出文件名
},
},
},
},
runtimeChunk
runtimeChunk
用于将 Webpack 的运行时代码提取到一个单独的文件中,以实现运行时代码的复用。optimization: {
runtimeChunk: 'single', // 将运行时代码提取到一个单独的文件中
},
minimize
minimize
用于控制是否压缩输出文件。当设置为 true
时,Webpack 会使用默认的压缩插件(如 TerserPlugin)来压缩 JavaScript 代码。optimization: {
minimize: true, // 启用压缩
},
minimizer
minimizer
用于自定义压缩插件。你可以在这里添加自定义的压缩插件,如 TerserPlugin(用于压缩 JavaScript 代码)、CssMinimizerPlugin(用于压缩 CSS 代码)等。const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
// TerserPlugin 的配置选项
}),
new CssMinimizerPlugin({
// CssMinimizerPlugin 的配置选项
}),
],
},
moduleIds
和 chunkIds
moduleIds
和 chunkIds
用于控制模块和 chunk 的 ID 生成方式。这可以帮助你优化输出文件的大小和提高构建速度。optimization: {
moduleIds: 'hashed', // 使用模块内容的哈希值作为模块 ID
chunkIds: 'named', // 使用模块名称作为 chunk ID
},
通过合理地配置 optimization
选项,你可以优化 Webpack 的构建过程,提高应用程序的性能。
通过合理地配置这些选项,你可以优化Webpack的构建过程,提高应用程序的性能和可维护性。
loader
:用于转换模块的工具。主要用于文件内容的转换。
babel-loader
处理js文件,将es6+代码转换为es5,通常与@babel/preset-env
一起使用;
css-loader
和saas-loader
处理css和sass文件,miniCssExtractPlugin.loader
将css提取为单独文件;
style-loader
将css插入到dom的标签中去;
file-loader
处理文件(如图片、字体),并返回文件的url;
url-loader
处理图片文件,8kb以下的图片转为base64,大于8kb的图片则拷贝到输出目录;
自定义loader
:实质上是一个函数,接受源文件内容作为输入,并输出处理后的内容。可以通过this.callbak
返回结果;
module.exports = function(source){ //自定义loader:将文件内容中的‘my’替换为‘我的’
const result = source.replace(/my/g,'我的');
return rusult;
}
插件系统的实现:Plugin 是一个具有 apply 方法的对象,当 Webpack 启动构建时,会调用所有 Plugin 的 apply 方法,并将 compiler 对象作为参数传入。在 apply 方法中,Plugin 可以监听事件钩子,并执行自定义的操作。
plugin
:用于扩展webpack功能的工具,可以在webpack构建过程中执行更复杂的任务,如打包优化、资源管理、环境变量注入等。Plugin主要用于处理构建过程中的各种任务。
CleanWebpackPlugin
在每次打包前清理输出目录,防止旧文件残留;
HtmlWebpackPlugin
根据模板生成Html文件,并自动注入打包后的js文件等;
MiniCssExtractPlugin
将Css提取到单独的文件中;
DefinePlugin
创建全局变量,在编译时进行替换;
TerserPlugin
用于压缩js代码,主要在生产环境中使用;
自定义Plugin
:plugin是一个类,包含apply方法,apply接受一个complier
对象,通过这个对象可以钩入webpack的各个构建阶段;
class MyPlugin{ //编译完成后输出提示
apply(compiler){
compiler.hooks.done.tap('MyPlugin',(stats)=>{
console.log('编译完成!')
})
}
}
例如引入 element-ui ,用到哪些组件就引哪些
import {Button,Dialog} from 'element-ui';
Vue.use(Button); // 按钮组件
Vue.use(Dialog); // 对话框组件
webpack的externals
属性,将公共的或不常改动的第三方包名称,配置在属性中,打包时会自动忽略当中的包。具体实现如下:
在 build/webpack.base.conf.js文件中:
module.exports = {
externals: {
Vue: 'Vue',
Axios: 'axios'
}
}
// 其中的 key--对应 import Axios名称,value--对应原始方法名称
需要在根目录,index.html 中引入一下
<script src="https://unpkg.com/vue@2.6.11/dist/vue.min.js">script>
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js">script>
include 规定需要处理的文件有哪些
enclude 排除不需要处理的文件夹
{ test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src')],
exclude: /node_modules/
}
{ module: {
noParse: /jquery/,
rule: [
...
]
}
}
babel-loader
提供了cacheDirectory
选项参数,默认为false。
设置空或true时,会利用系统的临时文件夹缓存经过 babel 处理好的模块,对于 rebuild js 有着非常大的性能提升。
{ test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [resolve('src')],
exclude: /node_modules/
}
webpack 在打包过程中,loader 转化js、css、img等文件是同步进行的,一个一个的转换。
happyPack 的原理是,将这些任务分解到多个子进程中,并行执行,执行完成后把结果发送到主进程,从而减少整体的打包时间。
uglifyjs-webpack-plugin
插件,会对JS文件自动压缩,不需要做其它的任何操作。也可以手动安装这个插件,设置一些另外的参数,比如开启并行压缩,加快打包的速度。TerserWebpackPlugin
来压缩 JavaScript 代码。压缩CSS文件和图片
css-minimizer-webpack-plugin
minicssExtraPlugin
用于压缩 CSS 文件
ImageMinimizerWebpaxkPlugin
进行压缩图片压缩
压缩HTML文件
HtmlWebpackPlugin
插件除了可以帮助我们简化 HTML 文件的创建,也可以压缩 HTML 文件。
首先,需要先安装 HtmlWebpackPlugin
插件:npm install --save-dev html-webpack-plugin
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
plugins: [new HtmlWebpackPlugin()],
};
如果不添加任何配置的话,会生成一个默认 index.html 文件,并自动注入所有的 chunk 和压缩。
也可以通过自定义配置参数,以下几个是常见的参数:
template
:模板的路径,默认会去寻找 src/index.ejs 是否存在。
filename
:输出文件的名称,默认为 index.html。
inject
:是否将资源注入到模版中,默认为 true。
minify
:压缩参数。在生产模式下(production),默认为 true;否则,默认为false。
如果 minify 为 true,生成的 HTML 将使用 html-minifier-terser 和以下选项进行压缩:
{
collapseWhitespace: true,
keepClosingSlash: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
1、Webpack:是一个强大的静态模块打包工具,它可以将各种类型的文件,如JavaScript、CSS、图片等,作为模块进行打包,并生成最终的静态资源文件。Webpack使用各种loader和plugin来处理不同类型的文件,还可以进行代码分割、懒加载、压缩等优化操作。
2、Vite:是一个基于ES模块的快速开发工具,它利用浏览器原生的ES模块机制,将每个模块作为一个独立的请求来加载,而不是像Webpack那样把所有模块打包成一个文件。这样可以在开发过程中实现快速的热模块替换,减少构建时间,提高开发效率。
Vite的设计初衷是为了解决传统打包工具的一些问题,传统的打包工具在开发过程中会将所有的模块打包成一个或多个最终的捆绑文件,然后在浏览器环境中执行。这种方式在大型项目中可能会导致开发服务器启动慢,因为需要将所有的模块进行打包。Vite通过利用ES模块的特性,在开发过程中仅对需要的模块进行编译和构建,从而提升了开发服务器的启动速度。Vite还支持热模块替换。
总结
Webpack是一个成熟和功能强大的前端构建工具,提供了丰富的功能和配置选项。而Vite是一个新兴的前端构建工具,通过利用ES模块和HMR等特性,提供了更快的开发体验。两者都在前端项目中发挥着重要的作用,开发者可以根据项目需求选择适合的工具。Vite在开发阶段更加轻量级和高效,因为它不需要进行复杂的打包过程,只需简单地使用浏览器原生支持的ES模块加载机制。但是在生产环境下,还是需要使用类似Webpack这样的构建工具来进行打包和优化。
Webpack 配置中的 hot: true
是 webpack-dev-server
的一个选项,用于启用热更新(Hot Module Replacement,简称 HMR)。当设置为 true
时,webpack-dev-server
将尝试使用 HMR 更新应用程序,而不是刷新整个页面。
仅仅设置 hot: true
是不够的。为了使 HMR 正常工作,您还需要执行以下操作:
安装 webpack-dev-server
:确保已经通过 npm 或 yarn 安装了 webpack-dev-server
。
npm install webpack-dev-server --save-dev
配置 webpack.config.js
:在 webpack.config.js
文件中,确保已经正确配置了 devServer
选项,并将 hot
设置为 true
。
module.exports = {
// ...
devServer: {
hot: true,
// 其他选项...
},
// ...
};
添加 HotModuleReplacementPlugin
插件:在 webpack.config.js
文件的 plugins
数组中,添加 new webpack.HotModuleReplacementPlugin()
。
const webpack = require('webpack');
module.exports = {
// ...
plugins: [
new webpack.HotModuleReplacementPlugin(),
// 其他插件...
],
// ...
};
处理模块更新:在项目的入口文件(如 index.js
)中,添加以下代码以处理模块更新。(需要热更新的文件)
if (module.hot) {
module.hot.accept();
}
只有完成以上步骤,HMR 才能在项目中正常工作。