介绍
webpack是一种前端资源构建工具,一个静态模块打包器。
在webpack看来,前端所有的资源文件都会作为模块处理。它会根据模块的依赖关系进行静态分析,打包生成对应的静态资源。
五个核心概念
- Entry :入口文件,以入口为起点开始打包,分析构建内部依赖图。
- Output :出口,打包后的资源输出位置及命名。
- Loader : 使得webpack处理非JS文件
- Plugins: 用于执行更广的任务。
- Mode :development & production
初始化项目
1、全局安装webpack、webpack-cli
npm install webpack webpack-cli -g
2、创建项目文件夹webpack-note。
然后初始化项目,局部安装webpack、webpack-cli
npm init
npm install webpack webpack-cli -D
3、根目录下创建src文件夹下创建js文件夹,创建index.js文件
内容如下:
let add = (a,b)=> {
return a+b;
}
add(3,4)
执行命令:webpack src/js/index.js -o build/js/bundles.js --mode=development
webpack src/js/index.js -o build/js/bundles.js --mode=production
命令打包后会压缩文件。
开发环境基本配置
1、创建配置文件
根目录下新建webpack.config.js文件
内容如下:
const { resolve } = require('path');//node内置模块 用来处理路径问题
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build/js') //输出文件路径
},
mode:'development'//开发环境
}
运行webpack命令。
2、样式文件的打包
安装需要的loader
npm install css-loader style-loader less-loader less -D
新建index.css,随便写的样式。
运行webpack
报错了 !! 这是因为webpack默认不认识css文件的,我们需要使用loader来处理。
修改webpack.config.js文件如下:
const { resolve } = require('path');//node内置模块 用来处理路径问题
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build/js') //输出文件路径
},
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
}
]
},
mode:'development'//开发环境
}
再运行webpack即可。
对于less文件做同样处理。
源码 分支是dev_css
3、HTML资源的打包
下载html-webpack-plugin
npm install html-webpack-plugin -D
新建一个HTML文件 ,内容随意。
修改配置文件
const { resolve } = require('path');//node内置模块 用来处理路径问题
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build/js') //输出文件路径
},
module:{
rules:[
]
},
plugins:[
// html-webpack-plugin 会默认创建一个空的HTML,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/js/index.html'
})
],
mode:'development'//开发环境
}
运行webpack
源码 分支是dev_html
4、打包图片资源
下载loader
npm install html-loader url-loader file-loader -D
配置文件修改如下:
const { resolve } = require('path');//node内置模块 用来处理路径问题
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build/js') //输出文件路径
},
module:{
rules:[
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
// 默认处理不了HTML中img图片
test:/\.(jpg|png|gif)$/,
// 下载url-loader file-loader
loader:'url-loader',
options:{
// 图片小于8KB 会处理为base64
// 优点:减少请求数量
linmit:8*1024,
// url-loader 默认使用es6模块化解析,而html-loader引入图片是commonjs
//解析时会出问题:[Object Module]
// 关闭uri-loader 的es6模块化 使用commonjs解析
esModule:false,
// 给图片进行重命名
// [hash:10]取图片hash的前10位
// [ext] 文件原来的扩展名
name:'[hash:10].[ext]'
}
},{
test:/\.html$/,
loader:'html-loader'
}
]
},
plugins:[
// html-webpack-plugin 会默认创建一个空的HTML,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/js/index.html'
})
],
mode:'development'//开发环境
}
源码 分支是dev_img
5、其他资源的打包 (如字体图标)
配置:
const { resolve } = require('path');//node内置模块 用来处理路径问题
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:'./src/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build') //输出文件路径
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
// 默认处理不了HTML中img图片
test:/\.(jpg|png|gif)$/,
// 下载url-loader file-loader
loader:'url-loader',
options:{
// 图片小于8KB 会处理为base64
// 优点:减少请求数量
linmit:8*1024,
// url-loader 默认使用es6模块化解析,而html-loader引入图片是commonjs
//解析时会出问题:[Object Module]
// 关闭uri-loader 的es6模块化 使用commonjs解析
esModule:false,
// 给图片进行重命名
// [hash:10]取图片hash的前10位
// [ext] 文件原来的扩展名
name:'[hash:10].[ext]'
}
},
{
test:/\.html$/,
loader:'html-loader'
},
{
// 排除css less js html 文件
exclude:/\.(css|js|less|html)$/,
loader:'file-loader',
options:{
name:'[hash:10].[ext]'
}
}
]
},
plugins:[
// html-webpack-plugin 会默认创建一个空的HTML,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/index.html'
})
],
mode:'development'//开发环境
}
源码 分支是dev_other
6、使用webpack-dev-server
安装webpack-dev-server
配置
const { resolve } = require('path');//node内置模块 用来处理路径问题
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:'./src/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build') //输出文件路径
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
// 默认处理不了HTML中img图片
test:/\.(jpg|png|gif)$/,
// 下载url-loader file-loader
loader:'url-loader',
options:{
// 图片小于8KB 会处理为base64
// 优点:减少请求数量
linmit:8*1024,
// url-loader 默认使用es6模块化解析,而html-loader引入图片是commonjs
//解析时会出问题:[Object Module]
// 关闭uri-loader 的es6模块化 使用commonjs解析
esModule:false,
// 给图片进行重命名
// [hash:10]取图片hash的前10位
// [ext] 文件原来的扩展名
name:'[hash:10].[ext]'
}
},
{
test:/\.html$/,
loader:'html-loader'
},
{
// 排除css less js html 文件
exclude:/\.(css|js|less|html)$/,
loader:'file-loader',
options:{
name:'[hash:10].[ext]'
}
}
]
},
plugins:[
// html-webpack-plugin 会默认创建一个空的HTML,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/index.html'
})
],
mode:'development',//开发环境
devServer:{
//项目构建后的路径
contentBase:resolve(__dirname,'build'),
// 启动gzip压缩
compress:true,
port:3000,//端口号
open:true//自动打开浏览器
}
}
npx webpack-dev-server 启动
源码 分支是dev_devserver
生产环境基本配置
1、提取css为单独文件
下载插件
npm install mini-css-extract-plugin -D
配置文件修改
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module:{
rules:[
{
test:/\.css$/,
use:[
// 'style-loader',
//取代 style-loader' 作用是提取JS中的css成单独文件
MiniCssExtractPlugin.loader,
'css-loader'
]
},
]
},
plugins:[
new MiniCssExtractPlugin({
filename:'css/build.css'
})
],
mode:'development',//开发环境
}
运行webpack
2、CSS兼容性处理
下载loader
npm install postcss-loader postcss-preset-env -D
配置文件修改
module.exports = {
entry:'./src/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build') //输出文件路径
},
module:{
rules:[
{
test:/\.css$/,
use:[
// 'style-loader',
//取代 style-loader' 作用是提取JS中的css成单独文件
MiniCssExtractPlugin.loader,
'css-loader',
{
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:()=>{
require('postcss-preset-env')()
}
}
}
]
}
]
},
mode:'development',//开发环境
}
package.json增加
"browserslist":{
"development":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
运行webpack
3、压缩CSS
下载
npm install optimize-css-assets-webpack-plugin -D
配置文件修改
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
plugins:[
//压缩css
new OptimizeCssAssetsWebpackPlugin()
],
mode:'development',//开发环境
devServer:{
}
运行webpack
4、JS语法检查
下载
npm install eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D
配置修改
module.exports = {
module:{
rules:[
{
// eslint eslint-loader
test:/\.js$/,
exclude:/node_modules/,
loader:'eslint-loader',
options:{
// 自动修复eslint的错误
fix:true
}
}
]
},
}
package.json增加如下
"eslintConfig":{
"extends":"airbnb-base",
"env":{
"browser":true
}
}
会自动修复eslint的错误
5、JS兼容性处理
下载
npm install babel-loader @babel/core @babel/preset-env @babel/polyfill core-js -D
配置文件修改
module.exports = {
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns:'usage',
// 指定core-js
corejs:{
version:3
},
// 指定兼容性做到哪个版本浏览器
targets:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10'
}
}
]
]
}
},
]
},
}
6、JS压缩
mode:'production',
改为生产模式 webpack会自动开启JS压缩的功能。
7、HTML压缩
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/index.html',
// 压缩HTML
minify:{
// 移除空格
collapseWhitespace:true,
// 移除注释
removeComments:true
}
}),
8、生产环境配置
const { resolve } = require('path');//node内置模块 用来处理路径问题
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// 定义node环境变量
process.env.NODE_ENV = "production"
// 复用loader
const commonCSSLoader = [
// 'style-loader',
//取代 style-loader' 作用是提取JS中的css成单独文件
MiniCssExtractPlugin.loader,
'css-loader',
{
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:()=>{
require('postcss-preset-env')()
}
}
}
]
module.exports = {
entry:'./src/index.js',
output:{
filename:'./build.js',//输出文件名
path:resolve(__dirname,'build') //输出文件路径
},
module:{
rules:[
{
test:/\.css$/,
use:[...commonCSSLoader]
},
{
test:/\.less$/,
use:[...commonCSSLoader,'less-loader']
},
{
// 默认处理不了HTML中img图片
test:/\.(jpg|png|gif)$/,
// 下载url-loader file-loader
loader:'url-loader',
options:{
// 图片小于8KB 会处理为base64
// 优点:减少请求数量
linmit:8*1024,
// url-loader 默认使用es6模块化解析,而html-loader引入图片是commonjs
//解析时会出问题:[Object Module]
// 关闭uri-loader 的es6模块化 使用commonjs解析
esModule:false,
// 给图片进行重命名
// [hash:10]取图片hash的前10位
// [ext] 文件原来的扩展名
name:'[hash:10].[ext]'
}
},
{
test:/\.html$/,
loader:'html-loader'
},
{
// eslint eslint-loader
test:/\.js$/,
exclude:/node_modules/,
enforce:"pre",//优先执行
loader:'eslint-loader',
options:{
// 自动修复eslint的错误
fix:true
}
},
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns:'usage',
// 指定core-js
corejs:{
version:3
},
// 指定兼容性做到 哪个版本浏览器
targets:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10'
}
}
]
]
}
},
{
// 排除css less js html 文件
exclude:/\.(css|js|less|html)$/,
loader:'file-loader',
options:{
name:'[hash:10].[ext]'
}
}
]
},
plugins:[
// html-webpack-plugin 会默认创建一个空的HTML,自动引入打包输出的所有资源
new HtmlWebpackPlugin({
// 复制./src/js/index.html 文件
template:'./src/index.html',
// 压缩HTML
minify:{
// 移除空格
collapseWhitespace:true,
// 移除注释
removeComments:true
}
}),
new MiniCssExtractPlugin({
filename:'css/build.css'
}),
//压缩css
new OptimizeCssAssetsWebpackPlugin()
],
mode:'development',//开发环境
devServer:{
//项目构建后的路径
contentBase:resolve(__dirname,'build'),
// 启动gzip压缩
compress:true,
port:3000,//端口号
open:true//自动打开浏览器
}
}