webpack
介绍
webpack是一个构建工具,实现了模块化管理项目.他的工作方式是用各种loader将各种资源转化为js文件或者对js文件进行压缩编译亦或对静态资源进行处理.
官网:webpack
由来
模块化存在一些问题
1. ESM的兼容性问题
2. 模块文件过多,网络请求频繁
3. 前端的所有资源包括html和css都需要模块化
构建工具应运而生,需要一个集编译,模块打包,支持不同的资源的模块打包工具.Webpack就是当前最流行的前端构建工具.
Webpack初体验
先进行初始化 yarn init
再通过包管理工具添加webpack和webpack-cli
//--dev指定为开发依赖
yarn add webpack webpack-cli --dev
使用
yarn webpack
对项目进行打包,按照webpack的默认的规则
Webpack的配置文件
- 在项目的根目录下新建一个
webpack.config.js
的文件作为webpack的配置文件.由于是js文件是按照nodejs的格式进行书写. - 对入口文件打包后的文件路径以及文件名字,loader进行配置
webpack的工作模式
webpack的工作模式有三种: 优化模式(production
),开发模式(development
),和none模式
- 优化模式会对代码进行自动压缩优化.
- 开发模式会优化打包速度出现一些辅助.
- 会按照原来的格式打包不做处理,最原始的代码
使用
1.直接在打包时配置 --mode [ 工作模式 ]
2.在配置文件中写入 mode 的配置
资源模块加载
原生内置的webpack只支持打包js文件,使用loader加载器加载其他类型的文件,loader是前端加载资源的核心,通过配置loader和插件 可以加载任意资源.
webpack本身只能打包不能编译
常用的加载器大体分为三类
- 编译转换
- 文件操作
- 代码检查
!!! 如果是前端的代码没有相互的依赖关系,可以使用index.js,在该文件中集中导出,html,js还有css等资源.
1. css资源
yarn add css-loader style-loader --dev
添加依赖到开发环境中,不会在打包时将node模块打包进去,如果不小心打包进去应该在移除之后重新添加.
打包后css文件会被使用脚本注入.
文件资源加载器
像图片和字体这些资源无法用js表示,需要用到文件资源管理器.
file-loader 或者 url-loader
可以用来转化资源文件
一种是打包到根目录另一个是生成字符串直接表示文件.
webpack特性
- 对import 和 export的支持是为了打包,webpack并不会转化es6的代码,
需要配置 label-loader
才能进行编译转化 - 支持多种模块规范,但是最好不要混淆使用.
webpack插件(plugin)
自动化构建体验,比加载器有更为宽泛的使用的功能.
Webapck的开发体验增强
1. webpack自动编译
可以在构建时添加 --watch参数 cli会在打包后继续运行,监视文件的变化并且进行重新构建.
集成工具
Webpack Dev Server 是一个自动的http开发服务器
可以在启动时加上–hot参数启动热更新
也可以添加到配置文件中.
构建实例
const path = require("path")
const HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //清理dist的插件
const webpack = require('webpack'); // 用于访问内置插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { Script } = require("vm");
const { options } = require("./router/userRouter");
module.exports = {
mode: 'development', //指定为开发模式
devtool: 'source-map',
target: 'node',
// 入口文件
entry: {
server: './app.js',
main: './main.js'
},
// 出口文件
output: {
// 输出到dist文件夹
path: path.resolve(__dirname, 'dist'), //__dirname: 表示当前文件的绝对路径(根目录)
filename: (pathData) => {
if (pathData.chunk.name === 'server'){
return 'router/[name].js'
} else{
return 'js/[name].js'
}
},
clean: true
},
// 插件数组
plugins: [
//每个html文件都要设置
new HtmlWebpackPlugin({
template: './views/login.html',
filename: './views/login.html',
chunks: ['main'] // 关联的 JS 文件
}),
new HtmlWebpackPlugin({
template: './views/order.html',
filename: './views/order.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
template: './views/index.html',
filename: './views/index.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
template: './views/goods.html',
filename: './views/goods.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
template: './views/user.html',
filename: './views/user.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
template: './views/404.html',
filename: './views/404.html',
chunks: ['main']
}),
new MiniCssExtractPlugin({ filename: './assets/css/[contenthash:6].css' }),
new CleanWebpackPlugin(), //用来清理每次重新打包的时候的dist文件夹中多余的东西
new webpack.HotModuleReplacementPlugin()
],
module: {
rules: [
{
test: /\.html$/,
use: 'html-loader'
},
{
test: /\.css$/, // 正则匹配css文件
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|jpg|gif|jpeg|webp|svg|ico|mp4)$/,
type: 'asset',
use:{
loader: 'url-loader',
options: {
limit: 1024 * 8,
name: '[hash:6].[ext]',
publicPath: './assets/img/',
outputPath: './assets/img/'
}
}
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
devServer: {
static: path.join(__dirname, '/dist'), // 静态文件的目录
compress: true, // 启用gzip压缩
port: 8080, // 服务器端口
hot: true, // 启用模块热替换
open: true, // 自动打开浏览器
historyApiFallback: true,
proxy: [
{
context: ["/auth", "/api"],
target: "http://localhost:8085",
},
]
}
}