webpack基础知识-保姆级别的,欢迎各位哥哥姐姐前来打卡,不对的地方,多多指导下
webpack是什么?
webpack是一种前端资源构建工具,一个静态模块打包器。在webpack看来,前端的所有资源文件都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。
核心打包原理
打包的主要流程如下:
- 需要读到入口文件里面的内容。
- 分析入口文件,递归的去读取模块所依赖的文件内容,生成AST语法树。
- 根据AST语法树,生成浏览器能够运行的代码
常见的模块解析包
- @babel/parser:将获取到的模块内容 解析成AST(es6的)语法树
- @babel/traverse: 遍历AST语法树
- @babel/core @babel/preset-env:ES6的AST转化成ES5的AST
- style-loader: 将css添加到DOM的内联样式标签style里
- css-loader:允许将css文件通过require的方式引入,并返回css代码,(解析css文件内的css代码,将 CSS 转化成 CommonJS 模块,)
- less-loader 处理less
- sass-loader 处理sass
- file-loader:分发文件到output目录并返回相对路径
- url-loader:和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
- html-minify-loader 压缩HTML
- babel-loader 用babel来转换ES6文件到ES5
- raw-loader:加载文件原始内容(utf-8)
- json-loader:加载 JSON 文件(默认包含)
有哪些常见的Plugin?你用过哪些Plugin?
- ignore-plugin:忽略部分文件
- html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)
- mini-css-extract-plugin: 分离样式文件,CSS 提取为独立文件,支持按需加载
- clean-webpack-plugin: 目录清理
- uglifyjs-webpack-plugin:不支持 ES6 压缩 (Webpack4 以前)
- terser-webpack-plugin: 支持压缩 ES6 (Webpack4)
- webpack-bundle-analyzer: 可视化 Webpack 输出文件的体积 (业务组件、依赖第三方模块)
- HappyPack:HappyPack 能让 webpack 把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。因此可以很大程度上优化打包速度。
loader 和 plugin 不同
- loader 本质就是一个函数,是使wenbpack拥有加载和解析非js文件的能力,loader支持链式调用,从右至左执行,支持同步或异步函数
- plugin :基于事件流框架Tapable,可以扩展webpack的功能,使得webpack更加灵活。可以在构建的过程中通过webpack的api改变输出的结果
webpack构建流程
- 初始化参数,从配置文件和shell语句中读到的参数合并,得到最后的参数
- 开始编译:用合并得到的参数初始化complier对象,加载是所有配置的插件,执行run方法开始编译
- 确定入口,通过entry找到入口文件
- 编译模块,从入口文件出发,调用所有配置的loader对模块进行解析翻译,在找到该模块依赖的模块进行处理
- 完成模块编译,得到每个模块被翻译之后的最终的内容和依赖关系
- 输出资源,根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,在把每个chunk转换成一个单独的文件加载到输出列表
- 输出完成,确定输出的路径和文件名,把内容写到文件系统中
- 在以上过程中,webpack会在特定的时间点广播出特定的事件,插件在监听感兴趣的事件后会执行特定的逻辑,改变webpack的运行结果。
webpack.config.js的基本配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
//path:Node.js Path模块 表示当前处置文件的目录
//path_resolve:将文件转为绝对路径
//__dirname:nodejs中的全局变量,指向当前文件所在的目录
//入库起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始,
//进入入口起点后,webpack会找到有哪些模块和库是入口起点(直接和间接)依赖的。
//默认值是./src/index.js,但你可以通过在webpack.config.js中配置entry属性,来指定一个(或多个)不同的入口起点
//单文件入口配置
module.exports={
//入口文件的配置项
entry:{
main:'./src/index.js'
},
//出口文件的配置项
output:{
path:path.resolve(__dirname,'dist'),//把dist目录变为绝对路径
filename:'index.js',//main.js输出到dist目录下的文件名称
},
//模块,例如解读css.图片如何转换,压缩
module:{},
//插件,用于生产模板和各种功能
plugins:[],
//配置webpack开发服务功能(安装完webpack=dev-server后,可以在这里做一些配置)
devServer:{
contentBase:path.join(__dirname,'dist'),//项目目录
compress:true,//gzip压缩
port:9000,//服务端口
//host:'0.0.0.0',//ip地址
https:true,//开启https
open:true,//启动后自动打开浏览器
proxy:{//代理
'/api':{//'/api'开头的请求会被代理
target:'http://localhost:3000',//代理地址
pathRewrite:{'^/api':''},//替换接口中'/api'字符串
}
}
}
}
//多文件入口配置
//添加多个entry对象,对象key作为最终输出文件名
//修改output的filename为动态获取文件名
// module.exports={
// //入口文件的配置项
// entry:{
// main:'./src/main.js',
// index:'./src/index.js'
// },
// //出口文件的配置项
// output:{
// path:path.resolve(__dirname,'dist'),//把dist目录变为绝对路径
// filename:'[name].js',//main.js输出到dist目录下的文件名称
// },
// //模块,例如解读css.图片如何转换,压缩
// //loaders的配置是修改webpack.config.js中的module属性中的配置
// //loaders执行顺序是倒序,后缀为.css的文件流会流转到css-loader,依次到style-loader,直至完成这条loaders链
// module:{
// /*
// noParse:过滤不需要解析的文件
// rules:设置解析规则数组
// {test:xxx}:匹配特定条件,一般是提供一个正则表达式或正则表达式的数组
// {include:xxx}:匹配特定条件,一般是提供一个字符串或字符串数组
// {exclude:xxx}:排除特定条件,一般是提供一个字符串或字符串数组
// {loader:[xxx]||xxx}:解析需要的loader,一般是提供一个字符串或字符串数组
// */
// rules:[
// {
// test:/\.css$/,
// use:['style-loader','css-loader']
// }
// ]
// },
// //插件,用于生产模板和各种功能
// plugins:[],
// //配置webpack开发服务功能
// devServer:{},
// /*
// webpack提供了一个Plugin插件配置项,可以讲项目中的js文件通过配置的插件进行解析
// 插件(Plugins)是用来拓展webpack功能的,他们会在整个构建过程中生效,执行相关的任务。
// Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程
// 中用来处理源文件的(jsx、scss、less),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程起作用
// 使用某个插件,需要通过npm进行安装,然后再webpack.config.js配置文件的plugins(试一个数组)配置项中添加该插件的实例
// */
// plugins:[
// new HtmlWebpackPlugin({
// template:path.join(__dirname,'/index.html')//new一个这个插件的实例,并传入相关的参数
// })
// ]
// }