webpack简介
一、为什么要使用打包工具
当涉及到在浏览器中展示前端应用程序时,浏览器只能直接理解和解析原生的HTML、CSS和JavaScript代码。然而,对于其他的技术或文件类型,浏览器就需要借助额外的工具来进行转换或解析,以使其能够被浏览器正确识别和处理。web前端打包工具的作用就是打包工具通过执行一系列的操作,如编译、压缩、合并等,来转换前端代码,减少其体积,减少网络请求,从而提高应用程序的加载速度和性能。此外,打包工具还能方便地将应用程序部署到服务器上。目前,会使用web前端打包工具是现代前端人员必备技能。打包工具在前端单页面中使用的比较多。
(总之,Web前端打包工具的作用是通过对前端代码进行编译、压缩、合并等操作,来减少代码体积、减少网络请求、提高应用的加载速度和性能,并方便地将应用部署到服务器上。掌握打包工具已经成为现代前端开发中不可或缺的技能。)
二、有哪些打包工具
1.Grunt:是一个用于自动化前端开发中重复任务的JavaScript任务运行器。它可以文件合并、压缩、测试等任务。
优点:配置简单且易上手。
缺点:任务执行速度相对较慢,特别是当处理大量文件或复杂任务时,可能会感觉到一定的延迟。
2.Gulp: 可以自动处理和转换文件,如压缩CSS、JS,合并文件,以及执行各种其他定制化的操作。
优点:易于理解和编写、任务执行速度较快;插件丰富,社区活跃。
缺点:配置相对复杂,需要了解流的概念。
3.Parcel:能够自动地分析项目的依赖关系,并行地打包和转换文件,无需手动配置即可使用。Parcel 支持多种文件类型,包括 JavaScript、CSS、HTML、图像、字体等。
优点:配置简单,无需手动配置。
缺点:自定义配置选项较少,灵活性相对较低。
4.Rollup:专注于将 JavaScript 库打包为更小、更高效的输出文件。Rollup 主要用于打包 JavaScript 库,支持 ES6 模块和 Tree-shaking,可以检测并移除未使用的代码,使得打包后的文件更精简,减少了不必要的代码和资源。
优点:输出文件体积小,效率高;支持 ES6 模块和 Tree-shaking。
缺点:配置复杂,可能对某些复杂的项目需求造成一定的限制。
5.Vite:可以快速的反应速度和即时的模块更新,无需等待重新构建的时间。Vite还支持最新的前端技术,如Vue 3的单文件组件(SFC)和React JSX等。
优点:Vite通过利用浏览器原生的ES模块导入,提供了快速的开发体验和构建过程,同时支持最新的前端技术。
缺点:相对较新的工具,可能存在一些稳定性和兼容性问题,对于复杂的项目或旧版本的浏览器,可能需要更多的适配和测试。
6.Webpack:将多个模块和资源打包成一个或多个最终的静态文件,以便在浏览器中加载。它能够处理各种类型的文件,并通过加载器(loaders)对它们进行转换和处理。Webpack还支持代码拆分,即将代码拆分成多个文件,实现按需加载,提高应用程序的加载速度。另外,Webpack还能通过插件(plugins)实现各种优化,如文件压缩、代码混淆等,从而减小文件体积、提高应用程序性能。(功能最全面配置最强大,目前是是市面上最流行的工具之一)。
优点:灵活的配置选项,满足复杂的项目需求;插件和加载器生态系统丰富;支持代码拆分、懒加载、文件压缩等优化。可以通过插件和加载器来扩展和定制Webpack的功能。
缺点:学习曲线较陡峭;配置相对复杂。
对于大型项目使用webpack,对于小型项目使用Vite
Webpack是创始人(托比亚斯·科伯斯)是一位德国的软件工程师。在2012年创建了Webpack。
Webpack 1:
- Webpack 1是在2012年由Tobias Koppers创建的。
- 它的目标是解决前端模块化的问题,通过将所有资源(包括JavaScript、CSS、图片等)视为模块,并将它们打包成一个或多个文件。
- Webpack 1引入了一些核心概念,如entry(入口)、output(输出)、loaders(加载器)和plugins(插件)等。
Webpack 2:
- Webpack 2于2016年发布。
- Webpack 2引入了一些重要的功能和改进,包括Tree Shaking(树摇优化)和Scope Hoisting(作用域提升)等。
- 它还增加了对ES6模块语法的原生支持,并提供了更好的性能和更丰富的插件生态系统。
Webpack 3:
- Webpack 3于2017年发布。
- Webpack 3的主要目标是提升构建速度和优化输出质量。
- 它引入了许多性能优化,包括Scope Hoisting、Module Concatenation(模块合并)和代码分割等。
Webpack 4:
- Webpack 4于2018年发布。
- Webpack 4进一步改进了构建性能,提供了更好的默认配置和优化选项。
- 它引入了许多新功能,如mode(模式)、零配置(Zero Configuration)和自动代码分割等。
Webpack 5:
- Webpack 5于2020年发布。
- Webpack 5带来了许多重大改进和新功能,如更好的构建性能、模块联邦(Module Federation)、持久化缓存(Persistent Caching)和更好的Tree Shaking等。
- 它还通过引入新的模块类型和废弃一些旧的特性来改进了构建结果的大小和质量。
webpack的使用
一、webpack的基本使用
1、创建一个package.json文件,可以在其中添加或修改项目的配置和依赖项信息
npm init -y //创建一个package.json文件
2、安装webpack
npm install webpack webpack-cli --save-dev //开发者模式
3.在packaga.json文件中配置
将"scripts":{
"test":"echo \ "Error: no test specified\" && exit 1"
替换成:
"build":"webpack" //在build中执行webpack这条命令
//每次打包都使用npm run build 进行打包文件
4、在项目根目录下创建一个名为webpack.config.js文件,用来定义入口文件出口文件、输出文件目录、加载器、插件等。
(配置文件一定要于项目根部,文件名不能写错否则找不到该文件)
三、webpack5大核心概念:
1、entry(入口) //指令Webpack从哪个文件开始打包,解析导入的其他模块依赖关系。
2、output(输出) //指令Webpack 打包完之后输出文件的路径、文件名等。
3、loader(加载器) //加载器允许Webpack去处理非JavaScript文件,并将它们转换为Webpack可以识别和处理的模块。
4、plugins(插件) //扩展功能,压缩、文件合并、代码分离、自动生成HTML文件等
5、mode(模式)【主要有两种模式】 打包环境
- 开发模式:development //开发的时候使用的方式
- 生产模式:production //对代码进行优化,包括压缩、混淆、删除无用的代码和将模块合并等,减小文件体积,提高性能 //部署上线了,给客户看————打包速度慢
四、打包/配置文件
1.1.打包一个简单的js文件 首先创建一个index.js文件,并且没有引入任何模块(文件名随便起)
const path = require("path");//path 模块是内置的核心模块之一,path模块的主要作用是帮助你处理路径相关的操作,比如拼接路径、解析路径、获取路径的绝对路径等。
module.export={
entry: path.join(__dirname, 'src', 'index.js'), //打包单个文件,__dirname绝对路径,在那个文件夹,要打包文件
output: {//定义打包后的文件输出路径、文件名以及其他输出相关的选项,他是一个绝对路径。
path: path.join(__dirname, "dist"),//path指定输出文件的存放路径,path.join函数来拼接目录路径;名称为dist打包后存放的文件夹
//代表当前模块文件所在的目录的绝对路径,是一个全局变量,返回的是一个字符串
//文件名
filename: "index.js" // '[name].[ext]' 占位符允许动态生成文件名,//指定输出的文件名
},
//mode模式分开发模式 生产模式
mode: "development"
}
使用npm run build 进行打包文件
1.2.打包多个js文件 首先创建index1.js文件和index2.js文件,没有引入任何模块(文件名随便起)
const path = require("path");//path 模块是内置的核心模块之一,path模块的主要作用是帮助你处理路径相关的操作,比如拼接路径、解析路径、获取路径的绝对路径等。
module.export={
entry: {//打包多个文件 a1\a2打包后生成的文件,分别对应的是index1.js/index2.js
a1:path.join(__dirname, 'src', 'index1.js'), //__dirname绝对路径,在那个文件夹,要打包的文件1
a2:path.join(__dirname, 'src', 'index2.js'), //__dirname绝对路径,在那个文件夹,要打包的文件2
}
output: {//定义打包后的文件输出路径、文件名以及其他输出相关的选项,绝对路径。
path: path.join(__dirname, "dist"),//path指定输出文件的存放路径,path.join函数来拼接目录路径;名称为dist打包后存放的文件夹
//代表当前模块文件所在的目录的绝对路径,是一个全局变量,返回的是一个字符串
//文件名
filename: "[name].js" // 动态生成文件名,根据a1/a2决定
},
//mode模式分开发模式 生产模式
mode: "development"
}
使用npm run build 进行打包文件
2.1, 打包一个js文件其中引入了css文件
webpack本身只能识别js文件,其他文件都需要通过loder加载器进行编译成webpack能识别的js语言
首先创建一个js文件并且引入一个css文件
然后在终端安装一下
npm install --save-dev css-loader style-loader
const path = require("path");//path 模块是内置的核心模块之一,path模块的主要作用是帮助你处理路径相关的操作,比如拼接路径、解析路径、获取路径的绝对路径等。
module.export={
entry: path.join(__dirname, 'src', 'index.js'), //打包单个文件,__dirname绝对路径,在那个文件夹,要打包文件
output: {//定义打包后的文件输出路径、文件名以及其他输出相关的选项,他是一个绝对路径。
path: path.join(__dirname, "dist"),//path指定输出文件的存放路径,path.join函数来拼接目录路径;名称为dist打包后存放的文件夹
//代表当前模块文件所在的目录的绝对路径,是一个全局变量,返回的是一个字符串
//文件名
filename: "index.js" // '[name].[ext]' 占位符允许动态生成文件名,//指定输出的文件名
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
//mode模式分开发模式 生产模式
mode: "development"
}
使用npm run build 进行打包文件
插件
常用的插件有:
'HtmlwebpackPlugin'用于生成HTML文件、
// 'HtmlwebpackPlugin'生成html文件
//1、首先在终端安装:
//在终端输入npm install html-webpack-plugin --save-dev //作为开发依赖
//用于将生成的html文件并自动将打包好的脚本文件添加到html中。
//2、在webpack.config.js中添加一下这段代码
//跟入口出口都是同级
const HtmlWebpackPlugin = require('html-webpack-plugin');
//使用require导入'HtmlWebpackPlugin';'html-webpack-plugin'生成html文件的过程,在打包过程中会自动生成一个包含正确资源链接的html文件,方便浏览器加载和使用
module.exports = {//是将配置对象导出module是配置的属性,是一个包含各个模块规则的对象
plugins:[ //配置了一个plugins属性他的值是数组
new HtmlWebpackPlugin({
template:'./src/index.html',//指定模板HTML的文件路径
filename:'index.html' ,//生成打包好的文件下的(dist)的HTML文件的文件名称名
})
]
}
'MiniCssExtractPlugin'用于提取CSS文件、有助于优化页面加载速度、提供缓存优化,并提高可维护性。
//MiniCssExtractPlugin 用于单独提取css
//首先在终端
//在终端输入npm install mini-css-extract-plugin --save-dev //作为开发依赖
//2、在webpack.config.js中添加一下这段代码
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//将css打包后的js文件中抽取出来,生成独立的css文件。通过抽取css到独立的文件可以实现样式的分离和优化。通过配置入口文件、输出文件、模块解析规则等。
module.exports = {
// ...其他配置
module: {
rules: [
{
test: /\.css$/,//用来匹配css文件
use: [MiniCssExtractPlugin.loader, 'css-loader'],//解析css文件并处理依赖关系
// 当匹配到css 结尾的文件时,把css提取到单独文件中,而不是以内联样式的方式存在。
内联的意思就是直接嵌入到html元素的style属性中的方式,而不是放在外部的css文件中。
//将css从打包的jacascript文件中抽离出来,生成一个单独的css文件。
},
],
},
plugins: [//配置了一个plugins属性
new MiniCssExtractPlugin({//创建A了一个MiniCssExtractPlugin实例,并传入一个配置对象作为参数
filename: 'styles.css', // 生成的CSS文件名
//filename指定生成了css文件名,就是将打包好的css提取到单独的css文件中,而不是以内联样式的方式存在。生成css文件会根据指定的文件名保存在输出目录中
}),
],
};
'CleanWebpackPlugin‘用于清理输出目录等。:输出目录中会生成新的构建文件,而旧的构建文件可能仍然存在于目录中。
//CleanWebpackPlugin
//用于清理输出目录的插件,可以在每次构建之前喊出指定的输出目录,以确保每次构建都是从一个干净的状态开始的;
//1.安装CleanWebpack
npm install clean-webpack-plugin --save-dev
//2.在webpack中引入CleanWebpackPlugin插件
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
//3.在配置对象中的plugins数组中添加CleanWebpackPlugin的实例
module.exports = {
plugins:[
new CleanWebpackPlugin({
//默认情况下,CLeanWebpackPlugin将清理webpack的输出目录,指定要清理的目录或文件使用传递选项来配置插件
cleanOnceBeforeBuildPatterns: ['dist'], // 清理输出目录
cleanAfterEveryBuildPatterns: ['temp/*.js'], // 清理每次构建后的临时文件,temp目录下所有以.js为后缀的文件
cleanStaleWebpackAssets: true // 清理未使用的 webpack 资产,清理上一次构件中生成的、但在当前构件中不适用webpack
})
]
}
3.1安装插件,每次打包都需要手动创建一个html文件,然后引入打包好的文件,这样比较麻烦就要借助到插件了
1、
在终端输入npm install html-webpack-plugin --save-dev //作为开发依赖
用于将生成的html文件并自动将打包好的脚本文件添加到html中。
2、
const HtmlWebpackPlugin = require('html-webpack-plugin');
//导入html-webpack-plugin插件
module.exports = {//CommonJS语法 是一个模块化的JavaScript规范
plugins:[
new HtmlWebpackPlugin ({//配置了一个HtmlWebpackPlugin作为插件
template:'./src/index.html',//指定模板HTML的文件路径
filename:'index.html' ,//生成打包好的文件下的(dist)的HTML文件的文件名称名
//构建过程中生成一个html文件,该文件以指定的模块文件为基础,将构建生成的JavaScript文件自动注入到html文件中,并将文件生成的html文件输出,简化了手动创建
})
]
}
3、如图
使用npm run build 进行打包文件就可以看到效果了
4.1每次内容发生改变时都需要手动输入命令进行打包所以下边安装一下实时编译的功能也叫热模块替换
- npm install webpack-dev-server --save-dev
- //用来安装webpack开发服务器,是一个基于express的开发服务器,提供实施重载和热模块替换功能
- //.webpack的开发服务器是一个用于开发环境的轻量级服务器,它可以在开发过程中提供实时的编译和构造,并支持热模块替换;热模块替换是一种webpack提供的功能,它允许在应用程序运行时,无需刷新整个页面的情况下,替换、添加或删除模块,从而实现实时更新和快速开发调试。
4.2在package.json文件中配置
添加
"scripts":{
"build":"webpack",//运行普通的webpack打包构建
"dev":"webpack-dev-server"// 把文件保存到内存中,而不是写入硬盘;每次内容发生改变时,会自动重新编译并在浏览器中实时刷新
}
5.1、安装依赖因为编译得代码都是es6的如果有低版本的会编译错误
5.2在终端
npm install @babel/core @babel/preset-env babel-loader --save-dev
//用于安装Babel相关的依赖,Babel用于将ES6+的代码转换后兼容的es5代码。
5.3在根目录中创建一个.babelrc的配置文件
{ //预设:babel一系列插件的集合,这个插件可以帮助我们把es6的代码转换成
es5 "presets":["@babel/preset-env"] //刚才安装好的预设,进行转换
}
5.4在webpack.config.js文件中配置
module.exports = {
module:{
rules:[
{
test:/\.js$/, //js的正则表达式,并转换为ES5语法
loader:'babel-loader', // loader的顺序是从下到上的
include:path.join(__dirname,'src'),//处理src的文件下的
exclude:/node_modules/ //排除
}
]
}
}
5.5使用这样就可以自动刷新了
npm run build serve//开启开发服务器,并在浏览器中自动打开应用程序。没当修改源代码时,会自动重新编译并通知实时刷新将更改反映在浏览器中
vue2打包
1.安装webpack,在终端
npm install vue@2 vue-loader@15 vue-template-compiler@2 --save-dev
vue安装的版本是2 vue-loader的15版本 ,适用于vue2的版本 vue-template-compiler解析vue模板语法,并转换为js代码会将模板编译成渲染函数,将数据和模板进行绑定,生成最终的HTML输出。
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');//负责解析'vue'文件中的各个部分(模板、脚本、样式)并将其转换为webpack可处理的模块 = require('vue-loader/lib/plugin');//负责解析'vue'文件中的各个部分(模板、脚本、样式)并将其转换为webpack可处理的模块
const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//将css打包后的js文件中抽取出来,生成独立的css文件。通过抽取css到独立的文件可以实现样式的分离和优化。通过配置入口文件、输出文件、模块解析规则等。
module.exports = {
// 1. 指定入口文件
entry: './src/main.js',
// 2. 指定输出文件
output: {
path: path.resolve(__dirname, 'dist'),//在这个配置中,所有生成的文件将被输出到该目录下。
//它能够确保生成的路径是标准化的绝对路径,无论在哪个操作系统上运行代码,路径都能够正确解析。
filename: 'main.js',
},
// 3. 配置模块解析规则
module: {
rules: [
{
// 处理.vue文件
test: /\.vue$/,
loader: 'vue-loader',
},
{
// 处理.js文件, 使用Babel进行转义
test: /\.js$/,
exclude: /node_modules/, //排除/node_modules/
use: {
loader: 'babel-loader',
},
},
{
// 处理css文件
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,//将css文件单独处理
'css-loader',//加载css文件
],
},
],
},
// 4. 配置解析别名
resolve: {
alias: {
vue$: 'vue/dist/vue.esm.js',//在引入vue.js时可以使用别名'vue'
},
},
// 5. 配置插件
plugins: [
new VueLoaderPlugin(), // 处理.vue文件的模块转换为js模块
new HtmlWebpackPlugin({ // 根据模板生成html文件,将打包后的脚本的样式自动引入
template: './index.html',
filename: 'index.html',
}),
new MiniCssExtractPlugin({ // 将CSS抽取到单独的文件
filename: 'style.css',
}),
],
// 6. 配置开发服务器
devServer: {//用于配置开发服务器的相关参数,如监听的端口、内容目录等
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
},
};
2.在package.json文件中添加或替换
"scripts": {
"build": "vue-cli-service build --fix"
}
3.在vue.config.js中添加
publicPath: './'
vue3打包
vue2和vue3之间存在较大的差异,包括编译模板方式、组件注册、API的变化等,因此不能使用vue2的打包项目的方式进行打包vue3;
1.首先在vue3项目的根目录下运行一下命令,安装必要的依赖:
npm install vue@next @vue/compiler-sfc vue-loader@next css-loader style-loader file-loader --save-dev
//意思就是会在项目中的 node_modules 文件夹中安装这些依赖,并且它们将被添加到项目的 package.json 文件中的 devDependencies 部分,以确保在开发过程中使用这些依赖。这些依赖的安装将允许你开发 Vue 3 项目并使用 webpack 进行打包,同时获得 Vue 3 的新特性和优势。
2.创建webpack配置文件:在项目根目录下创建一个`webpack.config.js`文件,用于配置webpack。
const path = require('path'); // 导入 Node.js 的 path 模块,用于处理文件路径
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 导入 HtmlWebpackPlugin 插件,用于生成 HTML 文件
const { VueLoaderPlugin } = require('vue-loader'); // 导入 VueLoaderPlugin,用于正确编译 Vue 组件
module.exports = (env, argv) => {
// 通过 argv.mode 获取当前运行的模式(开发模式或生产模式)
const isDevelopment = argv.mode === 'development'; // 判断是否是开发模式
return {
// 指定入口文件的路径,根据你的项目结构进行修改
entry: './src/main.js',
// 配置输出文件的文件名和输出路径
output: {
// 在开发模式下,输出文件名为 'bundle.js',在生产模式下使用带哈希值的文件名
filename: isDevelopment ? 'bundle.js' : 'bundle.[contenthash].js',
// 输出目录的绝对路径,使用 Node.js 的 path.resolve() 方法解析
path: path.resolve(__dirname, 'dist'),
},
// 配置不同类型文件的处理规则
module: {
rules: [
{
// 匹配以 .vue 结尾的文件
test: /\.vue$/,
// 使用 vue-loader 来处理 Vue 文件
loader: 'vue-loader',
},
{
// 匹配以 .css 结尾的文件
test: /\.css$/,
// 使用 style-loader 和 css-loader 处理样式文件
use: ['style-loader', 'css-loader'],
},
{
// 匹配以 .png、.jpg、.jpeg、.gif 和 .svg 结尾的文件
test: /\.(png|jpe?g|gif|svg)$/i,
// 使用 file-loader 处理图片文件
loader: 'file-loader',
options: {
// 输出的文件名,使用原始文件名和哈希值
name: '[name].[hash].[ext]',
// 输出的目录,将图片复制到 'dist/images' 目录下
outputPath: 'images',
},
},
],
},
// 配置模块的解析规则
resolve: {
// 解析文件时自动添加的扩展名,可以在引入文件时省略后缀
extensions: ['.js', '.vue'],
},
// 配置插件
plugins: [
// 生成 HTML 文件的插件
new HtmlWebpackPlugin({
// 模板文件路径,根据你的项目结构修改路径
template: './public/index.html',
}),
// VueLoaderPlugin 用于将 Vue 组件正确地编译
new VueLoaderPlugin(),
],
// 配置开发服务器
devServer: {
// 开启热模块替换功能,实现代码修改时浏览器无刷新更新
hot: true,
// 打包完成后自动在浏览器中打开应用程序
open: true,
},
// 配置 Source Map,用于在开发和生产模式下进行调试
devtool: isDevelopment ? 'eval-cheap-module-source-map' : 'source-map',
// 配置优化项
optimization: {
// 生产模式下开启 Tree Shaking,去除无用的代码
usedExports: true,
},
};
};