一、推荐一些好的博文
webpack认识:https://www.cnblogs.com/bilibilicai/p/6830154.html
详细的介绍,从安装到常用插件的使用:https://www.cnblogs.com/cangqinglang/p/8964460.html
js打包原理分析:https://blog.csdn.net/baozhiqiangjava/article/details/80603509
webpack安装配置:https://blog.csdn.net/qq_37322278/article/details/80157223
二、webpack初识
基本作用:模块化打包,可以从入口文件单独引用需要的依赖文件
环境搭建
1、初始化
npm init
不在npm中发布项目,配置项全部回车默认
2、安装 webpack
npm install webpack --save-dev(安装到项目目录中)(--save-dev 位置可以在前也可以在后)
全局安装 npm install -g webpack
3、配置好环境,可以开始写项目
主要是自己需要编写的js 和 html
可以选择安装一些常用的加载器
如,npm install --save-dev css-loader html-webpack-plugin文件
后面安装也行
4、打包处理
.\node_modules\.bin\webpack
更简便的方式:在package.json中配置
"scripts": { "start": "webpack --mode development",//--mode定义打包方式一般有两种默认为production,development为开发环境的代码,即不压缩的方式 }
直接使用npm run start运行webpack --mode development或webpack命令
5、看项目
直接打开index.html
6、热加载
热加载有两种方法:
第一种,使用webpack-dev-server
npm install webpack-dev-server -g(先安装全局的)
npm install webpack-dev-server --save-dev
配置文件追加
devServer: {
contentBase: "./dist",//dist为你需要注册静态服务的文件夹
port: "8080",//端口
inline: true, //表示代码修改后页面自动刷新
hot: true//便是模块热替换
}
json中追加
"scripts": {
"start": "webpack --mode development",
"dev": "webpack-dev-server --inline --hot --mode development"
}
启动时可用 npm run dev
优缺点:
(不需要手动更新页面,监听端口可能与后台端口冲突)(不生成文件,文件暂存在内存中)
第二种,使用watch模式
json的 script 中添加 "watch":"webpack --watch --mode development",
webpack.config.js 后添加
watchOptions:{
poll:1000,//监测修改的时间(ms)
aggregateTimeout:500, //防止重复按键,500毫米内算按键一次
ignored:/node_modules/,//不监测
}
三、文件介绍
dist 保存打包后的文件
index.js 编译的出口
index.html 打包后的html
package.json 配置文件(npm init 后自动生成,配置编译的入口,自定义的npm命令)
package-lock.json (安装webpack后生成)(锁定安装时的包的版本号,以便后续重新安装的时候生成相同的依赖,忽略项目开发过程中有些依赖已经发生的更新)
node_modules 存放依赖项的文件夹(安装webpack后生成)
webpack.config.js webpack 工程的配置文件,定义入口js文件,出口js文件,加载器,插件等
src 存放自己的文件
main.js 编译的入口(不在配置文件中设置时,默认是src下的index.js)(需要在js文件中importcss)
main.css 自己的css文件,需要使用加载器来转换(es6转换为es5是通过插件转换)
(写得博文不多,穿不上来图片)
目录结构可以是dist src node_modules同级,还可以创建一个config 专门存放配置文件
修改配置文件路径
将webpack.config.js 放入文件夹中,需要修改 json 中启动命令 和 上下文的路径
加入--config config/webpack.config.js
webpack.config.js设置上下文根目录为config的上一级,及父目录:context:path.resolve(__dirname, "..")
(__dirname 指当前路径,由于是写在webpack.config.js 中,所以指的就是./config 这个路径)
五、loader(预处理文件,打包除了js之外的任何静态资源,为这些资源配置打包规则)
1、加载css
下载依赖:npm install style-loader css-loader --save-dev
入口js文件 import (路径是原来的css文件相对于入口文件的路径,先import再打包)
加载图片:下载依赖:npm install --save-dev file-loader url-loader
webpack.config.js 配置规则
module:{
rules:[
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader'
},
// css-loader会遍历css文件,找到所有的url(...)并且处理。style-loader会把所有的样式插入到你页面的一个style
{
test:/\.css$/,
// use:['style-loader','css-loader']
use: [
{
loader: MiniCssExtractPlugin.loader,
// options: {
// publicPath: '../'
// }
},
"css-loader"
]
},
// 加载图片
{
test:/\.(png|jpg|gif|jpeg)/,
loader: 'url-loader?limit=8192&name=img/[hash:8].[name].[ext]'
}
]
},
2、
es6 es5转换
https://blog.csdn.net/lin5165352/article/details/82289562
https://www.webpackjs.com/loaders/babel-loader/
安装
webpack 4.x | babel-loader 8.x | babel 7.x
npm install babel-loader @babel/core @babel/preset-env webpack
webpack 4.x | babel-loader 7.x | babel 6.x (现在 babel 最新版本是6,所以用第二个命令安装)
npm install babel-loader@7 babel-core babel-preset-env --save-dev
引用
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader' }
] }
六、插件(webpack就是用插件系统构建的,插件用来适当的时机执行特定的任务,处理loaders做不了的事情)
https://www.jianshu.com/p/3066d96aec8b
通过 new webpack.ProvidePlugin() 引入的是 webpack的内置模块,不需要install
通过 const CleanWebpackPlugin = require('clean-webpack-plugin'); new CleanWebpackPlugin(['dist'])引入的需要安装
1、打包html(自动将引用的js整合到html中)
安装插件:npm install --save-dev html-webpack-plugin
plugins配置插件
new HtmlWebpackPlugin({
filename:'page.html',
template:'./src/page/page.html',
chunks:['page'],
// minify:{ //压缩HTML文件
// removeComments:true, //移除HTML中的注释
// collapseWhitespace:true //删除空白符与换行符
// }
}),
2、加载第三方框架(jquery或者echarts)
https://blog.csdn.net/u012881904/article/details/59109526
安装依赖项
npm install --save jquery
npm install --save echarts
入口js文件中引用即可使用
或者在入口文件中设置全局引用(内置插件)
new webpack.ProvidePlugin({
echarts:"echarts",
$: "jquery",
jQuery: "jquery",
"windows.jQuery": "jquery"
}),
3、css分离(css单独打包)
不分离的情况,css通过js入口文件内嵌到html页面中,样式多的情况还是需要用link,此时需要把css分离成单独的文件,打包的html能自动引用这些文件,图片路径沿用原来的css中路径不会出错(保证图片保存在相应路径下)
https://www.npmjs.com/package/mini-css-extract-plugin#minimal-example
npm install --save-dev mini-css-extract-plugin
var MiniCssExtractPlugin = require("mini-css-extract-plugin");
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
4、提取公共代码(内置插件)(把相同的代码提取出来,需要提前在入口chunk加载)
(有一种类似 css 中雪碧图的思想,minSize设为1的时候,相当于把所有用到的js文件都打包到一个utils.js中(css也会打包,也要单独引用),所有文件都引用这个js,js的请求将为1次)
// 提取公共代码
optimization: {(optimization与plugin之类的同级)
splitChunks: {
cacheGroups: {
// 注意: priority属性
// 其次: 打包业务中公共代码
utils: {
name: "utils",
chunks: "all",
minSize: 1,
priority: 0
},
// 首先: 打包node_modules中的文件
// vendor: {
// name: "vendor",
// test: /[\\/]node_modules[\\/]/,
// chunks: "all",
// priority: 10
// }
}
}
},
5、压缩
压缩
压缩js
install uglifyjs-webpack-plugin --save-dev
webpack运行用production模式
压缩html
new HtmlWebpackPlugin({
filename:'page.html',
template:'./src/page/page.html',
chunks:['page'],
// minify:{ //压缩HTML文件
// removeComments:true, //移除HTML中的注释
// collapseWhitespace:true //删除空白符与换行符
// }
}),
压缩css
https://blog.csdn.net/weixin_36185028/article/details/82182352
npm install optimize-css-assets-webpack-plugin --save-dev
普通压缩
const optimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [
new optimizeCss()
]
压缩图片
install imagemin-webpack-plugin --save-dev
var ImageminPlugin = require('imagemin-webpack-plugin').default
new ImageminPlugin({
disable: process.env.NODE_ENV !== 'production',
pngquant: {
quality: '95-100'
}
}),
6、其他
如何用 es6 编写 webpack.config.js 文件
https://cnodejs.org/topic/56346ee43ef9ce60493b0c96
七、一些问题和解决的思路(不对的请大神指点)
图片问题
未分离css时,引用的图片打包之后的路径问题
https://blog.csdn.net/puyahua/article/details/80076033
原理:
先通过原来的css查找图片,查找到图片后,将图片打包到dist文件夹(没有定位path的话),此时css引用的图片路径是dist目录下,若html也打包到了dist目录下,假设为 html2,从html2访问同目录下的图片没问题(不需要修改任何路径,因为css此时内嵌到了html2中,图片和html2是同级的),若html2被定位到了其他目录,或者从原来的html1中访问打包后的图片,需要用publicPath 增加一个虚拟路径,此时访问的图片路径为虚拟路径+图片,虚拟路径的计算需要从html开始定位到dist目录(因为css是内嵌到html中的)
概念:pablicPath,只会创建虚拟路径,不会真正的创建文件夹
分离css之后,打包的图片保存在原来图片与原来css对应的路径下,不需要改变,引用也不会出错
如,原来css在 static/css/ 文件夹下,图片在 static/img/ 文件夹下,打包之后,css也需要在 dist/css/ 文件夹下,图片在 dist/img/ 文件夹下
js问题
在入口 js 中 import 或者 require 其他js,然后只打包入口js,会将其他js打包到这个js,只生成一份出口 js
有公共代码此时可通过提取公共代码,将公共代码提取成一份 js 文件,让不同的html引用
打包多个入口 js,每个 js 生成一份文件,不同的 html 要引用不同的 js 可以过 html 插件中的 chunks 引用打包后 js 文件,
八、遗留问题
假设有a.html b.html c.html d.js e.js f.js,
a 引用 d e
b 引用 d f
c 引用 e f
如果通过require,a b c生成的出口 js 文件,会包含很多不同的公共代码,此时公共代码提取minSize设为2时,所有文件的请求会将为1么?
这种情况若是将 d e f 都打包成出口js文件,a b c通过html 插件中的 chunks 引用打包后 js 文件,js请求还是为3??webpack能做的只是将js压缩??
九、demo
https://github.com/candisecandise/gitpractice/tree/master/webpackDemo