webpack的基础了解
什么是webpack
本质上是一种前端资源编译工具,即类似于vite的打包工具。Webpack使用的是js代码进行开发,基于Node平台运行。
使用webpack所需要的一些前置node基础
输出webpack打包的数据时,常常需要使用node中的path模块,因此在这里做一个简单讲解
-
path.resolve()和__dirname
__dirname的意思为获取当前文件的绝对路径
首先我们来看这是官方文档引用的一段配置示例(暂时不需要了解这些配置项的具体含义),在output即输出的path路径中我们使用到了path.resolve这个方法
const path = require('path'); module.exports = { entry: './path/to/my/entry/file.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'my-first-webpack.bundle.js', }, };这个方法会按照传入的参数从右向左返回一个绝对路径,同时如果没有带盘符,则会默认使用项目所在盘符作为开始。
这行代码的意思即为返回当前配置文件的位置后添加dist(没有目录则会默认添加),例如该配置文件的位置为C:\project,则该path为C:\project\dist
如何使用webpack
-
首先需要安装对应的包
npm i -D webpack webpack-cli这两个包是作为webpack 的基础,前者用于源代码中使用,后者用于识别命令行中的命令 -
配置文件
如果没有进行配置,则默认会以/src/index.js作为入口文件,并以/dist/main.js作为出口 -
执行编译命令
npx webpack执行编译命令
webpack打包的核心流程
webpack的配置
关于如何使用webpack,最重要的是需要配置,即打包的逻辑
- 配置位置:项目根目录下的webpack.config.js文件进行配置
- entry为入口起点,可以选择一个文件或多个文件等
- output为输出点,可以选择输出位置以及名称等
- webpack只认识js文件,webpack的本质也是将各种文件转换为js文件,对于css,lass等文件则需要使用loader进行识别
loader
常见的loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 "load(加载)" 模块时预处理文件。
-
css-loader
如何将已经导入的css文件进行打包,需要使用css-loader和style-loader进行打包(由于仅仅用于打包,因此只需要在开发环境进行即可)
css-loader即将css文件进行解析,style-loader则将解析后的文件进行调用
npm install css-loader style-loader -D接着在module属性中添加该规则
module: { rules: [ { test: /.css$/, //正则表达式,匹配以css文件,不需要添加"",用以表示所有的css文件 use: ["style-loader", "css-loader"], //使用这两个loader }, ], } // 请注意:loader是从后往前执行,所以use的顺序不可以进行改变 -
less-loader,sass-loader
对于less和sass等的处理器,则需要安装对应的loader进行转换即可
-
postcss-loader
postcss-loader是一个用于 Webpack 的加载器(loader),它允许你在构建过程中使用 PostCSS 处理 CSS 文件。我们可以通过这个loader来进行例如添加浏览器前缀(适应不同的浏览器),代码优化,使用最新的css语法等一些功能首先需要下载
npm i -D postcss-loaderrules: [ { test: /.css$/, use: [ 'style-loader', // 将 CSS 注入到 DOM 中 'css-loader', // 解析 CSS 文件,并将 CSS 转换为 CommonJS 模块 'postcss-loader' // 使用 PostCSS 处理 CSS ] }同时,如果想要使这个postcss进行工作,我们需要创建一个
postcss.config.js文件来配置你想要使用的 PostCSS 插件:// postcss.config.js module.exports = { plugins: [ 'autoprefixer', // 添加浏览器前缀 'cssnano' // 压缩 CSS ] }; // 注意:这些插件需要提前下载npm i autoprefixer cssnano -D // 目前已经较少使用autoprefixer,更适用的为postcss-preset-env
- babel-loader
babel用于将一些带有新特性的js代码转为es5,比如将es6中的箭头函数转为普通函数、将es6中的const转为var。
首先需要进行下载npm i -D @babel/core @babel/preset-env babel-loader
module.exports={
test:/.js$/,
use:[
{
loader:"babel-loader",
options:{
presets:["@babel/preset-env"] //babel预设
}
}
],
}
5. asset资源模块
webpack内置了加载静态资源的工具,因此不需要下载直接引入即可
-
asset/resource
module.exports={ module:{ rules:[ { test:/.(png|jpe?g|svg|gif)$/, //(a|b)表示可a也可c,?表示可选 type:"asset/resource" //注意这里的key是type而不是use } ] } }通过此方式打包后的文件引用图片时默认会发送网络请求来获取数据,会产生多余的网络资源消耗
-
asset/inline
会将引用的资源转换为base64编码,会导致原始js文件变大 -
asset
指定类型为asset,会根据情况选择两种中的一种,比如文件阈值//配置1 module.exports={ module:{ rules:[ { test:"/.(png|jpe?g|svg|gif)$/", type:"asset", parser:{ dataUrlCondition:{ maxSize:6*1024 //这里即阈值,单位需要是字节数(byte),6*1024代表6kb } } } ] } }同时,也可以进行打包后生成文件位置,名称(默认为哈希值)的配置
//配置2 rules:[ { test:/.(je?pg|png|svg|gif)$/, type:"asset", generator:{ filename:"img/[name]_[hash:8][ext]" //在img文件夹下以原图片名+hash值+后缀的格式输出,这里的[]表示占位符 } } ]
plugin
webpack 插件是一个具有apply方法的 JavaScript 对象。
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' }),
],
-
资源管理clean插件
clean-webpack-plugin插件可以使得二次打包前先删除上次打包后的文件夹,可以使得二次打包不需要的文件(如图片)自动删除。
npm i clean-webpack-plugin -Dimport {CleanWebpackPlugin} from "clean-webpack-plugin" //也可以使用 const CleanWebpackPlugin=require('clean-webpack-plugin') module.exports={ plugin:[new CleanWebpackPlugin()] } -
html插件
html-webpack-plugin插件可以在打包后默认引入一个html文件导入所打包的js文件
npm i html-webpack-plugin -Dconst HtmlWebpackPlugin=require("html-webpack-plugin") module.exports={ plugin:[new HtmlWebpackPlugin()] }
可以自己添加title属性
-
DefinePlugin插件
define-plugin插件用于环境变量注入,使得变量一处定义,处处可用。该插件是webpack内置插件,不需要安装,从webpack库中引入。
const {DefinePlugin} from "webpack" module.exports={ plugins:[ new DefinePlugin({ PRODUCTION: JSON.stringify(true) //配置一些全局属性 }) ] } //也可以通过node方式进行引入 const webpack = require('webpack'); // 或者const {DefinePlugin} = require('webpack') plugins: [ // 插件列表 new webpack.DefinePlugin({ // 定义全局变量的插件 PRODUCTION: JSON.stringify(true), // 设置PRODUCTION为true字符串化 PRODUCTION;"true" //也可以使用这个方式,因为此插件使用时直接替换值,因此需要添加引号 }) ]