常见面试题
一、ModuLe
webpack支持ESModule ,CommonJS,AMD,Assests.( image ,font,video,audio,json).
- ESM 关键字export , 允许讲ESM中内容暴露给其他模块. 关键字import .
import{ aa } from './a.js';
export{ bb } ;
//package.json
type:module->ESM type:commonjs->CommonJS
-
CommonJS module.exports, 允许将CommonJS中的内容暴露给其他模块. require
-
modules ,如何表达自己的各种依赖关系?
- ESM import语句
- CommonJs require
- AMD define require
- css/sass/less @import
二、chunk和bundLe
- Chunk Chunk是webpack打包过程中Modules的集合,是(打包过程中) 的概念. Webpack的打包是从一个入口模块开始, 入口模块引用其他模块, 其他模块引用其他模块.. webpack通过引用关系逐个打包模块, 这些module就形成了一个chunk. 如果有多个入口模块, 可能会产出多条打包路径。每条路径都会形成一个chunk.
- BundLe 是我们最终输出的一个或者多个打包好的文件.
- Chunk和Bundle的关系是什么? 大多数情况下, 一个chunk会生产一个bundLe .但是也有例外. 但是如果加了sourcemap, 一个entry , 一个chunk对应两个bundLe . Chunk是过程中代码块, BundLe是打包结果输出的代码块. Chunk在构建完成就呈现为BundLe.
- SplitChunk
- 常问:这段配置会产生几个chunk?
三、PLugin和Loader
- Loader 模块转换器,将非js模块转化为webpack能识别的js模块. 本质上,webpackLoader将所有类型的文件, 转换为应用程序的依赖图可以直接引用的模块.
- PLugin 扩展插件,webpack运行的各个阶段, 都会广播出对应的事件.插件去监听对应的事件.
- Compiler 对象,包含了webpack环境的所有配置信息, 包括options loader ,plugins, webpack启动的时候实例化, 它在全局是唯一的, 可以把他理解为webpack的实例,
- Compliation 包含了当前的模块资源,编译生成资源。 webpack在开发模式下运行的时候, 每当检测到一个文件变化, 就会创建一次新的Compliation.
四、简单描述一下webpack的打包过程
- 初始化参数:shell webpack.config.js
- 开始编译:初始化一个Compiler对象, 加载所有的配置,开始执行编译
- 确定入口:根据entry中的配置,找出所有的入口文件
- 编译模块:从入口文件开始, 调用所有的loader, 再去递归的找依赖
- 完成模块编译:得到每个模块被翻译后的最终内容以及他们之间的依赖关系
- 输出资源:根据得到依赖关系,组装成一个个包含多个module的chunk输出完成:根据配置,确定要输出的文件名以及文件路径
快速搭建
- 创建目录
- 运行 serve . 命令
- 初始化
yarn init --yes
- 安装依赖
yarn add webpack webpack-cli --dev
- 执行
yarn webpack --version
- 打包
yarn webpack --watch
- 修改配置
"scripts": {
"build": "webpack"
},
- 修改路径,尝试运行打包后文件
配置文件
- 添加文件 webpack.config.js
- 书写配置
const path = require('path')
module.exports = {
mode: 'none',
// 指定工作模式
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'output')
// path一定要是绝对路径,所以通过模块转换
}
}
工作模式
- 开发模式
yarn webpack --mode development
- 原始模式
yarn webpack --mode none
- 生产模式(默认)
yarn webpack --mode production
样式打包
- 安装loader
// 安装CSS模块资源加载器
yarn add css-loader --dev
// 安装style标签加载器
yarn add style-loader --dev
- 修改配置规则
module:{
rules: [{
test: /.css$/,
use: ['css-loader','style-loader']
}]
}
文件资源加载器
- 安装资源加载器
yarn add file-loader --dev
- 修改配置
publicPath: 'output/'
module:{
rules: [
{
test: /.png$/,
use: 'file-loader',
}]
}
常用loader
- 编译转换类
- css-loader
- 文件操作类
- file-loader
- 代码质量检查类
- eslint-loader
转化ES5
- 安装
yarn add babel-loader @babel/core @babel/preset-env --dev
- 配置
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets:['@babel/preset-env']
}
}
},
插件机制
-
loader:资源加载
-
plugin:除了资源加载以外其他自动化工作
- 打包前清除dist目录
- 拷贝静态文件到输出目录
- 压缩打包结果输出的代码
- 常见插件
- clean-webpack-plugin
- html-webpack-plugin
- copy-webpack-plugin
- 自定义插件
class MyPlugin{
apply(compiler){
console.log('启动插件')
compiler.hooks.emit.tap('MyPlugin', compilation => {
for (const name in compilation.assets){
if(name.endsWith('.js')){
const content = compilation.assets[name].source()
const without = content.replace(/\/\*\*+\*\//g,'')
compilation.assets[name] = {
source: ()=> without,
size:()=>without.length,
}
}
}
})
}
}
plugins: [
new MyPlugin(),
]
dev-server
- 安装
yarn add webpack-dev-server --dev
- 运行
yarn webpack-dev-server
- 配置文件
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
},
- 作用
- 为静态文件提供web服务
- 自动刷新和热替换(HMR)
- 支持配置代理服务,解决跨域问题
source map
- 映射源代码和转换后代码
- 配置 devtool: 'source-map'