本文比较基础,我是刚学习的webpack,这是一篇我的学习总结,各位大佬如果发现问题,感谢帮忙指正
练习的代码
https://github.com/jsong93/webpack.git
webpack和gulp的区别
webpack和gulp都可以帮助我们打包,我理解他们之间的区别是
gulp是通过任务的方式,执行各个node任务来打包
webpack可以捆绑,分离代码。优化我们的项目。
开始
- 安装webpack
npm install -D webpack webpack-cli
- 配置
entry:定义入口文件,可以定义多个入口,webpack根据关系自动打包
entry: './src/index.js',
output:打包的输出配置
output: {
// 定义输出的文件名,[name],entry中定义的名字,没有默认为main。
// chunkhash一个hash值,防止浏览器缓存,当定义为热部署的时候不可以用
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
},
devtool:source map 可以映射出源代码,帮我我们查找错误。比如我们打包后生成一个bundle.js,如果程序报错直接定位到bundle.js中我们很难发现问题,source map可以帮我们定位最初打包前的代码。devtool
loader:提供一些转换的工具,比如ts,jsx,es6转换成es5。打包css,scss,less等
style-loader 要写在 css-loader前面
plugins:提供一些额外的插件
- 重要的插件
html-webpack-plugin
可以自动在我们的打包目录中创建一个index.html,也可以选择一个html模板,并引入打包后的文件。
clean-webpack-plugin
可以清空打包目录的文件夹
一个简单的webpack.conf.js
const path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin;
module.exports = {
entry: {
app: './src/index.js'
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
},
devtool: 'inline-source-map',
module: {
rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]
},
plugins: [
new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'index.html') }),
new CleanWebpackPlugin()
]
};
目录结构
提取公共文件
这个配置会将重复的文件提取到一个名为commons.js
{
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'all',
minChunks: 2
}
}
}
}
}
webpack.config.js
const path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin;
module.exports = {
entry: {
app: './src/index.js',
dog: './src/dog.js'
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
},
devtool: 'inline-source-map',
module: {
rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]
},
plugins: [
new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'index.html') }),
new CleanWebpackPlugin()
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'all',
minChunks: 2
}
}
}
}
};
目录结构
不再重复打包资源
通常我们引用的包资源是不回变化的,不需要每次打包的时候都在打包一次
用到的插件
new webpack.HashedModuleIdsPlugin()
webpack.config.js
const path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin,
webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js',
dog: './src/dog.js',
vender: ['lodash']
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
},
devtool: 'inline-source-map',
module: {
rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]
},
plugins: [
new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'index.html') }),
new CleanWebpackPlugin(),
new webpack.HashedModuleIdsPlugin()
],
optimization: {
splitChunks: {
cacheGroups: {
vender: {
name: 'vender',
chunks: 'all',
minChunks: 2
}
// commons: {
// name: 'commons',
// chunks: 'all',
// minChunks: 2
// }
}
}
}
};
懒加载
当只当触发某个事件的时候才加载,节约性能
import(/* webpackChunkName: 'lodash' */ 'lodash').then(_ =>
console.log(_.join(['hello', 'pup']), ' ')
)
index.js
import { Dog } from './dog.js';
// import _ from 'lodash';
import './index.css';
function component() {
const dog = new Dog('erha'),
div = document.createElement('div');
div.innerHTML = dog.bark();
return div;
}
const bt = document.createElement('button');
bt.innerHTML = 'pup';
bt.addEventListener('click', e =>
import(/* webpackChunkName: 'lodash' */ 'lodash').then(_ =>
console.log(_.join(['hello', 'pup']), ' ')
)
);
// console.log(_.join(['hello', 'pup']), ' ');
document.body.appendChild(component());
document.body.appendChild(bt);
提取出css
现在我们的css都是打包在js中的,现在把它提取出来
用到的插件
mini-css-extract-plugin,optimize-css-assets-webpack-plugin
需要的配置
{
module: {
// rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]
rules: [
{
test: /\.css$/,
use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[chunkhash].css'
// chunkFilename: '[id].css'
}),
// 压缩css
new OptimizeCss()
],
}
webpack.config.js
```js
const path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin,
webpack = require('webpack'),
MiniCssExtractPlugin = require('mini-css-extract-plugin'),
OptimizeCss = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
dog: './src/dog.js',
vender: ['lodash']
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
},
devtool: 'inline-source-map',
module: {
// rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]
rules: [
{
test: /\.css$/,
use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'index.html') }),
new CleanWebpackPlugin(),
new webpack.HashedModuleIdsPlugin(),
new MiniCssExtractPlugin({
filename: '[name].[chunkhash].css'
// chunkFilename: '[id].css'
}),
// 压缩css
new OptimizeCss()
],
optimization: {
splitChunks: {
cacheGroups: {
vender: {
name: 'vender',
chunks: 'all',
minChunks: 2
}
// commons: {
// name: 'commons',
// chunks: 'all',
// minChunks: 2
// }
}
}
}
};
项目目录
webpack-merge
我的开发环境和生产环境可能不同,需要创建不同配置文件,但是我们可以把通用的部分提取出来,这就用到了webpack-merge
webpack.common.js
const path = require('path'),
CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin,
HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js'
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({ title: 'production' })
],
// 压缩css用的loader
module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }] },
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
webpack.dev.js
const merge = require('webpack-merge'),
common = require('./webpack.common');
module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist/'
}
});
webpack.prod.js
const merge = require('webpack-merge'),
common = require('./webpack.common'),
UglifyJSPlugin = require('uglifyjs-webpack-plugin'),
webpack = require('webpack');
module.exports = merge(common, {
devtool: 'source-map',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
}
]
},
plugins: [
// 压缩 删除dead code
new UglifyJSPlugin({
sourceMap: false
}),
// 加了一个生产环境的环境变量
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
});