webpack4学习笔记
准备工作
安装webpack、webpack-cli、webpack-dev-server,创建package.json,在package.json的scripts中创建build启动方式,由于准备将webpack.config.js放在build文件夹下。
配置如下:
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
},
创建build文件夹,在其中创建webpack配置文件webpack.config.js。
注:webpack.config.js中entry、plugins等可以用到相对路径的地方,相对路径都是相对于根目录。
基础插件与处理
1. html部分
安装html-webpack-plugin,负责打包html文件
注意,在html文件中不需要手动引入打包后的js文件,html-webpack-plugin会自动将打包后的js文件引入html文件中
2. css部分
安装loader,如style-loader/css-loader/less-loader
注意,解析less除了安装less-loader还需安装less,提供运行环境
安装 mini-css-extract-plugin用于抽离css
安装postcss-loader、autoprefixer用于添加样式兼容性前缀
添加兼容性前缀的功能由autoprefixer完成,postcss-loader相当于一个loader的容器,autoprefixer配置在其中,使postcss-loader在加载css文件时能自动添加兼容性前缀
安装optimize-css-assets-webpack-plugin用于抽离css
注:此插件是配置在optimization.minimizer中,webpack4将大部分优化相关内容放在optimization中,又根据优化的具体内容划分为minimizer、splitChunks等模块。
注意,抽离的css无法自动压缩,因此后续需配置压缩抽离的css的插件
安装mini-css-extract-plugin用于压缩抽离后的css
此插件配置在plugins中
3. js部分
安装uglifyjs-webpack-plugin用于压缩js
由于抽离css时optimization.minimizer的配置,导致webpack4压缩的默认js相关配置被覆盖,因此需要手动配置js压缩,此插件也是放在optimization.minimizer中
安装babel-loader、@babel/core、@babel/preset-env
(加载器)、(核心模块,可以调用transform方法转换源代码)、(转化模块,es6->es5)
安装@babel/plugin-proposal-class-properties
@babel模块很大,因此最好按需下载模块,此模块为class的转换工具
安装@babel/plugin-proposal-decorators
class的装饰器
安装@babel/plugin-transform-runtime(dev环境)、@babel/runtime(生产环境)
babel只能转义ES6语法,比如箭头函数,但是遇到ES6新增的api就无能为力了,runtime可处理async、Promise、generater等新增API
安装@babel/polyfill
runtime无法处理实例上的方法,如'aaa'.includes('aa'),因此需使用@babel/polyfill,@babel/polyfill的使用方式较为特殊,并非配置在插件中,可在需要的js文件中引入,或在entry中添加'@babel/polyfill'。
*注:polyfill、runtime作用都是实现ES6相关API,但polyfill是污染全局变量,runtime是使用局部变量,对于实例上的api,必须污染原型链上的全局变量,因此runtime无法处理。由于runtime是使用局部变量实现,假设多个地方使用了Promise,在使用的地方注入局部变量,势必会有大量重复代码,plugin-transform-runtime可通过一些helper函数的注入来减少语法转换函数的开销,如多处使用promise时,实现promise的方法指向同一处。*
4. 图片处理
安装file-loader或url-loader用于解析图片文件
webpack运行于nodejs,无法解析图片;若图片采用的是样式background:url('...'),此种背景图css-loader会进行解析;file-loader、url-loader都可以解析图片文件,file-loader是将图片拷贝至打包后的文件,url-loader与file-loader相比多了可将图片解析为base64放入文件中的功能,因此使用时一般添加limit,小于多少比特的文件采用转换base64(base64同常比原文件大1/3),limit设为0的话,url-loader功能与file-loader没区别了
安装html-withimg-loader,用于解析html中img
若在html中添加img,图片地址为src目录下的draw.svg,直接打包的话打包后的文件中src地址仍指向src目录下的src,因此需要html-withimg-loader将html中的img指向的图片打包至dist;html-withimg-loader并不能直接解析图片文件,遇到html中的img标签时,html-withimg-loader需通过file-loader或url-loader对图片文件进行解析,并修改html中src的指向
5.不同类型文件放入相应文件夹
将不同类型文件放入相应文件夹,通常在打包的最后一步进行,如js文件的output,图片文件的url-loader中,css文件若没有minicss插件,一般默认打包到js文件中,若单独分离,最后一步为mini-css-extract-plugin插件处理,因此在此处设置
6. 代码规范
安装eslint eslint-loader(可在官网上勾选具体规则,下载配置,不配置会报错)
7. 暴露对象
若要将某个对象(如jquery)暴露于全局window下
- 安装并使用expose-loader
若要将对象暴露于每一个模块
- 使用webpack.ProvidePlugin
8.sourceMap
若要在打包后文件的基础上查看原文件,则需要设置devtool,注意,生产环境若没在UglifyJsPlugin中设置sourcemap:true,即使设置了devtool也无法查看原文件(原文件可在F12->Sources->webpack:// 中查看,未设置则无此文件夹),devtool的类型有:
- source-map:大而全,会产生单独的map文件,可查看报错部分在原文件的行和列
- eval-source-map:不会产生单独的文件,但报错能显示行和列
- cheap-module-source-map:报错不会显示多少列,但是一个单独的映射文件
- cheap-module-eval-source-map: 不会产生文件,集成在打包后的文件中,报错不会显示多少列
9.resolve配置
详情见代码注释:
resolve: {
// 解析第三方包只从node_modules查找
// 如代码中import XX from 'xx';'xx'默认只在node_modules查找
// 一般引用模块默认从当前目录的node_modules查找,找不到则沿着
// 上一层目录去查找,此配置缩小查找范围
modules:[path.resolve('node_modules')],
// 一般import XX from 'xx',引入的路径都是在package.json中'main'配置里的路径,
// 此配置可规定引入时先查找package.json下的哪个路径
// mainFields: ['style','main'],
// 设置默认入口文件名字,默认是index,因此若配置main,此项目中依赖了'strip-ansi'包,该包package.json
// 中未配置main,因此默认找index.js,此配置让这种场景默认找main.js,因此require('strip-ansi')报错
// mainFiles: ['main'],
// 引入文件时若未填写后缀,先找同名js,再找css,再json,依次从左到右
// extensions: ['.js','.css','.json'],
alias:{
//别名,代码中'@/'直接指向src目录
'@':path.resolve(__dirname,'../src'),
}
10.常用插件
安装cleanWebpackPlugin(打包前清空dist)
安装copyWebpackPlugin(文件直接复制)
bannerPlugin(版权声明插件,不用安装,webpack内置)
常用功能
1、代理
webpack代理功能可用于解决跨域问题,将浏览器到有跨域问题服务器的请求,转化为浏览器到无跨域问题的代理服务器,代理服务器到有跨域问题服务器的请求,其效果类似于nginx的proxy_pass;同源策略只针对浏览器,服务器到服务器的请求不会有跨域问题。
proxy配置只针对于开发环境,生产环境不会自动搭建服务器。
devServer中配置:
proxy:{
//匹配/api接口,将其代理到http://localhost:8080
// 方法1:
//'/api':'http://localhost:8080'
// 方法2:
'/api':{
target: 'http://localhost:8080',
// 将路径替换,/api/name中的/api替换为空字符串
pathRewrite:{
'/api':''
}
}
},
除此之外,还可以在nodejs搭建的服务器中,利用webpack-dev-middleware启动webpack,此时打包后的服务器与搭建的服务器同源,也不会引起跨域问题。
2、mock数据
利用devServer提供的生命周期钩子,在开发环境dev服务器上新增接口。
devServer中配置:
before(app){
app.get(/^\/api/,(req,res)=>{
res.json({data:'mock-data-before'})
})
}
3.实时打包
build完毕后服务不会立刻结束,修改代码后可实时打包,相当于build版的热更新。
新增如下配置:
watch:true, // 实时打包,相当于build的热更新
watchOptions:{
poll:1000, //每1000毫秒轮询一次
aggregateTimeout:300, //防抖,停止输入300ms后才更新
ignored: /node_modules/, //不监控node_modules
},
(混合开发APP时可将此功能与打包APP的热更新相结合?)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。