这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
1.webpack入门概念
webpack是一个静态模块打包工具
不是运行的时候打包,是代码打包好后在‘浏览器’运行,在代码运行前就进行一步处理,这中间的一步,也引出了webpack工程化的强大能力。 区别webpack和webpack-cli
在webpack4之前,这两个东西是合二为一的,4开始,webpack相当于干活的,而cli相当于发命令的
webpack不用全局下载,只需要局部下载即可
webpack正处于一个发展期,有很多不同的版本,如果都用一个版本,可能不能处理多个新旧不同的项目
npx webpack 使用局部webpack进行打包(手动敲命令,使用布局) , 也可以使用npm scripts运行的webpack命令默认先找局部的webpack(使用配置,默认使用局部)
webpack本身就能解析打包各种模块规范的js代码
包括es6 , CommonJs , AMD/requirejs , CMD/seajs
核心基本概念
**
1.模式mode development/production(默认)
2.入口entry
3.输出output
4.加载器loader
5.插件plugin
10个常用配置
1.mode 2.entry 3.output 4.module 5.plugins 6.devtools 7.devSever 8.reslove 9.optimization 10.externals
相关依赖包
webpack webpack-cli webpack-dev-server webpack-merge cross-env css-loader style-loader postcss-loader less-loader stylus-loader sass-loader file-loader url-loader image-webpack-loader babel-loader vue-loader eslint-loader MiniCssExtractPlugin.loader thread-loader html-webpack-plugin clean-webpack-plugin@1.0.1 mini-css-extract-plugin optimize-css-assets-webpack-plugin copy-webpack-plugin terser-webpack-plugin add-asset-html-webpack-plugin webpack-bundle-analyzer webpack.ProgressPlugin webpack.HotModuleReplacementPlugin webpack.HashedModuleldsPlugin webpack.DllPlugin webpack.DllReferencePlugin new webpack.ProvidePlugin\
基本使用
热更行,打包指令,自动将打包文件插入到页面当中 webpack.config.js配置:
const path = require('path')
const HtmlWebpckPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
// 输入目录,输出绝对路径
function resolve(dir) {
return path.resolve(__dirname,dir)
}
module.exports = {
//模式
mode:'production',
//入口
entry:resolve('src/index.js'),
//出口
output:{
path:resolve('dist'),
filename:'bundle.js'
},
//模块加载器
module:{
rules:[
]
},
//插件
plugins:[
//向页面中插入引入打包的js/css的代码
new HtmlWebpckPlugin({
template:'public/index.html'
}),
//清楚打包文件夹 (dist)
new CleanWebpackPlugin(['dist'])
],
//开发服务器
devServer:{
open:true,//自动打开浏览器访问
}
}
package.json口令配置:
"scripts": {
"build": "webpack --mode production", // yarn build / npm run build
"dev":"webpack-dev-server --mode development" //yarn dev / npm run dev
},
js打包
主要使用babel进行对js的打包
webpack文档 => loader => babel
**
//1.对babel的理解
webpack本身有用处理各种模块化规范的能力,但是,并不具备处理es6语法的能力,
真正处理es6的是:babel
但是babel本身在某种意义上也不具备编译es6的能力,babel相当于提供了一个平台,babel依赖的非常多单独针对某个语法编译的插件,比如async就有一个babel的编译插件,const也有一个,箭头函数又有一个,而babel把他们汇集在一起。
意义何在?:
如此众多的插件,不可能每个都去配置,所以用以一个大包来汇总和众多小的插件
查看@babel/preset-env 下package.json 就可以查看到babel的众多依赖
//2.babel的解析
1.babel只转换不兼容的“新语法”(可以理解为语法糖,本质上还是底层的一些语法实现的)
=>const/let/箭头函数/解构赋值/class语法....
2.babel不转换新的api (理解为新的方法,浏览器本身就不存在,所以无法编译)
=>Promise/Map/Set/Object.assign()/Generator/Proxy ....
//3.引出@babel/polyfill : 可以理解为一个补丁包
既然babel不能编译新的api,那么就需要一个包将这些方法都实现,然后打入项目之中,供人使用
=>而@babel/polyfill主要依赖两个包
1.core-js:一个俄罗斯的小哥所写,主要重写了很多es6,es7..的语法
2.regenerator-runtime: 弥补core-js没有实现的async await的缺陷
更进一步的处理:
**
1.我们使用基础配置的babel进行es6语法的编译
2.使用 @babel/polyfill 进行es6新api进行编译
=》低版本浏览器语法,打包支持es6语法,通常是polyfill通过类似打补丁的方式将包引入到项目当中
=》既然有包打入项目,就可以进行优化
1.使用配置的方式,实现按需引入,用了什么语法就打入什么补丁
2.当使用有很多模块使用了类语法的时候,每个模块都会独立产生一个辅助函数=>_classCallCheck
可以提取出来生成一次即可,就需要使用plugins:[@babel/plugin-transform-runtime]
打包图片
主要用到的loader有:
- file-loader
- url-loader( 依赖于file-loader,针对小图片可以进行base64处理,减少请求)
有时候会出现url-loader的包依赖于file-loader但是却没有下载的情况,需要自行下载
**
webpack.config.js下module属性配置:
//模块加载器
module:{
rules:[
//处理图片
{
test:/.(png|jpg|gif|svg)$/,
use:{
loader:'url-loader',
options:{
limit:1024*10, //把小于 5kb的文件转成Base64的格式
name:'img/[name].[ext]',
}
}
}
]
}
还有图片压缩,自行搜索使用
出了图片,还有字体,音频同样使用的都是url-loader
**
使用方法和图片一样,直接添加一个对象配置即可,修改test属性和use的options属性
css处理
对于处理不同的css文件,需要不同的loader:
css: 1.css-loader 2.style-loader
less: 1.less 2.less-loader
stylus: 1.stylus 2.stylus-loader
sass: 1.node-sass 2.sass-loader //注意:node-sass下载可能失败,yarn < npm < cnpm
使用配置:
css全部被打包进bundle.js当中,css的样式都是通过js来写入的
**
webpack.config.js下module属性配置:
//模块加载器
module:{
rules:[
//处理css
{
test: /.css$/,
use: ['style-loader', 'css-loader'] //从下往上,从右往左
},
//处理less
{
test: /.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
//处理stylus
{
test: /.(styl|stylus)$/,
use: ['style-loader', 'css-loader', 'stylus-loader']
}
]
}
PostCss
利用PostCss可以:1.自动添加代码的厂商前缀 2.准换现代的css代码
主要包:autoprefixer postcss-loader
配置:
webpack.config.js下module属性配置:
//模块加载器
module:{
rules:[
//处理css
{
test: /.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader'] //从下往上,从右往左
},
//处理less
{
test: /.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
},
//处理stylus
{
test: /.(styl|stylus)$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader']
}
]
}
再创建postcss.config.js:
module.exports = {
plugins:[
require('autoprefiexer')(),
require('postcss-px2rem')({
unitRem:37.5
})
]
}
单独打包css
要用上mini-css-extract-plugin MiniCssExtractPlugin.loader
webpack.congfig.js:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module:{
rules:[
//处理css
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader, //代替style-css
'css-loader',
'postcss-loader'] //从下往上,从右往左
},
//处理less
{
test: /.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
},
//处理stylus
{
test: /.(styl|stylus)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'stylus-loader']
}
]
},
plugins:[
//从js中抽取css单独打包
new MiniCssExtractPlugin({
filename:'css/[name].css'
})
]
注意:抽取文件单独打包的时候需要主要一些路径问题,此处会出现一个绝对路径的问题
解决:
**
output:{
path:resolve('dist'),
filename:'bundle.js'
publicPath:'/' //给出口文件的路径设添加为/,设置为相对路径
},