Entry
Entry 用来指定webpack打包的入口
- 单入口:entry是一个字符串
module.exports = {
entry: './path/entry/file.js'
}
- 多入口: entry是一个对象
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
}
}
Output
Output 用来告诉webpack如何将编译后的文件输出到磁盘
- 单入口
module.exports = {
entry: './path/entry/file.js',
output: {
filename: "bundle.js",
path: path.join(__dirname, 'dist')
}
}
- 多入口
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist')
}
}
loaders
webpack 默认只支持JS和JSON两种文件类型,通过Loaders去支持其它文件类型并且把它们转成有效模块
常见loader:
属性 | 说明 |
---|---|
babel-loader | 转换ES6、ES7等JS新特性语法 |
css-loader | 支持.css文件的加载和解析 |
less-loader | 将less文件转换成css |
ts-loader | 将ts转换成js |
file-loader | 进行图片、字体等的打包 |
raw-loader | 将文件以字符串的形式导入 |
thread-loader | 多进程打包JS和CSS |
用法:
module.exports = {
entry: {
app: './src/app.js',
},
output: {
filename: 'bundle.js',
},
module: {
rules: [
{ test: '\.txt$',use: 'raw-loader' }
]
}
}
plugins
插件用于bundle文件的优化,资源管理和环境变量的注入
常见plugins:
属性 | 说明 |
---|---|
SplitChunksPlugin | 将chunks相同的模块代码提取成公共的js |
CleanWebpackPlugin | 清理构建目录 |
MiniCssExtractPlugin | 将CSS提取到单独的文件中 |
CopyWebpackPlugin | 将文件或文件夹拷贝到构建的输出目录 |
HtmlWebpackPlugin | 创建html文件去承载输出的bundle |
UglifyjsWebpackPlugin | 压缩js |
ZipWebpackPlugin | 将打包出来的资源生成一个zip包 |
用法:
module.exports = {
entry: {
app: './src/app.js',
},
output: {
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
mode
mode用来指定当前构建环境是:production、development和none,默认为production
选项 | 说明 |
---|---|
development | 设置process.env.NODE_ENV的值为development, 开启NamedChunksPlugin和NamedModulesPlugin |
production | 设置设置process.env.NODE_ENV的值为production |
none | 不开启 |
文件监听
发现源码发送变化时,自动构建出新的输出文件
轮询判断文件的最后编译时间是否变化
某个文件发生了变化,并不会立即告诉监听者,而是缓存起来,等aggregateTimeout
module.export = {
//默认false
watch: true,
watchOptions: {
// 默认为空,不监听的文件,支持正则匹配
ignored: /node_modules/,
// 监听到变化后等300ms再去执行,默认300ms
aggregateTimeout: 300,
// 轮询时间1000ms
poll: 1000
}
}
热更新
webpack-dev-server
// package.json
{
"scpirt": {
"dev": "webpack-dev-server --open"
}
}
// webpack.config.js
module.export = {
plugins: [
// hot:true 会自动引入
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot: true,
// hotOnly:true // 热更新失败不自动刷新
}
}
// js代码实现热更新需要添加以下代码
if (module.hot) {
module.hot.accept()
}
webpack-dev-middleware
原理
- Webapck Compile: 将JS编译成Bundle
- HMR Server: 将热更新的文件输出给HMR Runtime。是服务端,用来将变化的 js 模块通过 websocket 的消息通知给浏览器端。
- HMR Runtime: 会被注入到浏览器,更新文件的变化。是浏览器端,用于接受 HMR Server 传递的模块数据,浏览器端可以看到 .hot-update.json 的文件过来。
- Bundle server: 提供文件在浏览器的访问。
- bundle.js: 构建输出的文件
文件指纹
Hash: 和整个项目的构建相关,只要文件修改,整个项目构建的hash值就会修改
Chunkhash: 和webpack打包的chunk有关,不同的entry会生成不通过的chunkhash值
Contenthash: 根据文件内容来定义hash,文件内容不变,则contenthash不变
//通常js使用chunkhash
output: {
path: path.join(__dirname, 'dist'),
filename: '[name]_[contentHash:8].js'
},
//css使用contenthash
new MiniCssExtractPlugin({
filename: '[name]_[contentHash:8].css'
}),
//图片通常使用hash
{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: 'file-loader',
options: {
name: 'img/[name][hash:8].[ext]'
}
}]
},
代码压缩
js压缩
内置了uglifyjs-webpack-plugin
css压缩
optimize-css-assets-webpack-plugin
new OptimizeCssAssetsWebpackPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano')
}),
html压缩
使用html-webapck-plugin,设置压缩参数
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'),
filename: 'index.html',
chunks: '[index]',
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
}),
自动清理目录
使用clean-webpack-plugin,默认会删除output指定的输出目录
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
new CleanWebpackPlugin()
自动补全css3前缀
postcss-loader和autoprefixer
px自动转换成rem
px2rem-loader,可结合lib-flexible自动修改根元素font-size(最大为54px)
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')({
overrideBrowserslist: ['> 0.15% in CN']
})
]
}
},
{
loader: 'px2rem-loader',
options: {
// 1rem = 75px
remUnit: 75,
// 小数点位数
remPrecision: 8
}
},
'less-loader'
]
},
source map
通过source map定位到源代码,开发环境开启,线上环境关闭
关键字
- eval: 使用eval包裹模块代码
- source map: 产生.map文件
- cheap: 不包含列信息
- inline: 将.map作为DataUrl嵌入,不单独生成.map文件
- module: 包含loader的sourcemap
类型
- (none)
- eval
- cheap-eval-source-map
- cheap-module-eval-source-map
- eval-source-map
- cheap-source-map
- cheap-module-source-map
- inline-cheap-source-map
- inline-cheap-module-source-map
- source-map
- inline-source-map
- hidden-source-map
- nosources-source-map
提取页面公共资源
利用webpack4内置的SplitChunksPlugin进行公共脚本分离
chunks参数说明:
- async 异步导入的库进行分离(默认)
- initial 同步导入的库进行分离
- all 所有导入的库进行分离(推荐)
基础库分离
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /(react|react-dom)/,
name: 'vendors',
chunks: 'all'
}
}
}
}
}
分离页面公共文件
module.exports = {
optimization: {
splitChunks: {
minSize: 0,
cacheGroups: {
commons: {
name: 'commons',
chunks: 'all',
minChunks: 2 //最小引用次数
}
}
}
}
}
通过cdn引入
使用html-webpack-externals-plugin
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'react',
entry: 'https://unpkg.com/react@16/umd/react.production.min.js',
global: 'React'
},
{
module: 'react-dom',
entry: 'https://unpkg.com/react-dom@16/umd/react-dom.production.min.js',
global: 'ReactDOM'
}
]
})
tree shaking 摇树
只把用到的方法打入bundle,没用到的方法就会在uglify阶段被擦除掉
注:必须是ES6的语法,CJS的方式不支持
production模式自动开启
Scope Hoisting
将所有模块的代码按照引入顺序放在一个函数作用域里,然后适当重命名一些变量防止变量名冲突
模块的引用次数大于1次是不生效
production模式自动开启ModuleConcatenationPlugin()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。