首页 > 其他分享 >webpack 八股文

webpack 八股文

时间:2022-10-24 14:44:45浏览次数:55  
标签:文件 八股文 loader webpack 模块 js 打包

面试题
1)webpack核心概念
1. entry 入口:以某个文件为入口开始打包
2. output 输出
- 打包后资源输出到哪里去
3. loader 加载器
- webpack 本身只能识别 json、js 模块,其他模块一旦加载就会报错
- 需要借助 loader 将其它模块编译成js
4. plugins 插件
- loader 功能有限,要想做功能更加强大的工作交给插件,比如资源压缩等功能
5. mode
- 模式:开发环境(development)和生产环境(production)
2)Webpack常用loader和plugins
1. 处理JS文件
eslint-loader
在package.json中配置eslintConfig来指示eslint-loader到底要干什么事
enfore: 'pre' 优先执行
babel-loader
在package.json中(webpack配置文件中也行)配置babel来指示babel-loader到底要干什么事
terser-webpack-plugin
是一个优化和压缩JS资源的插件
2. 处理Vue文件
vue-loader(语法)
3. 处理JSX文件
babel-loader
presets: ['@babel/preset-react']
4. 处理CSS文件
开发环境:创建style标签插入样式
style-loader(创建style标签插入样式)
css-loader/less-loader / sass-loader / stylus-loader(解析样式)
postcss-loader(css兼容性)
px2rem-loader自动将px转换为rem
生产环境:提取单独css文件,将来通过link引入
// 从js文件中单独提取css文件
MiniCssExtractPlugin.loader(loader后面是插件)(还需要配置插件(抽取出来的文件名称) new MiniCssExtractPlugin)
OptimizeCssAssetsPlugin 压缩css文件
css-loader/less-loader / sass-loader / stylus-loader
postcss-loader
5. 处理HTML文件
// 以 './src/index.html' 为模板创建新的html文件
// 新html文件结构和原来一样 并且 会自动引入webpack打包生成的js/css资源
// 还可以进行html文件压缩配置
new HtmlWebpackPlugin({ template: './public/index.html' })
html-loader 解决 html 中 img src 为 解析前路径的问题,找不到资源
6. 处理图片文件
url-loader
limit: 10000 小于10kb一下的图片会被base64处理
7. 处理其他类型文件(如字体图标、音视频等)
file-loader 原封不动输出
8.补充
CleanWebpackPlugin // 自动删除由于重命名在打包的重复文件
3)是否写过Loader?简单描述一下编写loader的思路?
1.loader 的本质为函数,它接收上一个 loader 产生的结果或者资源文件作为入参,返回编译后的文件内容。
返回值应该是 String 或者 Buffer,因为这样webpack才能将字符串js脚本转成ast语法树
2.函数中有异步操作或同步操作,异步操作通过 this.callback 返回,同步操作直接返回内容即可。
3.一般在编写loader的过程中,保持功能单一,避免做多种功能
// 导出一个函数,source为webpack传递给loader的文件源内容
module.exports = function(source) {
const content = doSomeThing2JsString(source);
// 如果 loader 配置了 options 对象,那么this.query将指向 options
const options = this.query;
// 可以用作解析其他模块路径的上下文
console.log('this.context');
this.callback(null, content); // 异步
return content; // 同步
}
4)是否写过Plugin?简单描述一下编写Plugin的思路?
1.webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在特定的阶段监听这些事件添加的自定义功能。
2.插件必须有apply 方法,这样才能访问compiler实例
3.传给每个插件的 compiler对象是同一个引用,因此不建议修改
4.异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住
5)那你再说一说Loader和Plugin的区别?
1)Loader 本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。
因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译的工作。
2)Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
扩展webpack功能,包括:打包优化,资源管理,注入环境变量等
5)如何优化 Webpack 的构建速度?
1. HMR 热模块替换
为什么要用?
默认情况下,一旦修改了代码,全部代码重新编译刷新,速度慢(全体刷新)
有什么作用?
只更新修改的模块,其他模块不变(局部更新)
怎么使用?
devServer: { hot: true }
new webpack.HotModuleReplacementPlugin()
注意:默认情况下只有样式文件有HMR功能(style-loader),JS是没有的
开启JS的HMR功能:
1. 手写JS代码 --> module.hot.accpet('模块路径', () => {})
2. 在Vue使用 --> vue-loader
3. 在React使用 --> react-hot-loader
2. cache 缓存(针对js)
eslint和babel两个任务处理JS文件,时间一般会比较长,为了让其重新构建速度更快
可以使用缓存。
eslint --> cache: true
babel --> cacheDirectory: true

cache-loader(可以缓存其它文件)放置在要缓存loader的后面
注意:一般只针对耗时长的任务:eslint-loader/babel-loader/vue-loader
3. oneOf
作用:让模块只被一个loader处理,其他的就不看了(默认情况会被所有的loader处理)~
能够提升打包速度~,如果一个文件需要被两个loader处理,那么可以一个放在oneof里面一个放在外面
注意:eslint-loader(外) / babel-loader(内)
4.多进程构建:HappyPack(不维护了)、thread-loader
5.缩小打包作用域:exclude/include (确定 loader 规则范围)
6.cdn引入第三方库:将第三方库通过 CDN 引入,不打入 bundle 中
//html文件中
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
//webpack中
externals: {
// jQuery不被打包进来
jquery: 'jQuery'
}
7.DLL:第一次单独打包第三方库,后面运行webpack不在打包第三方库,只要在引入使用即可,使用 DllPlugin 生成manifest.json 引用文件,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间。
4)如何优化 Webpack 的打包包体积?
1.压缩代码(html/js/css/图片)
HtmlWebpackPlugin/生产环境下会自动压缩js代码mode: 'production'/OptimizeCssAssetsWebpackPlugin
2.提取页面公共资源
//单入口
可以将node_modules中代码单独打包一个chunk最终输出
//多入口
可以将node_modules中代码单独打包一个chunk最终输出
自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
optimization: {
splitChunks: {
chunks: 'all'
}
}
3.Tree shaking
打包过程中检测工程中没有引用过的模块并进行标记,在资源压缩时将它们从最终的bundle中去掉(只能对ES6 Modlue生效) 开发中尽可能使用ES6 Module的模块,提高tree shaking效率
4.动态Polyfill(core-js实现js兼容性处理)

6)webpack编译过程
1)初始化参数:从配置文件和Shell语句(sricpt脚步命令)中读取并合并参数,得出最终的配置对象
2)用上一步得到的参数初始化Compiler对象
3)加载所有配置的插件
4)执行对象的run方法开始执行编译
5)根据配置中的entry找出入口文件
6)从入口文件出发,调用所有配置的Loader对模块进行编译
7)再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
8)根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk
9)再把每个Chunk转换成一个单独的文件加入到输出列表
10)在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
7)聊一聊Babel原理吧
Babel大概分为三大部分:
解析:将代码转换成 AST
转换:访问 AST 的节点进行变换操作生产新的 AST
生成:以新的 AST 为基础生成代码
6)webpack如何实现代码分离
入口起点:使用 entry 配置手动地分离代码。
防止重复:设置splitChunks去重和分离 chunk。
动态导入:通过模块的内联函数调用来分离代码。
webpack分包
目前webpack实现分包的方式主要有以下两种:
第一种是根据我们的业务去配置不同的打包入口,也就是我们会有多个打包入口同时打包,输出多个打包结果。
第二种就是采用ESM的动态导入功能,去实现模块的按需加载,这个时候webpack会把我们动态加载的模块单独输出到一个bundle中。
1.多入口打包
entry:{ // 将entry配置成一个对象,来设置多个打包入口
index:"./src/index.js",
album:"./src/album.js"
},
2.提取公共模块
optimization: {
splitChunks: {
//第三方包和import()语法引入的文件单独打包一个文件,打包的文件名可以通过output中的chunkFilename属性去配置
//入口文件中公共代码提取在一个文件中,默认30k
chunks: 'all',
name: 'common'
}
}
3.动态导入模块
动态导入就是采用ES Module的动态导入。import()
//配置第二步
import(/* webpackChunkName: 'test' */'./test')
.then((result) => {
// result为文件内容
})
.catch(() => {
console.log('文件加载失败~');
});
6)配置解析模块路径别名
resolve:解析模块的规则
resolve: {
// 配置解析模块路径别名: 简写路径
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路径的后缀名
extensions: ['.js', '.json', '.jsx', '.css']
}
9)sourcemap(代码调试用的)
webpack通过配置可以自动给我们source maps文件,map文件是一种对应编译文件和源文件的方法,可以解决在浏览器运行代码时报错,定位报错代码的源文件位置(生成的map文件是给浏览器使用的)
配置webpack的devtool字段
//false表示什么都没做
//source-map(使用它就行,包含最完整的信息)包含行和列信息,包含loader的sourcemap(包含loader可以定位到loader编译前的文件就是源文件,不包含就是定位到编译后的文件)
//inline-source-map包含行和列信息,包含loader的sourcemap,不会单独生成一个map文件,会内嵌到编译后的文件中
//cheap-source-map包含行信息不包含列信息,不包含loader的sourcemap
//cheap-module-source-map包含行信息不包含列信息,包含loader的sourcemap
//开发环境推荐使用cheap-module-eval-source-map,线上推荐使用hidden-source-map
devtool: 'false',
10)chunk和bundle和module
打包前一个入口和它依赖的模块是一个chunk,打包后就变成一个bundle(一个是打包前叫法,一个是打包后叫法)
module就是一个模块文件,一个 chunk 应该包括多个 module
11)hash、chunkhash和contenthash/文件指纹是什么?
文件指纹是指打包后输出的文件名和后缀。用来处理webpack缓存
Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改
Chunkhash:和 Webpack 打包的 chunk 有关,不同的 entry 会生出不同的 chunkhash
Contenthash:根据文件内容来定义 hash,文件内容不变,则 contenthash 不变
JS的文件指纹设置
//设置 output 的 filename,用 chunkhash。
output: {
filename: '[name][chunkhash:8].js',
path:__dirname + '/dist'
}
CSS的文件指纹设置
//设置 MiniCssExtractPlugin 的 filename,使用 contenthash。
plugins:[
new MiniCssExtractPlugin({
filename: `[name][contenthash:8].css`
})
]
图片的文件指纹设置
//设置file-loader的name,使用hash。
rules:[
{
test:/\.(png|svg|jpg|gif)$/,
use:[{
loader:'file-loader',
options:{
name:'img/[name][hash:8].[ext]'
}
}]
}]

13)文件监听原理呢?
在发现源码发生变化时,自动重新构建出新的输出文件。
Webpack开启监听模式,有两种方式:
启动 webpack 命令时,带上 --watch 参数
在配置 webpack.config.js 中设置 watch:true
原理:轮询判断文件的最后编辑时间是否变化,
14)说一下 Webpack 的热更新原理吧
其实是自己开启了express应用,添加了对webpack编译的监听,添加了和浏览器的websocket长连接,当文件变化触发webpack进行编译并完成后,会通过sokcet消息告诉浏览器准备刷新。而为了减少刷新的代价,就是不用刷新网页,而是刷新某个模块,
webpack-dev-server可以支持热更新,通过生成 文件的hash值来diff比对需要更新的模块,浏览器再进行热替换
15)在实际工程中,如何保证各个loader按照预想方式工作?
可以使用 enforce 强制执行 loader 的作用顺序,pre 代表在所有正常 loader 之前执行,post 是所有 loader 之后执行。
19)webpack如何实现持久化缓存
1.服务端设置http缓存头(cache-control)
2.打包进行splitChunk(代码分割)
3.保持hash值的稳定
optimization: {
splitChunks: {
chunks: 'all'
},
// 每个文件都会保留引用文件的hash值,只要子文件的改变依然会导致,父文件缓存的失效
// 把所有的文件hash值都打包在runtime.js文件中可以解决这个问题
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
}
}
20)输出的资源按照文件夹分类
1.js
//入口文件输出在build/js/built.js
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
20)webpack5新特性
1)持久化缓存(内置了cache配置)
webpack会缓存生成的webpack模块和chunk,来改善构建速度,缓存在webpack5中默认开启,
2)移除Node.js的polyfill
webpack4带了许多Node.js核心模块的polyfill,一旦模块中使用了任何核心模块(如crypto),这些模块就会被自动启用
webpack5不再自动引入这些polyfill,需要自己配置
3)更强大的tree-shaking
tree-shaking就在打包的时候剔除没有用到的代码
webpack4 本身的 tree shaking 比较简单,主要是找一个 import 进来的变量是否在这个模块内出现过
webpack5可以进行根据作用域之间的关系来进行优化
4)模块联邦
业务模块抽离成一个单元供多个应用使用

 

面试题:
1)webpack核心概念
2)Webpack常用loader和plugins!
3)是否写过Loader?简单描述一下编写loader的思路?
4)是否写过Plugin?简单描述一下编写Plugin的思路?(tapable库)
5)那你再说一说Loader和Plugin的区别?
6)如何优化 Webpack 的构建速度?!
7)如何优化 Webpack 的打包包体积?!
6)webpack编译过程
9)聊一聊Babel原理吧
10)webpack如何实现代码分离
10)配置解析模块路径别名
12)sourcemap(代码调试用的)
13)chunk和bundle和module
14)hash、chunkhash和contenthash/文件指纹是什么?
15)文件监听原理呢?!
16)说一下 Webpack 的热更新原理吧
17)在实际工程中,如何保证各个loader按照预想方式工作?
18)webpack如何实现持久化缓存!
18)输出的资源按照文件夹分类
19)webpack5新特性!

标签:文件,八股文,loader,webpack,模块,js,打包
From: https://www.cnblogs.com/lxxxxStar/p/16821368.html

相关文章

  • 【Webpack】418- 深度优化 Webpack 性能,翻倍构建性能
    0.背景随着构建体系不断完善、构建体验不断优化,webpack已经逐渐成为了前端构建体系的一大霸主,对于工作中的真正意义上的前端工程项目,webpack已经成为了我们前端构建技术选......
  • webpack学习
    目录什么是webpack?什么是构建工具?为什么要用webpack?webpack的核心配置Entryoutputloaderpluginsmodewebpack打包命令小结:webpack配置信息样板基本配置信息react项目中路径......
  • vue笔记 webpack配置vue环境
       import时需要写完整的路径,用webpack之后进行模块化开发,不需要引入完整的路径。 无需写完整的路径,直接去node_modules目录下面找     vue在npmrun......
  • vue笔记 10 webpack 安装命令npm install [email protected] -g
             ......
  • webpack与rollup打包工具
    webpack与rollup打包工具jxZheng冷静&&勤思考​关注他  一、rolluprollup是一个JavaScript模块打包器,可以将小块代码编译成大块复杂的代......
  • Webpack 和 Rollup:一样但又不同
    Webpack和Rollup:一样但又不同油墨香^_^于2022-07-2909:53:16发布247收藏1分类专栏:#Webpack文章标签:webpackjavascript前端版权Webpack专栏收录该内容38......
  • Webpack完整打包流程分析
    前言webpack在前端工程领域起到了中流砥柱的作用,理解它的内部实现机制会对你的工程建设提供很大的帮助(不论是定制功能还是优化打包)。下面我们基于webpack5源码结构,对......
  • Webpack中的plugin插件机制
    大家有没有遇到过这些问题:webpack打包之后的文件没有压缩静态文件要手动拷贝到输出目录代码中写了很多环境判断的多余代码上一篇「webpack核心特性」loader说到......
  • 如何不借助第三方web服务器启动(webpack)vue打包后的dist目录
    很多时候,我们打包完成了,想看看打包后的项目是否有问题,那么会借助于除webpack之外的第三方工具例如http-servernginx等那么是否有办法能将就开发环境的localhost:xxxx/di......
  • 习惯用脚手架的你, 了解Webpack这些知识点吗?
    大概准备春招两个月了,也没找到坑位埋自己,来看看webpackwebpack官网:www.webpackjs.com对于前端的大兄弟来说,每天在前端摸爬滚打,各方征战,那对于webpack肯定再熟......