webpack笔记

95 阅读2分钟

loader

webpack的loader本质是一个函数接受源码输出处理后的源码,可同步可异步,异步需要调用webpack的async生成callback函数

该函数接受两个参数,第一个参数是error,第二个参数是处理后的源码。

plugin

生命周期

基于tapable 的事件

compiler:在启动webpack时创建,代表完整的webpack环境配置。包含options、loader、plugin

compilcation:一次资源版本构建,每次文件变化时生成新的

HOR热加载原理:

webpack-dev-server = express+webpack-dev-middleware

webapck-dev-middleware 1.将打包结果放到内存,用对象对应文件系统。2.监听文件变化

webpack-dev-server 会启动一个websocket链接,并在打包结果内注入websocket客户端代码和热更新代码

文件变化重新编译后,通知客户端,用jsonp方式请求新的模块文件,调用hotcheck更新代码

打包构建流程

1.初始化,读取配置,入口文件

2.构建ast树,loader执行

3.生成chunck

优化技巧

webpack缓存

webpack4 babel-loader/eslint-loader/cache-loader webpack5 cache.type='filesystem'

module.exports = {
    //...
    cache: {
        type: 'filesystem'
    },
    //...
};

esbuild-loader

没有使用一些自定义的 babel-plugin (如 babel-plugin-import) 不需要兼容一些低版本浏览器(esbuild 只能将代码转成 es6) 那你就可以大胆使用 esbuild-loader 为你的项目提效了~

module.exports = {
    module: {
      rules: [
-       {
-         test: /\.js$/,
-         use: 'babel-loader',
-       },
+       {
+         test: /\.js$/,
+         loader: 'esbuild-loader',
+         options: {
+           loader: 'jsx',  // Remove this if you're not using JSX
+           target: 'es2015'  // Syntax to compile to (see options below for possible values)
+         }
+       },

        ...
      ],
    },
  }

模块延迟加载

会分割成多个小的js文件,按需加载

// src/router/index.js
const routes = [
 {
   path: '/login',
   name: 'login',
   component: login
 },
 {
   path: '/home',
   name: 'home',
   // lazy-load
   component: () => import('../views/home/home.vue'),
 },
]

Gzip

需要发送header中带Accept-Encoding: gzip,deflate的请求

客户端

const CompressionPlugin = require('compression-webpack-plugin')
// config
plugins: [
   // gzip
   new CompressionPlugin({
     algorithm: 'gzip',
     threshold: 10240,
     minRatio: 0.8
   })
 ]

服务端

tomcat中修改${TOMCAT_HOME}/conf/server.xml

<Connector port="8080" protocol="HTTP/1.1" 
   connectionTimeout="20000"
   redirectPort="8443" 
   compression="on" //开启
   compressionMinSize="2048" // 进行压缩的最小值,低于该值的文件不进行压缩(单位B,默认2048,即默认2k)
   noCompressionUserAgents="gozilla,traviata"//不需要进行压缩的浏览器,当浏览器类型为指定的类型时,不进行压缩
   compressableMimeType="text/css" />// 需要压缩的文件类型(多个类型以逗号分隔)

node中配置

const compression = require('compression')
// 在其他中间件前使用
app.use(compression())

http强缓存

webpack + express 实现文件精确缓存

webpack配置

output: {
	filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].js',
    path: path.resolve(__dirname, '../dist'),
},

express配置

app.use((req, res, next) => { // 将 index.html 设为 no-cache
     if(~req.url.indexOf('html')) {
         res.setHeader('Cache-control', 'no-cache')
     }

     next()
 })

 app.use(express.static('dist', {
     etag: false,
     maxAge: 1000 * 60 * 60 * 24 * 365, // 缓存一年
 })) // 将dist设为根目录

tomcat配置

<filter>
 <filter-name>ExpiresFilter</filter-name>
 <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
 <init-param>
    <param-name>ExpiresByType image</param-name>
    <param-value>access plus 10 days</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType text/css</param-name>
    <param-value>access plus 10 days</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType application/javascript</param-name>
    <param-value>access plus 10 days</param-value>
 </init-param>
</filter>

<filter-mapping>
 <filter-name>ExpiresFilter</filter-name>
 <url-pattern>/*</url-pattern>
 <dispatcher>REQUEST</dispatcher>
</filter-mapping>