Webpack学习笔记

提升开发体验

  • 使用Webpack进行打包后js文件,是经过编译的代码,看起来很不直观,不方便开发人员进行检查和纠错

  • 可以使用SourceMap(源代码映射)进行优化

js 复制代码
// 开发模式下配置 - 只有行映射,更省时
devtool:"cheap-module-source-map"

// 生产模式下配置 - 包含行列映射,更精准
devtool:"source-map"

提升打包速度

  • 开发时修改了其中一个模块的代码,Webpack默认会全部重新打包编译,速度很慢

  • 可以使用HotModuleReplacement(HMR/热模块替换),在程序中替换、添加或删除模块,不用全量重载

js 复制代码
// devServer配置 - 默认对css起作用,js不起作用
hot: true

// js支持hot
if (module.hot) {
  module.hot.accept("./js/count", function (count) {
        console.log(count);
    }) // 配置支持hot的js,第二个参数是模块内容变化后的处理逻辑,可以去掉
}

include、exclude

  • 配置包含和排除的文件,提升处理效率,只能配置一种
js 复制代码
// 只处理src文件夹下的文件
include: path.resolve(__dirname, '../src')
// 排除node_modules
exclude: /node_modules/,

Cashe

  • 每次打包时js文件都需要经过Eslint和Babel的编译,速度较慢

  • 可以缓存之前的Eslint检查和Babel的编译结果,提升打包速度

js 复制代码
cacheDirectory: true, // 开启babel缓存
cacheCompression: false // 关闭缓存文件压缩

Thread多进程

  • 当项目越来越庞大时,打包速度回越来越慢,js的打包涉及到eslint、babel、Teser(Webpack默认配置使用)想要提升打包速度就是提升js的打包速度

  • 可以采用多进程同时处理js文件的方式来进行优化,要比单进程打包快多了

js 复制代码
{
  test: /\.js$/,
  include: path.resolve(__dirname, "../src"),
  use: [
    {
      loader: 'thread-loader',
      options: {
          works: threads
      }
    },
    {
      loader: 'babel-loader',
      options: {
          cacheDirectory: true,
          cacheCompression: false
      }
    }
  ]
}

plugins: [
  new ESLintPlugin({
      context: path.resolve(__dirname, '../src'),
      cache: true,
      cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
      threads, // eslint启用多进程
  })
]

optimization: {
  minimizer: [
      new Terser({
          parallel: threads
      })
  ]
},

Tree Shaking减少代码体积

  • 开发时我们定义了一些工具函数库,或者引入第三方工具函数库或组件库,如果没有做特殊处理,打包时会引入整个库,实际上却只需要极小部分的功能

  • 可以使用TreeShaking来移除Javascript中没有使用上的代码,它依赖ES Module

  • Webpack默认开启了这个配置,不需要额外操作

Babel

  • Babel为编译的每个文件都插入了辅助代码,使体积过大,Babel对一些公共方法使用了非常小的辅助代码,比如_extend。默认情况下会被添加到每一个需要它的文件中

  • 可以将这些辅助代码作为一个独立模块,来避免重复引入

ImageMinimizer

  • 项目引入了较多图片时,图片体积过大,未来请求速度比较慢

  • 可以使用image-minimizer-webpack-plugin 对图片进行压缩,减少图片体积

shell 复制代码
npm i image-minimizer-webpack-plugin -D 
npm i imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D

Code Split优化代码运行性能

  • 打包代码会将所有的js文件打包到一个文件中,体积太大了。

  • 可以对将打包生成的文件进行代码分割,生成多个js文件,渲染哪个页面,只加载某个js文件,这样加载的资源少,速度就更快。

  • 多入口

js 复制代码
entry: {
  app: './src/app.js',
  main: './src/app.js',
},
output: {
  path: undefined, // 开发模式没有输出
  filename: '[name].js', // webpack命名方式,【name】为文件配置名称
},
  • 提取公共模块
js 复制代码
optimization: {
	splitChunks: {
		chunks: "all"
	}
}
cacheGroups: {
  default: {
    minSize: 0,
    minChunks: 2,
    priority: -20,
    reuseExistingChunk: true,
  }
}
  • 按需加载动态引入 - 路由懒加载就是这样实现的
javascript 复制代码
// 修改引入方式,会把引入的js文件切割成单独的文件,按需加载
import('./count')
	.then(module => 
		// 加载成功
		console.log(module);
	)
	.catch(error => 
		// 加载失败
	)
  • 给模块命名
javascript 复制代码
// 使用webpack魔法命名
import(/* webpackChunkName: "xxx" */ './count')
	.then(module => 
		// 加载成功
		console.log(module);
	)
	.catch(error => 
		// 加载失败
	)

// webpack配置文件
output: {
	chunkFilename: "static/js/[name].js" // 必须和webpack魔法命名保持一致
}
  • 统一命名配置
js 复制代码
filename: 'static/js/[name].js' // 最重要的是[name].js

// 资源类文件统一地址
assetModuleFilename: 'static/media/[hash:10][ext][query]'

Preload(立即加载资源)/ Prefetch(浏览器空闲时才开始加载资源)

  • 共同点是只加载不执行,但是兼容性有问题,具体可以查询插件官网

  • 一般使用Prefetch比较,但是兼容性问题太严重了,所以酌情使用

Network Cache

  • js文件最终编译打包为多个文件,文件相互以来会导致编译时未变化的js文件也重新编译,因为文件名称内的hash值变化了

  • 可以使用runtimeChunk进行hash名称的记录,未变化的js文件不再次参与编译

js 复制代码
contentHash:10 // 配置文件hash值

optimization: {
	runtimeChunk: {
		name: (entrypoint) => `runtime~${entrypoint.name}.js`,
	}
}

Core-js

  • babel对js的兼容性处理使用了@babel、preset-env智能预设来处理,它能将ES6的一些语法进行编译转换,比如箭头函数和...运算符等,但是如果是async函数、promise对象和数据的一些方法等,它没办法处理

  • 此时可以使用core-js来做ES6以及以上API的polyfill,彻底解决兼容性问题

js 复制代码
npm i core-js

// 直接引用
import "core-js";

// 按需引入
import "core-js/es/promise";

// 自动按需引入 - babel.config.js文件
presets: [
  ['@babel/preset-env', {
    useBuiltIns: "usage",
    corejs: 3
  }]
],

PWA技术

  • 断网后网页无法访问

  • 可以采用渐进式网络应用程序,是一种类型与native app体验的Web app技术

  • 其中最重要的是在离线时应用程序能够继续运行的功能,内部通过Service Workers技术实现

shell 复制代码
npm i workbox-webpack-plugin -D
  • 清除console.log语句的loader
js 复制代码
modeule.exports = function(content) {
	return content.replace(/console\.log\(.*\);?/g, "");
}
  • 使用loader的this.getOptions方法时需要传入schema配置json
js 复制代码
// schema.json
{
	'type': 'object',
	'properties': {
		'author': {
			'type': 'string'
		}
	}
	addtionalProperties: false,
}

// xx-loader.js
const schema = require('./schema.json');
// 使用schema配置的规则进行验证,验证通过获取options,否则程序 会报错 
const options this.getOptions(schema);
  • 在资源文件的处理loader配置中添加以下语句,可以防止使用webpack默认处理,只使用指定的loader进行处理
js 复制代码
{
	test: /xxx/,
	loader: './loaders/xxx-loader', 
	type: 'javascript/auto' // 添加该配置
}
  • 自定义的style-loader可以实现css代码插入页面的处理,但是无法对css引入的其他资源进行处理,所以还是需要使用css-loader进行处理
js 复制代码
{
	test: /\.css/,
	loader: ['./loaders/style-loader', 'css-loader'],
}
  • 定义debug命令
js 复制代码
"scripts": {
	"debug": "node --inspect-brk ./node_modules/webpack-cli/bin/cli.js"
}

PS:如果有需要补充的内容,请在评论区留言

转载时请注明"来自掘金 - EvenZhu"
相关推荐
明辉光焱12 分钟前
[Electron]总结:如何创建Electron+Element Plus的项目
前端·javascript·electron
牧码岛32 分钟前
Web前端之汉字排序、sort与localeCompare的介绍、编码顺序与字典顺序的区别
前端·javascript·web·web前端
开心工作室_kaic1 小时前
ssm111基于MVC的舞蹈网站的设计与实现+vue(论文+源码)_kaic
前端·vue.js·mvc
晨曦_子画1 小时前
用于在 .NET 中构建 Web API 的 FastEndpoints 入门
前端·.net
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:在 PDF 文件中添加图像作为页面背景
前端·pdf·.net·spire.pdf
咔咔库奇1 小时前
ES6基础
前端·javascript·es6
Jiaberrr1 小时前
开启鸿蒙开发之旅:交互——点击事件
前端·华为·交互·harmonyos·鸿蒙
徐小夕2 小时前
Flowmix/Docx 多模态文档编辑器:V1.3.5版本,全面升级
前端·javascript·架构
Json____2 小时前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库