简介
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
核心概念
- entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
- Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
Webpack 启动后会从Entry里配置的Module开始递归解析
Entry
依赖的所有Module
。 每找到一个 Module, 就会根据配置的Loader
去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个Chunk
。最后 Webpack 会把所有 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。
一、简单的单页面配置
1、webpack.config.js最简单目录结构
module.exports = {
mode:'development', //开发还是生产模式
entry:"./src/index.js", //入口文件
output: { //出口
},
devServer: { //开发服务
},
module: { //模块的配置
},
plugins: [ //插件
]
};
复制代码
2、output出口文件
output: {
//打包后的文件名
filename:'bundle.js',
//打包后的目录,必须绝对路径
path:require('path').resolve(__dirname,'dist')
},
复制代码
3、plugins 插件的 配置
- npm i html-webpack-plugin
let htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new htmlWebpackPlugin({
template:'./src/index.html', //模板文件
filename:'index.html' //打包后的文件名称
})
]
复制代码
4、往src/index.js主文件添加点内容
- src/index.js主文件
//主模块 webpack默认会识别js模块
import str from "./a";
console.log(str);
document.getElementById('app').innerHTML = 'hello world'
复制代码
- src/a.js 证明下可以使用es6语法
export default 'hello'
复制代码
- src/index.html只放一个div
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
复制代码
5、测试效果
到这里,就可以实现打包了,但我们需要在package.json写两个命令
输入npm run dev 查看结果
6、增加css、less的支持
6.1 安装依赖的loader
- npm i style-loader css-loader less-loader -D
- 配置module里面的规则
module: { //模块的配置
rules: [
{
test:/\.css/,use:['style-loader','css-loader']
},
{
test:/\.less/,use:['style-loader','css-loader','less-loader']
}
]
},
复制代码
6.2 src/index.js引入index.css和index.less文件
//主模块 webpack默认会识别js模块
import str from "./a";
console.log(str);
document.getElementById('app').innerHTML = 'hello world'
import "./index.css" //引入css
import "./index.less" //引入less
复制代码
6.3 增加点样式
- 简单的增加两个样式
测试效果
6.4 优化改进
效果实现了,但是有个问题,我们看下渲染出来的页面结构
要解决这个问题,需要引入一个插件 mini-css-extract-plugin
- 安装插件 npm i mini-css-extract-plugin -D
- 修改module中的规则
module: { //模块的配置
rules: [
{
test: /\.css$/, use: [{ //指定对应的loader
loader: MiniCssExtractPlugin.loader
}, 'css-loader']
},
{test:/\.less$/,use:[{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'less-loader']
}
]
},
复制代码
- 使用mini-css-extract-plugin插件
let MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new MiniCssExtractPlugin({
// 指定打包后的输出目录
filename: "css/index.css",
})
],
复制代码
看下效果
二、多页面多入口配置
我们假定有2个页面 index.html 、login.html
- index.html保持不变
- login.html 引入一个login.js文件
2.1修改entry
entry: {
"index":"./src/index.js", //前面的key用于标识,后面会用到
'login':'./src/login.js'
},
复制代码
2.2修改output
output: { //出口
filename: "js/[name].js", //打包后的目录格式 [name]对应上面定义的key
//出口路径是一个绝对路径
path: require("path").resolve(__dirname, 'dist')
},
复制代码
需要主要的是[name]对应entry对应的key
2.3修改plugins
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
chunks:['index']
}),
new htmlWebpackPlugin({ //增加一个htmlWebpackPlugin
template: './src/index.html',
filename: 'login.html',
chunks:['login']
}),
new MiniCssExtractPlugin({
filename: "css/index.css"
})
]
复制代码
chunks代码块,也是对应entry中的key,
2.4增加login.js
- 简单的弹出一句话
alert('我是login页面')
复制代码
2.5测试
- 测试index.html页面
- 测试login.html
- 测试下打包后的文件
目前为止,多页面多入口已经简单实现,你可能会问当有很多的页面时候怎么办?
- 可以写个循环,动态的生成new htmlWebpackPlugin(),根据你对应的依赖进行选择
三、介绍几个常用插件(后续更新)
3.1、clean-webpack-plugin
可以在每次打包的时候,把dist目录清空,然后打包最新的文件。很简单,就不废话了。
let cleanWebpackPlugin = require('clean-webpack-plugin');
plugins: [
new cleanWebpackPlugin(['./dist']),
]
复制代码
3.2webpack自带的热更新模块
- 我们可以自定义开发服务的端口,设置热更新
let webpack = require('webpack');
devServer: { //开发服务
contentBase:"./dist", //启用静态服务目录
port:3000,
hot:true
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
]
复制代码
- 在文件监听热更新,以index.js为例
//主模块 webpack默认会识别js模块
import str from "./a";
console.log(str);
document.getElementById('app').innerHTML = 'hello world'
import "./index.css"
import "./index.less"
//如果有热更新 就启动热更新
if(module.hot){
module.hot.accept();
}
复制代码