一、介绍
工程化工具: grunt->gulp->browserify->webpack->vite
webpack 概念:
webpack是个工具,协助开发者做项目管理、打包、模块管理、加载资源,并转换到对应环境,webpack是一种静态编译工具(预编译),它能把各种资源,例如JS(含JSX)、样式(含less/sass)、图片等都作为模块来使用和处理 官网,中文国内
历史
-
webpack1 支持CMD和AMD(第三方的模块化),同时拥有丰富的plugin和loader,webpack逐渐得到广泛应用。
-
webpack2 支持ES6 Module,分析ESModule之间的依赖关系,webpack1必须将ES,Module转换成CommonJS模块,支持tree sharking
tree sharking: 优化功能,顾名思义,就是将多余的代码给 “摇晃” 掉,在开发中我们经常使用一些第三方库,而这些第三方库只使用了这个库的一部门功能或代码,未使用的代码也要被打包进来,这样出口文件会非常大,tree-sharking 帮我们解决了这个问题,它可以将各个模块中没有使用的方法过滤掉,只对有效代码进行打包
-
webpack3 新的特性大都围绕ES Module提出,如Scope Hoisting和Magic Comment
Scope Hoisting: 可以让 Webpack 打包出来的代码文件更小、运行的更快,它又译作 "作用域提升",是在 Webpack3 中新推出的功能
Magic Comment: 魔法注释(magic comment)修改打包动态组件名称
webpack4
webpack5
作用和优势:
-
webpack 是以 commonJS的形式来书写脚本,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
-
能被模块化的不仅仅是 JS 了。
-
开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
-
扩展性强,插件机制完善,
-
Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。
二、目标
模块化,工程化(环境分离),自动化我们的开发环境,涉及到的知识点有入口、出口、转换器、插件
development:
1. 浏览器调试工具
2. 注释、开发阶段的详细错误日志和提示
3. 快速和优化的增量构建机制
production:
1. 开启所有的优化代码
2. 更小的main大小
3. 去除掉只在开发阶段运行的代码
4. Scope hoisting(作用域提升)和Tree-shaking(打包的结构只包含实际用到的 exports)
三、环境要求
webpack5 :Node12+、npm5+
四、项目中使用
1、安装
和谐版本号:
"devDependencies": {
"webpack": "^5.64.4",
"webpack-cli": "^5.0.0",
//ES6+ 转成ES5
"@babel/core": "^7.13.10",
"@babel/preset-env": "^7.13.10",
"babel-loader": "^8.2.2",
//处理的css文件的模块化
"css-loader": "^5.1.3",
//把引入的样式插入到页面中style标签里
"style-loader": "^2.0.0",
//处理的scss文件的模块化
"sass-loader": "^12.3.0",
//scss语法的处理(scss编译成css)
"node-sass": "6.0.1",
//处理文件(如:图片文件,字体文件)的模块化和打包
"file-loader": "^6.2.0",
"url-loader": "^4.1.1",
//处理html文件的
"html-webpack-plugin": "^4.5.0"
//搭建开发服务器的。
"webpack-dev-server": "^3.11.0"
}
和谐版本号二:
"@babel/core": "^7.13.10",
"@babel/preset-env": "^7.13.10",
"babel-loader": "^8.2.2",
"html-webpack-plugin": "^4.5.0",
"node-sass": "^6.0.1",
"sass-loader": "^12.3.0",
"css-loader": "^5.1.3",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"file-loader": "^6.2.0",
"webpack": "^5.64.4",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.11.1"
全局环境
npm i webpack webpack-cli -g
项目环境
npm i webpack webpack-cli --save-dev
2、打包
执行: webpack
//默认 会自动找src/index.js 到 dist/main.js
//要求设置开发模式|生产模式
执行: webpack --mode development | production
//指定出入口
webpack 入口文件路径 --mode development 出口文件路径
入口文件路径:就是要打包那个文件
出口文件路径:把打包结果放在何处,文件名是
在打包时,我们 一般会把配置写在一个单独的文件里。每个项目根目录下都必须配置有一个 webpack.config.js ,告诉 webpack 它需要做什么。配置文件是一个nodejs文件
webpack.config.js文件示例
var webpack = require('webpack');
module.exports = {
mode: 'development', //production 区别环境
entry: {
}, //页面入口文件配置
output: { }, //文件输出配置
module: { //模块加载器配置
rules: [
]
},
resolve: { } //其它解决方案配置
plugins: { } // 插件
}
webpack.config.js配置的详细解释:
mode:
mode: 'production', //development 区别环境
entry:
是页面入口文件配置。可以是字符串,也可以是对象
//1、字符串:
entry: "./src/index.js", //入口文件,需要打包的入口文件
//2、对象
// 会创建多个入口包。key就是 块(chunk)名字。value就是一个字符串或者一个数组
entry: {
page1: "./page1.js",//入口文件
page2: "./page2.js"//入口文件
}
output:
是对应输出项配置,表示入口文件最终要生成什么名字的文件、存放到哪里,其语法为:
entry: {
page1: "./page1.js",//入口文件
page2: "./page2.js"//入口文件
},
//output必须是个对象
output: {
path: __dirname+"/dist/",
filename: "js/[name].bundle.js"
}
该段代码最终会生成一个 page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/下
module.rules:
可以配置loader,loader类似一种转化器, 它可以把一个东西,转成另一个。webpack本身只支持javascript文件模块化,其他文件如需模块化,需要转换器(loader,加载器),loader都需要安装
即:告知 webpack 每一种类型的文件都需要使用什么模块加载器来处理:
style-loader
编译好的css文件插到页面, 遍历 CSS 文件,然后找到 url() 表达式然后处理,即负责解读,处理css中路径引用等问题,加载css文件
npm install style-loader -D
css-loader
读取css文件,模块化, 把 CSS 代码插入页面中的一个 style 标签中 。
npm install css-loader -D
url-loader
把模块化引入的文件,转换base64。对未设置或者小于limit设置的图片进行转换,以base64的格式,被img标签的src所使用
npm install url-loader -D
file-loader
模块化引入文件,大于limit byte的图片用进行解析。url-loader是对file-loader的上层封装
npm install file-loader -D
babel-loader
优雅降级, es6+ 转换 es5,与他同款还有tracuer
npm install babel-loader @babel/core @babel/preset-env -D
@babel/core 核心
@babel/preset-env 解析目标 es6+ 包
配置:
rules: [ //加载器配置
{ //.css 文件使用 style-loader 和 css-loader 来处理
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader'
}
]
},
{
test: /\.scss$/,
use: [
// 将 JS 字符串生成为 style 节点
'style-loader',
// 将 CSS 转化成 CommonJS 模块
'css-loader',
// 将 Sass 编译成 CSS
'sass-loader',
],
},
{ //图片文件使用 url-loader 来处理,小于8kb的直接转为base64
test: /\.(png|jpg)$/,
use:[
{
loader: 'url-loader',
options: {
limit: 8192,//当图片的大小小于8KB,那就把图片转成base64,否则,输出成文件
// outputPath:'images/',//输出的文件路径
name:'images/[name]-[hash:8].[ext]'
}
}
]
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/, //排除掉js文件
options:{ //相关配置 可以配置在webpack.config 亦可以配置在.bablerc
presets: ['@babel/preset-env']
}
}
]
.babelrc
babel-loader的options选项也可以在项目根目录下创建文件.babelrc
,写上如下代码
resolve:
Resolve 定义文件名后缀,省略引入时输入后缀。定义别名
resolve: {
extensions: ['', '.js', '.json', '.scss'],//可以省略的后缀名
alias: { //模块别名定义,方便后续直接引用别名,
'@': path.resolve(__dirname,'src'),
'~': path.resolve(__dirname,'public'),
'components': path.resolve(__dirname,'src/components')
}
}
插件(plugins)
所有的插件,都需要安装、引入,在plugins选项里面实例化插件
html-webpack-plugin
产出html,动态给单页html做拷贝,及注入的工作
安装
npm i html-webpack-plugin -D
引入
//webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');//插件==类
配置plugins
module.exports = {
plugins:[
new HtmlWebpackPlugin({
// title:'HTML标题',//html 浏览器的标题
filename:'index.html',//输出到dist的文件名
template:'./public/index.html',//要参考的html模板
hash:true, //防止缓存,会给文件后面加入hash
minify:{
//是否去除空格,默认false
collapseWhitespace: true,
//是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
minifyCSS: true,
//是否压缩html里的js(使用uglify-js进行的压缩)
minifyJS: true,
//是否移除注释 默认false
removeComments: true,
},
favicon:'./public/favicon.ico',//配置网址图标
})
]
}
webpack-dev-server
搭建前端开发环境服务器,可以在开发环境下,浏览器热刷新,模块热重载(增量构建机制),默认自动打包(放到内存),创建前端开发型服务器(默认找webpack.config所在的位置,找index.html)
配置
//scripts 命令行
"scripts": {
"start": "webpack-dev-server --port 8080 --open --mode development"
},
//webpack.config.js配置文件
devServer:{
port: 8088,//端口
open: true, //开浏览器
static: {
directory: path.join(__dirname, 'public'),//静态资源|html 托管位置
},
// inline:true, //浏览器热刷新
host:'127.0.0.1', //主机地址
// https: false , //开启https服务器,需要提供签名文件
client: {
progress: true,
},
hot: false,
liveReload:false
// watchContentBase: true, //监听public下的文件变动
proxy:{
'/api':{
target:'http://localhost:9001',
pathRewrite:{
'^/api': ''
}
},
'/douban':{
target:'https://douban.uieee.com',
pathRewrite:{
'^/douban':''
},
secure: false //接受https的代理
}
},
}
devtool
使用webpack打包后,代码的错误是按照打包后的文件的行号进行报错的。如果想按照源代码的行号,使用devtool,把代码错误指定到src源代码中
vue-cli2.X
module.exports={
devtool:'inline-source-map'
}
vue-cli3+
module.exports={
configureWebpack: {
// devtool
devtool: 'cheap-module-eval-source-map'
}
}