webpack的部分问题

常用的loader和plugin和devtool

  • loader

    1. babel-loader 转译js代码

      ​ 可以使用include和exclude帮助我们避免不必要的转译,开启缓存转译可以提升工作效率

      use:{
        exclude:/(node_module|bower_components)/,
        loader:'babel-loader?cacheDirectory=true'
        }
      
    2. css-loader 转译css文件 对@import和require处理

    3. style-loader 把css-loader转译后得结果插入到脚本中 显示样式

    4. sass-loader/less-loader预编译和转换sass/less文件

    5. file-loader 将加载文件、图片 import/require() 解析为url,将文件发送到输出文件夹,返回文件的url

    6. url-loader 是file-loader的扩展可以设置对图片的大小限制,小于限制用base64编译返回输出,大于限制使用file-loader传递参数

  • plugin

    1. DllPlugin 作用和optimization.splitChunk作用相似,拆分bundles,提高构建速度
    2. SplitChunksPlugin 分离公共的第三方模块及业务代码
    3. MiniCssExtractPlugin 抽离css,删除和压缩css代码,是extract-text-webpackplugin插件的webpack5升级用法,可以实现contenthash,保证只要css文件内容不变,就不会重复构建css文件
    4. HtmlWebpackPlugin 为html文件动态引入外部资源给script、link添加编译后的hash,防止引用缓存文件问题、可以生成创建html入口文件,比如单页生成一个html入口文件,多页面生成多个html
    5. UglifyjsWebpackPlugin 删除和压缩js代码
    6. CleanWebpackPlugin 每次编译会删除上一次编译的dist文件
    7. CopyPlugin 复制开发环境中public中的文件
  • devtool

    生产环境中使用 inline-source-map

    开发环境中使用 eval-cheap-module-source-map

    生成source-map文件,可以看到清晰的build后的代码结构,方便出错调试

    • cheap可以提高souremap的生成效率
    • eval 提高持续构建效率

代码分割的几种方式

  • 在入口entry手动分离代码
  • 使用optimization.splitChunks、SplitChunkPlugin分离代码
  • 动态引入 使用import导入,使用的时候再去下载对应的文件
  • Tree-shaking webpack内置优化,去除没有用到的代码
  • 防止重复 CommonsChunkPlugin去重和分离chunk

SplitChunkPlugin的用法

optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 0,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          // test: /[\\/]node_modules[\\/]/,
          test(module) {
            if (/[\\/]node_modules[\\/]/.test(module.resource) && module.resource.lastIndexOf('.css') === -1) {
              return true
            }
          },
          priority: -10,
          reuseExistingChunk: true,
          filename: function(chunk) {
            return 'js/chunks-vendors-[contenthash:8].js'
          },
          // exclude: '*.css'
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  }
  • chunks
    1. saync 表示只从异步加载的模块(动态加载 import())进行拆分
    2. initial 表示拆分同步代码
    3. all表示以上两者都拆分
  • minSize表示分离后最小块文件的大小,单位是字节
  • minRemainingSize
  • minChunks 引入的次数大于1次进行代码分割
  • maxAsyncRequests 最大异步请求数量 就是同时加载的模块最大模块数量
  • maxInitialRequests 入口文件做代码分割最多分成30个文件
  • enforceSizeThreshold
  • cacheGroups 位于node_modules中的模块做代码分割 使用正则,根据模块的分类进行打包
  • priority 根据优先级决定打包到哪个组里,打包到优先级高的组里
  • reuseExistingChunk 如果一个模块已经被打包过了,那么再打包时就忽略这个上模块

热替换

devServer中hot:ture启动热替换,改变html页面不刷新,只更新改变的部分

Tree Shaking

ESM es module

去掉不需要,用不到的代码或者模块

sideEffects 在package.json中设置,webpack认为可以删除的就可以删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2roak9x-1629114600765)(C:\Users\yt\AppData\Roaming\Typora\typora-user-images\image-20210802093249316.png)]

不删除css文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNFpH1rE-1629114600769)(C:\Users\yt\AppData\Roaming\Typora\typora-user-images\image-20210802093359226.png)]

关于TreeShaking的原理

Tree shaking是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫Dead code elimination

tree shaking只能在静态modules下工作,由于ES6模块加载是静态的,因此整个依赖树可以被静态的推导出解析语法树。

原理:

  • ES6 Modules引入静态分析,编译的时候能够判断到底加载了哪些模块
  • 静态分析程序流,判断哪些模块和变量没有被引用,进而删除对应代码。

common.js和es6的模块导出区别

我们在webpack中使用的export和import,会经过Babel转换为CommonJs规范。

  • CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。
  • CommonJS模块是加载时运行,ES6模块是编译时输出接口
  • CommonJS是单个值的导出,ES6可以导出多个
  • CommonJS是动态语法可以写在判断里,ES6静态语法只能写在顶层
  • CommonJS的this是当前模块,es6的this是undefined

webpack Plugin的工作原理

读取配置的过程中会先执行 new HelloPlugin(options) 初始化一个 HelloPlugin 获得其实例。

初始化 compiler 对象后调用 HelloPlugin.apply(compiler) 给插件实例传入 compiler 对象。

插件实例在获取到 compiler 对象后,就可以通过compiler.plugin(事件名称, 回调函数) 监听到 Webpack 广播出来的事件。 并且可以通过 compiler 对象去操作 Webpack。

https://blog.csdn.net/frontend_frank/article/details/106205260 可以看一下这位博主的文章。

preload和prefetch

可以在html中的link标签添加rel=preload等

<head>
    <link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Demi.otf') %>" crossorigin>
    <link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Regular.otf') %>" crossorigin>
</head>

在webpack中

插件preload-webpack-plugin,结合htmlWebpackPlugin在构建构成中插入link标签

const PreloadWebpackPlugin = require('preload-webpack-plugin');
...
plugins: [
  new PreloadWebpackPlugin({
    rel: 'preload'as(entry) {  //资源类型
      if (/\.css$/.test(entry)) return 'style';
      if (/\.woff$/.test(entry)) return 'font';
      if (/\.png$/.test(entry)) return 'image';
      return 'script';
    },
    include: 'asyncChunks', // preload模块范围,还可取值'initial'|'allChunks'|'allAssets',
    fileBlacklist: [/\.svg/] // 资源黑名单
    fileWhitelist: [/\.script/] // 资源白名单
  })
]

include属性默认asyncChunks,表示预加载异步js模块;allAssets表示预处理所有类型资源(图片、字体等)

preload用来声明当前页面的关键资源,强制浏览器尽快加载;而prefetch用来声明将来可能用到的资源,在浏览器空闲时进行加载。

编写loader和plugin

compile编译

垫片 装下面两个包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTfZB5kJ-1629114600775)(C:\Users\yt\AppData\Roaming\Typora\typora-user-images\image-20210802114123567.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1lCd7CG-1629114600778)(C:\Users\yt\AppData\Roaming\Typora\typora-user-images\image-20210802114129914.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJx2DyH3-1629114600783)(C:\Users\yt\AppData\Roaming\Typora\typora-user-images\image-20210802114203601.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值