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:'/' //给出口文件的路径设添加为/,设置为相对路径
},
系列问题
1.区别webpack的两个工具包:webpack和webpack-cli
=>在webpack 3中,webpack本身和它的CLI以前都是在同一个包中,但在第4版中,他们已经将两者分开来更好地管理它们。cli相对来说是一个命令工具
2.为什么建议不要全局下载webpack工具包?
=>因为webpack不同版本的配置常常是不一样的,为了不同的项目,最好都单独启用一个webpack
3.如何解决webpack命令不能识别的问题?
=>有一些旧版本的webpack安装后还需要配置环境变量才能使用
4.webpack的10大配置选项
5.webpack常用的10个loader
6.webpack中常用的5个plugin
=>见上
7.为什么要使用html-webpack-plugin?
=>自动引入打包好后的bundle.js ,为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
8.为什么要使用clean-webpack-plugin?
=>有时候我们打包生成的文件通常是随即名,而使用clean-webpack-plugin可用来清除旧文件,产生新的文件,避免相同文件不同名的问题
9.区别css-loader和style-loader
=>webpack是用JS写的,运行在node环境,所以默认webpack打包的时候只会处理JS之间的依赖关系
=>如果在JS中导入了css,那么就需要使用 css-loader 来识别这个模块,通过特定的语法规则进行转换内容最后导出
css-loader:会处理 import / require() @import / url 引入的内容.将css文件生成一个js数组数据,包括路径,css字符串
style-loader:这个数据页面并不能直接使用。而是使用通过style-loader再页面中创建一个style标签,将css字符串属性写入到页面当中
10.区别url-loader和file-loader
=>1.文件大小小于limit参数,url-loader将会把文件转为DataURL;2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。。
11.webpack-dev-server用来做什么
=>1.webpack-dev-server是一个小型的Node.js Express服务器
12.说说热模替换(HMR)的理解
=>模块热替换(HMR)的作用是,在应用运行时,无需刷新页面,便能替换、增加、删除必要的模块。
=>具体实现思路可以看官方文档: https://www.webpackjs.com/concepts/hot-module-replacement/
13.说说代理服务器的理解
?
14.说说history路由404问题
?
15.@babel/preset-env能干什么?不能干什么?如何解决?
=>包含了各种可能用到的转译工具。用来降级和转义es语法
=>不能转换浏览器不存在的api
16.直接使用@babel/polyfill有什么问题,如何解决?
=>包过大,最好是按需引入
18.如何对css进行单独打包和压缩
=>普通的打包通过css-loader将css文件转化为js数组数据,然后通过style-css再页面创建style标签,将属性和值插入其中
=>如果要单独打包,就要用到extract-text-webpack-plugin@next,将css从js中抽取出来,将style-css的功能替换为单独创建文件
19.postcss是什么?
=>将css转换成css抽象语法树,可以简单的理解为将css转换成js,调用插件来处理抽象语法树,通过插件实现对css的处理。
20.autoprefixer用来做什么?
=>自动加上一些属性的厂商前缀
21.postcss-px2rem用来做什么的?
=>这些css文件打包前,将文件里面的px计算成rem,然后在进行解析,这样就可以直接在页面中使用px了。