github.com/atbulbs/web…javascript
官方推荐的一些打包分析插件 webpack.js.org/guides/code…css
安装和使用webpack-bundle-analyzer github.com/webpack-con…html
# 生成stats.json文件
$ webpack --profile --json > stats.json
复制代码
官方文档: developers.google.com/web/updates…前端
参考文档: blog.logrocket.com/using-the-c…java
// 查看代码覆盖率
// dev tool > command + shift + P > Show Coverage > 录屏
复制代码
官方文档: webpack.js.org/api/module-…node
function getComponent () {
return import(/* webpackChunckName: 'lodash' */'lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
复制代码
官方文档: webpack.js.org/guides/code…webpack
实现第一次加载的时候就是最快的, webpack推荐交互的代码放到异步加载的模块里去写 prefeching/preloading可实现网页空闲时预先加载异步模块git
// src/click.js
export default funciton clickHandler () {
console.log('clicked')
}
// src/index.js
window.document.addEventListener('click', () => {
// prefetch会等待核心代码加载完成, 页面空闲时去加载prefetch的文件
// webpackPreload会和核心代码一块儿加载
import(/* webpackPrefetch: true */'./click.js').then({ default: func } => func())
})
复制代码
官方文档 webpack.js.org/guides/code…es6
分割业务代码和库代码, 否则打包文件会很大, 首次访问加载时间会很长github
并且若是不分割, 修改业务代码后, 从新访问, 又所有得从新加载库代码
分割方式: 配置 + 同步引入 与 动态引入(无需作任何配置)
动态引入文档 webpack.js.org/guides/code…
function getComponent () {
// jsonp引入
// 动态的import, 实验性的语法
// npm i babel-plugin-dynamic-import-webpack -D
return import('lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
// .babelrc 动态引入
// npm i -D babel-plugin-dynamic-import-webpack
{
plugins: ['dynamic-import-webpack']
}
复制代码
SplitChunksPlugin官方文档: webpack.js.org/plugins/spl…
// splitPlugin 配置
optimization: {
// SplitChunksPlugin config
// 以下是官方默认配置
splitChunks: {
// async 只对异步代码生效
// all 对同步异步都作代码分割, 可是同步代码还需cacheGrops配置
// initial 只对同步代码作分割
chunks: 'async',
// 若是引入的模块大于minSize才作代码分割
minSize: 30000,
// 对于大于maxsize的模块尝试进行二次代码分割
maxSize: 0,
// 打包后的文件至少有多少个chunk文件引入这个模块才进行代码分割
minChunks: 1,
// 同时加载的模块数量,
// 在打包前5个库的时候会生成5个js文件,
// 超过5个就再也不作代码分割
maxAsyncRequests: 5,
// 入口文件作代码分割的最大文件数量
maxInitialRequests: 3,
// 自动命名定界符
automaticNameDelimiter: '~',
// 让cacheGroups里的filename生效
name: true,
// 缓存组, 把库文件先放到缓存里, 再根据test规则分组合并打包
cacheGroups: {
// vendors: false
vendors: {
// 若是是node_modules里面的文件, 就打包到vendors组里
test: /[\\/]node_modules[\\/]/,
// 分组时的优先级
priority: -10
// 组文件的名字 vendors.js, 否则会是 vendors~main.js
// filename: 'vendors.js'
},
// 被分割的代码的默认的配置, 没有test, 全部模块都符合要求
default: {
// 至少被引用了2次
minChunks: 2,
priority: -20,
// 复用已被分割打包过了的模块
reuseExistingChunk: true,
// 组的文件名
// filename: 'common.js',
}
}
}
}
复制代码
官方文档: webpack.js.org/guides/lazy…
前端框架结合webpack实现懒加载: webpack.js.org/guides/lazy…
// 点击页面才会加载lodash代码
function getComponent () {
// 懒加载并非webpack里面的一个概念, 而是ES的import语法,
// webpack能识别这种语法, 对import引入的模块作代码分割
// 至关于对optimization的splitChunks作了配置
return import(/* webpackChunckName: 'lodash' */'lodash').then(({ default: _ }) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '*')
return element
})
}
window.document.addEventListener('click', () => {
getComponent().then(el => window.document.body.appendChild(el))
})
复制代码
官方文档: webpack.js.org/guides/tree…
官方文档: webpack.js.org/configurati…
关于静态模块结构的官方文档: exploringjs.com/es6/ch_modu…
// Tree Shaking只支持 ES Module(静态引入), 不支持Common JS(动态引入)
// development mode 默认没有tree shaking
// production mode 不须要这个optimization
optimization: {
usedExports: true
}
// package.json
"sideEffects": false, // false时对全部模块摇树
// 实践
"sideEffects": [
// 否则打包时会忽略 @babel/polly-fill, 由于其没有导出对象, 只在window上挂载了对象
"@babel/polly-fill",
// 对css不摇树
"*.css"
],
复制代码
官方文档: webpack.js.org/configurati…
devtool: 'none' // 关闭sourcemap
devtool: 'source-map' // 会生成一个.map文件
devtool: 'inline-source-map' // .map文件会被打包到js文件里, 错误提示会精确到第几行第几列
devtool: 'cheap-inline-source-map' // 只精确到行, 不精确到列, 提示性能, 并且只会提示业务代码的错误, 不提示loader和第三方模块的错误
devtool: 'cheap-module-inline-source-map' // 提示loader和第三方模块的错误
devtool: 'eval' // 用js eval效率最高, 提示不全面, 不展现行数
devtool: 'cheap-module-eval-source-map' // 开发时的最佳实践
devtool: 'cheap-module-source-map' // 生产时的最佳实践
复制代码