构建工具问题整理

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、工具函数少
适用场景 项目类型 第三方库、项目类型 第三方库
相关推荐
QGC二次开发1 分钟前
Vue3 : Pinia的性质与作用
前端·javascript·vue.js·typescript·前端框架·vue
云草桑12 分钟前
逆向工程 反编译 C# net core
前端·c#·反编译·逆向工程
布丁椰奶冻18 分钟前
解决使用nvm管理node版本时提示npm下载失败的问题
前端·npm·node.js
AntDreamer32 分钟前
在实际开发中,如何根据项目需求调整 RecyclerView 的缓存策略?
android·java·缓存·面试·性能优化·kotlin
Leyla44 分钟前
【代码重构】好的重构与坏的重构
前端
影子落人间1 小时前
已解决npm ERR! request to https://registry.npm.taobao.org/@vant%2farea-data failed
前端·npm·node.js
世俗ˊ1 小时前
CSS入门笔记
前端·css·笔记
子非鱼9211 小时前
【前端】ES6:Set与Map
前端·javascript·es6
6230_1 小时前
git使用“保姆级”教程1——简介及配置项设置
前端·git·学习·html·web3·学习方法·改行学it
想退休的搬砖人1 小时前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js