webpack是一个模块打包工具,他将各种不同类型的文件最终都打包成.js、.css、.png、.jpg4个类型的静态资源。
- 模块化开发
用webpack之前,项目都是在html中引入一个个js文件来开发;而在webpack中,一切皆模块(js、css、图片、字体、),可以通过import、require来实现模块开发。帮助我们优化代码,提升性能
- 新语法
由于js、css等开发语言的语法在逐渐更新, 但浏览器不会实时更新兼容,webpack可以使用预处理器loader(例如less-loader、sass-loader、babel-loader)对文件进行预处理编译(例如less、sass、ES6、TS),这样使开发者更自由方便是使用最新的语法开发。
- 主流框架脚手架
一些主流的框架的脚手架(例如vue的vue-cli、react的create-react-app)都使用了webpack,因此可以根据项目需求,自由的配置webpack,从而提升项目性能
- 扩展性强、插件机制完善
开发者可以自定义插件、loader
- 拥有丰富的配置
依赖管理、动态打包、代码分离、按需加载、代码压缩、静态资源压缩、缓存等配置
- 社区庞大,轮子丰富
webpack处理应用程序递归构建的一个依赖关系图,核心就是文件之间的直接依赖关系。webpack通过依赖关系图获取非代码资源,比如images或字体,并把他们作为依赖提供给应用程序。
依赖关系图的开始,从入口开始寻找依赖,打包构建。(允许多个入口)
默认值是"./src/index.js"
例如:
module.exports = {
entry: "index.js"
}
指定打包的位置和文件名。
默认主要文件是"./dist/main.js"
其他默认文件位置是"./dist"
例如:
const path = require('path');
module.exports = {
entry: './my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
webpack默认只识别js和json文件,其他类型的文件(如css、ts)需要安装loader处理,webpack将他们转换成模块,同时被添加到依赖图中。
loader属性:
应用:通过单独定义一个module对象属性,定义rules属性,来配置loader的具体属性
示例:
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
插件是用来扩展webpack的工具,正是开发者社区插件的丰富使得webpack的功能更加丰富。
通常在先require引入,然后在plugins数组中定义插件。
示例:
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
module.exports = {
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
webpack提供了模式的选择(开发模式development、生产模式production、空模式none),可通过在不同环境选择不同的配置模式,让项目性能更优。
不同环境对应修改不同的配置文件(例如webpack.dev.js、webpack.prod.js)
示例:
module.exports = {
mode: 'development',
};
resolve用来设置模块如何解析,常用的配置有:
示例:
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.tsx', '.json'],
alias: {
'@': resolve('src'),
},
symlinks: false,
}
}
根据mode的不同值来自定义不同的webpack的内置优化配置,一般用于生产模式提升性能。
常用的配置项有:(详细的可查看API)
示例:
module.exports = {
//...
optimization: {
splitChunks: {
// include all types of chunks
chunks: 'all',
// 重复打包问题
cacheGroups:{
vendors:{ //node_modules里的代码
test: /[\\/]node_modules[\\/]/,
chunks: "all",
name: 'vendors', //chunks name
priority: 10, //优先级
enforce: true
}
}
},
runtimeChunk: {
name: 'runtime',
},
},
};
帮助我们在代码发生变化后自动编译代码,具有实时重新加载功能。
常用配置项: (详细的可查看API)
open:告诉 dev-server 在服务器项目启动后打开浏览器
port:本地环境的端口号
proxy:API请求代理配置(通过子属性targert设置API地址;默认情况,代理时会保留主机头的来源,可以通过子属性changeOrigin设置为 true覆盖此行为)
compress:默认为true。为每个静态文件开启gzip压缩
示例:
devServer: {
port: 8080,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
"/app-config": {
ws: false,
target: 'http://xx.xx.xx.xx:8080', // 后台接口地址
changeOrigin: true
},
}
}
缓存生成的 webpack 模块和 chunk,来改善构建速度。
他的值在开发模式下会被设置为cache: {type: 'memory'}(与cache: true作用一致);
生产模式下会被禁用。
项目中会使用到很多loader配置,每个loader对应提供了不同的功能。例如:
css-loader:会对@import和url()进行处理,就像js解析require和import一样;
babel-loader:通过babel和webpack将代码转译为js代码;
sass-loader:将预处理器scss/sass转译成css语法代码;
style-loader:把css插入到dom中;
html-loader:将html导出为字符串,在编译器需要时,将压缩html字符串
... ... 更多loader配置和使用功能可查看API
配置过程(以css-loader、style-loader为例,二者可串联配置):
1,安装loader的依赖:npm install --save-dev style-loader css-loader
2,修改通用环境配置文件 webpack.commom.js
const paths = require('./paths');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
include: paths.appSrc,
use: [
'style-loader', // 将JS字符串生成为 style 节点
'css-loader', // 将CSS转化成 CommonJS 模块
],
},
]
}
}
webpack5中,可以将images图片和font字体混入到系统中。
加载图片:
const paths = require('./paths');
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
include: paths.appSrc,
type: 'asset/resource',
},
],
},
}
加载字体:
module.exports = {
module: {
rules: [
{
test: /.(woff|woff2|eot|ttf|otf)$/i,
include: [
resolveApp('src'),
],
type: 'asset/resource',
},
]
}
}
webpack可以通过一些更详细的配置来实现性能优化。例如:
配置cache加快构建时间;
合理拆分chunks、压缩代码等来减小打包体积;
设置按需加载、浏览器缓存等加快加载速度。
具体可参考学习 Webpack5 之路(优化篇)