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配置
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>