构建工具问题整理

webpack

webpack需要了解其构建过程,以及常用的loader、plugin,热更新原理,配置等等

webpack配置大致的组成部分

  • mode: prodcution、development
  • entry: 入口文件
  • output: 输出形式
  • loaders: 加载常见的loader有 css-loader、style-loader、scss/less-loader、vue-loader
  • plugin: 插件,常见的plugin:html-webpack-plugin、clean-webpack-plugin

说一下webpack的构建过程

  1. 初始化配置,包含命令行的参数,webpack.config.js等参数组合形成的配置数据
  2. 根据入口不同有不同的chunk,每一个chunk的构建过程是:
md 复制代码
检查当前是否已经被依赖而构建了
将文件形成AST抽象语法树
根据AST分析出依赖文件
替换依赖函数,require换成_webpack_require,并把相对路径转为绝对路径这个过程并没有改变文件本身
保存转换后的代码,并添加到依赖表中去,表中key为chunkname,value是转换后的文件
根据依赖表循环以上过程,直到文件没有依赖或者都已经构建过了的依赖
完成后生成当前的chunkid、chunkname、hash
  1. 多个chunk包,合并生成bundle文件输出,并形成一个hash到名字中

webpack热更新原理

  1. 本地修改代码保存
  2. webpack编译,文件hash修改了
  3. HMR服务知道文件已经修改,通过websocket通知浏览器文件发生变化
  4. runtime运行时,重新读取minifest来下载和更新页面

webpack proxy原理,为什么可以解决跨域

过程是:将开发环境的数据请求,代理到指定的服务器上,返回数据

解决跨域:因为跨域是浏览器为了保护站点安全的设计,服务端请求服务端是没有跨域的

编写loader和plugin的思路(loader、plugin原理)

loader和plugin的区别

  • loader是文件加载器,重在转换;运行在输出文件之前
  • plugin是webpack扩展能力,目的是为了解决loader无法解决的事情,可以在整个编译周期中生效

编写loader的思路

loader的本质是一个函数,对于函数:

  • 函数的入参是对应的源文件
  • 函数的this指向webpack实例,所以loader函数最好不要使用箭头函数
  • loader配置的参数通过this.query拿到
  • 函数的返回值为目标文件

编写plugin思路

  • plugin通常会输出一个构造函数(类),且必须包含apply方法
  • apply的参数是compiler,compiler包含webpack所有的配置信息,如loader,plugin
  • 通过complier钩子去监听对应的状态,再执行回调
  • 在回调中compilation作为参数做一系列的事情,如addEntry添加编译入口
  • webpack给compilation对象提供了一系列的方法来让开发者更好的定制开发需求
compiler钩子

compiler支持监听机制,在文件修改重新编译时可以拿到实例上的所有配置

compilation钩子

compilation实例能够访问所有的模块和他们的依赖由compiler创建

如何通过webpack优化性能

  1. html、css、js、文件、静态资源等压缩
js 复制代码
const TerserWebpackPligin = require('terser-webpack-plugin')
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')

optimization: {
    minimize: true,
    minimizer: [
        new TerserWebpackPligin({ // js去空格
            parallel: true // 启动多核压缩
        }),
        new CssMinimizerWebpackPlugin({ // css去空格
            parallel: true
        })
    ]
},
plugin: [
    new HtmlWebpackPlugin({
      minify: {
          minifyCss: false, // 是否压缩css
          collapseWhiteSpace: true // 是否折叠空格
          removeComments: true // 是否移除注释
      }
    }),
    new CompressionWebpackPlugin({ // 压缩
        test: /\.(css|js)$/, // 哪些文件需要压缩
        threshold: 500, // 设置文件大小
        miniRatio: 0.7, // 压缩比例
        algorithm: 'gzip' // 使用什么算法
    })
]
  1. tree shaking 将没用的模块过滤掉(tree shaking)
  2. 代码分离:使用webpack的splitChunksPlugin这个被webpack内置的插件,
css 复制代码
module.exports = {
    optimization:{
        splitChunks:{
            /*
            * all: 全部分离
            * initial: 同步包分离
            * async: 异步包分离
            */
            chunks:"all" 
        }
    }
}

如何提升webpack的构建速度

  1. 根据不同的项目复杂度开启多进程,使用的loader是thread-loader
  2. webpack5开启缓存
  3. 并行压缩使用的是terser-webpack-plugin
  4. 复杂业务根据不同的业务场景打包不同的包

其他的构建工具有哪些,优缺点有哪些

工具 webpack vite rollup
优点 生态完整、丰富的loader和plugin支持几乎你可能遇到的所有的问题 按需编译、速度快、HMR更新更快 打包产物干净、生成包体积更小
缺点 大型项目打包会慢,限制webpack5支持缓存之后好一些了 prod仍然时候的rollup在打包,对css支持不太好、相对年轻还需要大量的使用者来验证 不支持HMR、工具函数少
适用场景 项目类型 第三方库、项目类型 第三方库
相关推荐
代码搬运媛4 小时前
Jest 测试框架详解与实现指南
前端
counterxing5 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq5 小时前
windows下nginx的安装
linux·服务器·前端
之歆5 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜6 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108086 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen7 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
Patrick_Wilson8 小时前
知识沉淀的四层模型:从个人笔记到企业资产,让文档真正长出复利
面试·程序员·ai编程
humcomm8 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy8 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程