webpack学习
简介
前端资源构建工具
就是将一个个小的功能功能包含起来,我们只需关心大工具的使用方法,
将前端一系列需要做的小操作整合盛一个大的构建工具一次性全操作完
静态模块打包器
- entry(入口文件)
作为起点,进行打包,告诉webpack打包哪些内容
- chunk
将我们项目中所需要的引入的模块梳理成依赖树状图依次加载进来
形成代码块(chunk) - bundel
将我们所引入的资源进行编译打包最后输出(bundel)
5大核心概念
entry
入口资源
三种方式:
string:单入口文件打包生成一个chunk,输出一个bundle文件,输入默认是main.js
array:不论几个数组中几个文件,最终都会将所以文件内容汇总到数组的第一个内容中进行输出
object:多入口文件。对应的多页面开发
loader
类似翻译官(因webpack只识别js)
使用loader转换成webpack能识别的资源
多个loader使用use:【】
单个loader使用:loader:""
排除某些应用:exclude
检查某些元素:include
oneof:只使用某些嵌套规则之一
plugins
处理更复杂的功能
图片压缩,css压缩等
output
出口:
path:输出文件目录
filename:输出文件,可以指定名称和目录
publicpath:所以引入资源的公共路径前缀(用于生产环境)
chunkfilename:非入口chunk名字(node-module|import等输出的名字)
library:把导出的结果赋值给变量,通过变量去引用。
librarytarget:指定运行环境(amd,cmd,common.js,umd,windows)
mode
环境
初体验
npm init
npm install webpack webpack-cli -g(安装到全局,可以通过执行指令去启动代码)
npm install webpack webpack-cli -D(安装到项目的开发环境中)
创建相关目录
运行webpack ./src/index.js -o ./build/built.js --mode=delopy'
开发环境配置
entry
loader
output
配置项
-
webpack-dev-server
devServer: { contentBase: path.resolve(__dirname, 'build'), compress: true, open: true, port: 3001 },
打包样式资源
- style-loader
创建style标签,将js中的样式资源插入进行,添加到head中生效
- css-loader
将css文件变成common.js模块加载js中,里面内容是样式字符串
打包html资源
- 插件:htmlwebpackplugin
打包图片资源
当webpack打包的发现多处使用同样的图片是,他不会重复打包
-
打包样式中的图片
- url-loader
esmodule:false(关闭es6模块化,使用common.js去加载)
name:[hash:10].ext - flie-loader
- url-loader
-
打包html中的图片
- html-loader
负责引入,处理html文件中的img图片。从而能被url-loader进行处理
问题:
当使用的时候由于url-loader默认使用es6模块解析,而html-loader引入图片是common.js。解析时会出现问题
解决:
关闭url-loader的es6模块化,使用common.js
- html-loader
生产环境
将css代码从js中抽离出来
代码压缩
处理兼容性问题
代码更规范。性更更强
在各个浏览器都可以运行
mini-css-extract-plugin
提取css为单独文件,将css从js中抽离出来
使用方式
use: [miniCssExtractPlugin.loader,css-loader']
plugins: [
new miniCssExtractPlugin({
filename: 'css/built.css'
})
],
postcss-loader
处理css兼容性问题
安装postcss-loader
配置2中方式
默认:''postcss-loader"
修改loader的方式:
use: [
// 将css从js中抽离出来
miniCssExtractPlugin.loader,
'css-loader',
{
// 处理css兼容性问题
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
],
pageage.json里面配置browserslist
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
optimize-css-assets-webpack-plugin
压缩css
babel-loader
处理es6语法兼容性问题。
性能优化
开发环境
优化打包速度
优化代码调试
-
优化打包速度
- HMR
在devServer中开启hot:true
在css下可以用使用,因为style-loader内部实现了热更新功能
html中不会更新,需要在入口文件中配置
js默认不会更新。可以配合缓存(hash|chunkhash|contenthash)去实现
- HMR
- 优化代码调试
- source-map
代码错误提示
分为内部和外联2中方式/开发环境和生产环境的需求不一样,根据需求可以选择不同
inline-source-map(内)
hidden-source-map(外)
eval-source-map(内)
nosource-source-map(外)
cheap-source-map(外)
cheap-module-source-map(外)
总结:开发环境使用eval-source-map
生产环境:source-map
生产环境
优化代码打包速度
优化代码运行的性能
-
优化打包速度
- oneof
当规则匹配时,只使用第一个匹配规则。
- 多进程打包thread-loader
用这个需要注意,除非你要加载的东西很多,不然进行启动也需要时间,通信也需要开销。
-
babel缓存
设置 cacheDirectory: true
{ test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], cacheDirectory: true } } },
-
dll
单独打包,将第三方库单独进行打包。最后通过插件注入html中
举例使用:
单独创建webpack.dll.js,
设置入口和出口文件。
引入webpack
通过webpack.DllPlugin创建出一个映射manifest.json
启动: webpack --config webpack.dll.js
在webpack.config.js中设置DllReferencePlugin的manifest就是我们生成的文件,这样打包时我们的文件就不会打包进入了
通过插件将单独打包生成的文件动态引入html中(add-asset-html-webpack-plugin)//webpack.dll.js const webpack = require('webpack') // 使用dll技术对某些库进行单独打包,比如vue、jq module.exports = { entry: { vue: ['vue'] }, output: { filename: '[name].js', path: __dirname + '/dll', library: '[name]_[hash]', //打包库里面向外暴露的内容叫什么名字 }, plugins: [ new webpack.DllPlugin({ name: '[name]_[hash]', path: __dirname + '/dll/manifest.json' //映射哪些库不需要打包 }) ], mode: 'development' }
//webpack.config.js new webpack.DllReferencePlugin({ manifest: __dirname + '/dll/manifest.json' })
- externals
将一些第三方库之类的通过cdn引入,排除这些依赖
官方:从输出的 bundle 中排除依赖
- oneof
-
优化线上代码性能
- 文件缓存
hash(每次修改都会被修改,因为css+js都使用同一个hash)
chunkhash(如果css在js中引用,即便js未修改也将重新加载)
contenthash(最优,根据文件内容生成hash) - tree-shaking
将一些不用的代码过滤掉
类似一个大树上,都很多我们需要的插件(绿色叶子),还有一些不用的插件(灰色叶子),当我们开启tree-shaking,就会抖抖到灰色的叶子
开启前提条件:
使用es6模块
开始生产模式
问题:可能会过滤到css等一些其他文件,需要在package.json中设置sideEffects - code-split
方式一:通过设置optimization:{splitchunks:{chunks:'all'}}
他可以件node-modules中的单独打包成一个chunk最终输出
自动分析放多入口文件中有没有公共到部分。如果有就会打包成一个单独的chunk
方式二:通过js代码的方式。import动态引入
方式三:通过修改口文件的名字实现 - 懒加载和预加载
懒加载:使用代码的分割的方式对代码实现懒加载。需要事件触发再去进行加载
预加载:等其他文件都加载完毕,等浏览器空闲的时候再去进行加载
注意除非保证用户一定去使用。不然也浪费
设置webpackPrefetch:true - pwa
渐进式网络开发应用程序(离线可访问)
通过插件workbox-webpack-plugin开启serviceWorker
需要处理兼容性问题
- 文件缓存
resolve路径配置优化
alias
简写路径
$css:__dirname+'src/css'
//页面使用时只需要:import ‘$css/common.css’
extensions
省略文件后缀,默认省略(.js|.json)可配置
extensions:['.js','.json','.css','.vue']
modules
告诉webpack解析模块时去哪找目录
modules:['node-modules']
devServer
contentBase:运行代码目录
compress:true开启代码压缩
port:端口
host:域名
hot:开启模块热更新(HMR)
open:自动打开浏览器
watchContentBase:监视目录下所有文件,一旦变化就reload
watchContentOptions:可以设置忽略的文件,比如(ignored:node-modules)
proxy:实现跨域,浏览器和服务器之前有同源策略的影响,但是服务器与服务器之间不存在跨域问题,我们可以使用代理服务器转发实现
clientLogLevel:''none.不启动服务器日志信息
optimization
splitchunks:{chunks:'all'}
runtimeChunk:{name: entrypoint => runtime~${entrypoint.name}
}处理缓存失效)
XMind: ZEN - Trial Version