webpack一个静态模块打包器
把html不能识别的静态文件编译成可识别的。
预编译处理器less / ES6语法等等
https://blog.youkuaiyun.com/weixin_33795806/article/details/91379506
https://www.bilibili.com/video/BV1e7411j7T5
写了一个html页面如下,html无法识别less,并且js中使用es6语法引入了jquery,这里不能识别,页面报错
响应404
如何构建:
1、从Index.js入口搜索Import中需要编译文件,形成一个依赖关系图
2、(打包)将代码引进来形成一个chunk(块),一个个按不同资源类型编译成该类型可执行文件
3、打包完输出成bundle(静态资源)
-----------------------------------------------
webpack五大概念:
Entry
入口文件,指示webpack该从哪个文件为入口起点打包
Output
输出指示打包好后的bundle该输出到哪个文件,怎么命名
Loader
(翻译)Loader让webpack可以处理非js资源,(如将less编译成webpack可处理资源),webpack自身只理解js文件
Plugins
(执行)插件(Plugins)可以用于执行范围更广的任务。插件的范围包括:从打包优化和压缩,一直到重新定义环境中的变量等。(压缩、优化等等)
Mode
-----------------------------------------------
如何使用
1、npm i webpack webpack-cli -g
2、npm i webpack webpack-cli -D 开发依赖,不属于生产依赖
3、创建src和build目录(src是源代码存放,build是打包处理后的输出文件目录)
4、src下创建一个index.js入口文件进行第一次实验
webpack ./src/index.js -o ./build/built.js --mode=development
开发环境
hash值作为该打包后文件的唯一id
生产环境
(会压缩代码,看大小小很多)
5、写了一个json格式文件用ES6语法引入,看有没运行成功
在Build建一个html,引入built.js看
输出了引入的json文件
尝试打包less文件报错:
webpack能处理js/json资源,不能处理css/img等其他资源
那要怎么做才能让它去处理到其他资源呢?
首先创建一个webpack.config.js文件,与src同级
插一句:模块化分成好几种标准,在src里采用的是es6标准,因此使用Import,但是需要被编译,而在项目中使用的是common.js标准,导入使用module.exports暴露配置
webpack.config.js
// 使用resolve来拼接绝对路径的方法
const {resolve} = require('path')
module.exports = {
//入口起点
entry:'./src/webpack/index.js',
// 输出
output:{
//输出文件名
filename:"built.js",
//输出路径,__dirname是nodejs的一个变量,代表当前文件目录的绝对路径
path:resolve(__dirname,'build')
},
module:{
rules:[
// 详细的loader配置
{
//匹配哪些文件,使用正则
test:/\.css$/,
// 匹配到了使用哪些loader处理
use:[
// loader中执行顺序从右到左,从下到上
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 将css文件变成commonjs模块加载js中,里面内容是样式字符串
'css-loader'
]
}
]
},
plugins:[
],
mode:'development'
// mode:'production'
}
npm i style-loader css-loader
这一次不用再指定什么入口出口了,直接webpack回车就可以,因为那些都在config定义好了。
css文件打包成功
生效了
less:
npm i less less-loader
打包html资源(使用plugin
1、使用插件html -webpack-plugin(npm i )
会自动引入打包好的built.js到html里
loader: 1.下载 2.使用( 配置loader)
plugins: 1.下载 2.引入 3.使用
build下的html文件,你会发现原本没引入,webpack后自动帮你引入了。
打包静态资源,处理图片
npm i url-loader file-loader
{
//处理图片资源
test: /\.(jpg|png|gif)$/,
//下载url-loader file-loader
loader: 'url-loader',
options: {
//图片大小小于8kb,就会被base64处理,直接放进src里,否则就会编译到built当中作xxx.jpg,这样就需要请求才能得到图片
//优点:减少请求数量(减轻服务器压力) 缺点:图片体积会更大(文件请求速度更慢) .
limit: 8 * 1024
}
},
遇到问题1:
能解析作为图片背景Url引入的图片,无法解析作为img src引入的图片
{
//处理图片资源增补,处理html中的img src资源,此loader引入img,然后被上面的url-loader解析
test:/\.html$/,
loader:'html-loader',
}
2、(我这没遇到这问题)如果有可以参考解决
引入html-loader解析后,img src变成这样
原因:html-loader将img解析成common.js的标准引入,但是url-loader默认解析es6标准,因此无法解析
一个有意思的option,可以减少命名长度
打包其他资源,例如字体资源
file-loader
自动编译
dev-server
在webpack.config.js中配置
//开发服务器devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特点:只会在内存中编译打包,不会有任何输出
//启动devServer指令为: npx webpack-dev-server
devServer:{
// 项目构建后路径
contentBase: resolve(_ dirname, ' build'),
//启动gzip压缩
compress: true,
//端口号
port: 3000,
//自动打开浏览器
open: true
]
编译运行
1、设置每个编译类型的输出目录,而css/less经过loader处理会形成js和总js一起输出。
总的js目录输出:
若想提取单独的css文件,不要和js放一块
使用这个插件
css兼容性问题解决
1、
2、
development:兼容到浏览器上一版本
production:兼容到>0.2%,并且不要没啥用(dead)的浏览器
3、在pakage.json中有两种环境变量,怎么知道要兼容哪种需求,就要在config里规定当前Node的环境
压缩css
插件:optimize-css-assets-webpack-plugin
引入:const OptimizeCssAssetsWebpackPlugin = require(‘optimize-css-assets-webpack-plugin’ )
使用:
js语法检查
语法检查: eslint-loader eslint
注:
1、只检查自己写的源代码,第三方的库是不用检查的
2、需要设置检查规则:
package.json中eslintConfig中设置
airbnb ==> eslint-config-airbnb eslint-plugin-import
(airbin是一个js语法规则)
// pakage.json:
eslintConfig": {
"extends": "airbnb-base"
}
// config文件
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options:{
//自动修复eslint的错误
fix: true
}
}
eslint对console.log会警告,如果不想它警报
js兼容性处理(兼容ES6等等)
有些chrome可以,但是ie不认
js主要是把es6转普通js,不像css有那么多浏览器版本问题,所以不需要在pakage.json里指定env等等,直接使用preset-env预设作为兼容性要求。
如何使用babel
npm i babel-loader @babel/core @babel/preset-env
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
}
]
但是关于promise等更难的语法简单预设就无法转换了
全部js兼容性处理–> @babel/polyfill
不是插件,只需要引入即可
但是polyfill直接引入体积太大了,我们只想按需加载使用怎么办?
下载 npm i core-js
兼容性处理使用 preset-env+core-js 的第三种办法。按需加载。
js和html压缩
1、
// 生产环境下会自动压缩js代码
mode :‘production’
2、html文件压缩
webpack优化配置
webpack默认更新一个页面将重新打包,但是,如果一个项目有上千个页面,我只修改其中一个页面,要重新编译不是无敌麻烦吗?
所以需要只更新那个模块,这就需要HMR: hot module replacement 热模块替换/模块热替换
hmr基于dev-server,设置属性hot:true即可。
source-map
生成.map文件
source -map:可以提供源代码到构建后代码映射技术( 如果构建后代码出错了,通过映射可以追踪源代码错误的地方)
OneOf
提升优化生产环境的构建速度:避免同一个文件被反复处理,把重复类型的提取出来,放到oneof外面
优化(一)缓存
1、针对js,babel缓存,babel有类似于模块热更新的功能,100个已编译文件里,只改某一个就只更新某一个。
2、静态资源的缓存有个问题,在这边修改,可是被强缓存就会直接读取缓存中的文件,修改不及时,为此需要把缓存文件加一个版本hash值,比较hash值一不一样。
但是修改js,css文件也会改,因为css是编译后插到js里面的,所以同步更新。
(有点看不懂得地方)
注:同一个入口文件进来就会形成一个chunk
所以不要用hash了,用contenthash
优化(二)tree shaking
https://www.bilibili.com/video/BV1e7411j7T5?p=24
去除应用程序中没有使用得代码
优化(三)code-split
代码分割,可以实现按需,分割并行加载减少时间等等
1、通过单入口、多入口来拆分js文件,
但是单入口就是单页面,而多入口会生成多页面
2、
optimization:{
splitChunks:{
chunks:'all',
}
},
懒加载
点击了才会Import加载,用一个.then语法异步等待。
前提是必须按需加载才行,不然都在built.js里就不行
PWA(渐进式网络开发应用程序) 离线可访问
通过serviceWorker