构建工具问题整理

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的构建过程是:
检查当前是否已经被依赖而构建了
将文件形成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、文件、静态资源等压缩
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内置的插件,
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、工具函数少
适用场景 项目类型 第三方库、项目类型 第三方库

原文链接:https://juejin.cn/post/7329799331217080355 作者:salvatore

(0)
上一篇 2024年1月31日 下午4:10
下一篇 2024年1月31日 下午4:21

相关推荐

发表回复

登录后才能评论