webpack 是一个现代 javascript 应用程序的静态模块打包器(module bundler),当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle(包)
webpack基本使用
webpack四个核心概念:
入口(entry):告诉 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始,默认值为 ./src输出(output):告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./distloader:可以将所有类型的文件转换为 webpack 能够处理的有效模块,让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)插件(plugins):用于扩展 webpack 的功能,相比于 loader, 插件功能更为强大,范围包括从打包优化和压缩,一直到重新定义环境中的变量,可以用于执行范围更广的任务
webpack打包的基本配置
新建项目目录:输出目录 /dist(打包后存放目录),/src(源代码目录)下面创建入口文件 main.js
初始化项目:
npm init
执行初始化项目会生成 pakeage.json 文件,这个文件主要用于记录在项目开发中所要用到的包,以及项目的详细信息等记录
安装 webpack webpack-cli:
npm install webpack webpack-cli -D
package.json 文件中配置 scripts:
{
......
"scripts": {
//执行打包:npm run build
"build": "webpack --config webpack.config.js"
}
}
新建 webpack 的配置文件 webpack.config.js:
const path = require('path');
//导出配置对象
module.exports = {
//entry:入口文件配置(从哪个文件开始打包)
entry: './src/main.js',
//output:出口文件配置(打包到哪里)
output: {
//打包输出的目录(绝对路径)
//path.resolve()方法会把一个路径或路径片段的序列解析为一个绝对路径
//__dirname是nodejs的一个全局变量,指向被执行js文件的绝对路径
path: path.resolve(__dirname, 'dist'),
//打包后生成的文件名
filename: 'js/bundle.js'
},
//mode:打包模式:production(压缩),development(不压缩)
mode: 'development'
}
执行配置的 scripts 脚本进行打包:
npm run build
执行打包后 /dist/js 文件夹下会有打包后的 bundle.js 文件
自动生成html插件:html-webpack-plugin
html-webpack-plugin 插件简化了HTML文件的创建实现,将为你生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包,实现 public 目录下 index.html 不需要手动引入打包后的文件,会被该插件自动生成 HTML 文件引入
安装 html-webpack-plugin:
npm install html-webpack-plugin -D
配置 webpack.config.js :
//引入html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
//导出配置对象
module.exports = {
......
//plugins:插件配置
plugins: [
......
new HtmlWebpackPlugin({
//html模板文件路径
templte: './public/index.html'
})
]
}
执行打包后 /dist 文件夹下会有 index.html 文件,并已经引入了打包后的文件
webpack使用Babel降级处理高版本的js语法
Babel 是 JavaScript 编译器,主要用于在旧的浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容的版本
babel-loader:允许你使用 Babel 和 webpack 转译 JavaScript 文件
安装依赖:
npm install -D babel-loader @babel/core @babel/preset-env
配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
......
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有js文件
test: /\.js$/,
//排除文件(排除node_modules文件夹)
exclude: /(node_modules)/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
webpack打包前清除dist目录
clean-webpack-plugin 插件可以在每次打包前清除 dist 文件夹,再打包生成新的打包文件
安装 clean-webpack-plugin:
npm install clean-webpack-plugin -D
配置 webpack.config.js :
//引入clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
//导出配置对象
module.exports = {
......
//plugins:插件配置
plugins: [
......
new CleanWebpackPlugin()
]
}
loader使用
webpack 可以使用 loader 来预处理文件,webpack 只能理解 JavaScript 和 JSON 文件,loader 让 webpack 能够处理其他类型的文件,并将它们转换为有效模块,这允许你打包除 JavaScript 之外的任何静态资源
webpack处理css文件
style-loader :将模块的导出作为样式添加到 DOM 中
css-loader :解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
入口文件 main.js 中使用 require() 引入css文件
安装 style-loader 和 css-loader:
npm install style-loader css-loader -D
配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
......
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有css文件
test: /\.css$/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//css-loader:让webpack能够识别解析css文件
//style-loader:通过js动态创建style标签,让解析后的css作用到页面中
use: ['style-loader', 'css-loader']
}
]
}
}
执行打包后,css文件会被打包到 bundle.js 中
分离css文件插件:mini-css-extract-plugin
mini-css-extract-plugin 插件可以将 CSS 提取为独立的文件,对每个包含 css 的 js 文件都会创建一个CSS文件,支持按需加载 css 和 sourceMap,该插件只能用于 webpack4 中
安装 mini-css-extract-plugin:
npm install mini-css-extract-plugin -D
配置 webpack.config.js :
//引入mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有css文件
test: /\.css$/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//css-loader:让webpack能够识别解析css文件
//mini-css-extract-plugin:分离css文件
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
//公共资源加载路径
publicPath: '../'
}
},
'css-loader'
]
}
]
},
//plugins:插件配置
plugins: [
......
new MiniCssExtractPlugin({
//打包好文件的存放路径和文件名(/dist/css/index.css)
filename: 'css/index.css'
})
]
}
执行打包后 /dist/css 文件夹下会有打包后的 index.css 文件
webpack处理less文件
less-loader:加载和转译 LESS 文件
入口文件 main.js 中使用 require() 引入less文件
安装 less 和 less-loader:
npm install less less-loader -D
配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
......
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有less文件
test: /\.less$/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//less-loader:将less文件转换成css文件
//css-loader:让webpack能够识别解析css文件
//mini-css-extract-plugin:分离css文件
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
//公共资源加载路径
publicPath: '../'
}
},
'css-loader',
'less-loader'
]
}
]
}
}
webpack处理图片
file-loader: 将文件发送到输出文件夹,并返回(相对)URL
url-loader: 像 file loader 一样工作,但如果文件小于限制,可以返回 data URL
安装 url-loader 和 file-loader:
npm install url-loader file-loader -D
配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
......
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有以.png .jpg .gif结尾的文件
test: /\.(png|jpg|gif)$/i,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//url-loader:让webpack能够识别解析图片文件
//图片会默认转成base64字符串,如果图片太大再转base64会让图片体积增大,可以通过options配置limit限制图片的转换
//图片打包后默认直接输出到dist目录下,可以通过options配置输出到指定目录下
use: [
{
loader: 'url-loader',
options: {
//图片小于8k,转换成base64,节约请求次数,大于8k,不转换成base64
limit: 8 * 1024,
//输出文件名
name: '[name].[ext]',
//静态资源引用路径
publicPath: '../images/',
//输出的文件目录
outputPath: 'images/'
}
}
]
}
]
}
}
webpack处理vue文件
安装 vue:
npm install vue
vue-loader:加载和转译 Vue 组件
vue-template-compiler:,模板解析器,解析 Vue 模板预编译为渲染函数
安装 vue-loader 和 vue-template-compiler:
npm install vue-loader vue-template-compiler -D
配置 webpack.config.js :
//引入vue-loader
const VueLoaderPlugin = require('vue-loader/lib/plugin')
//导出配置对象
module.exports = {
......
//module:模块加载规则
module: {
......
//loader:加载器的规则
rules: [
......
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有vue文件
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
//plugins:插件配置
plugins: [
......
new VueLoaderPlugin()
]
}
创建vue根组件 App.vue:
<template>
<div id="app"></div>
</template>
<script>
export default {
}
</script>
<style>
</style>
编写入口文件 main.js:
//引入vue
import Vue from 'vue'
//引入根组件App.vue
import App from './App.vue'
//创建vue实例
new Vue({
//提供一个页面上已存在的DOM元素作为vue实例的挂载目标
el: '#app',
//render函数用于渲染一个组件作为根组件(固定写法)
render (createElement) {
//把App.vue组件渲染为根组件
return createElement(App)
}
})
vue-cli脚手架环境下的webpack配置
在项目根目录下创建vue配置文件 vue.config.js,在 vue.congfig.js 中进行 webpack 配置,会覆盖 vue-cli 中 webpack 的默认配置
vue.congfig.js:
//导出配置对象
module.exports = {
......
}
webpack开发服务器
在项目开发的过程中,可以使用 webpack 启动一个开发服务器,方便实时查看调试项目
自动刷新服务器插件:webpack-dev-server
webpack-dev-server 为你提供了一个具有 live reloading(实时重新加载) 功能的简单的 web server,并且可以实现反向代理,解决在开发过程中的跨域问题
安装 webpack-dev-server:
npm install webpack-dev-server -D
配置 package.json:
{
......
"scripts": {
//执行打包:npm run build
"build": "webpack --config webpack.config.js",
//执行启动服务器:npm run dev
"dev": "webpack-dev-server --config webpack.config.js"
}
}
配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//devServer:开发服务器配置
devServer: {
//端口号
port: 9999,
//自动打开浏览器
open: true
}
}
执行配置的 scripts 脚本启动开发服务器:
npm run dev
反向代理配置:
通过开发服务器配置实现反向代理,解决在开发过程中的跨域问题 配置 webpack.config.js :
//导出配置对象
module.exports = {
......
//devServer:开发服务器配置
devServer: {
//端口号
port: 9999,
//自动打开浏览器
open: true,
//反向代理配置
proxy: {
//只要以/api接口开头的请求都会被反向代理
//需要修改请求地址中的'https://blog.csdn.net/weixin_45426836'为'/api'
//结果为:/api/a => https://blog.csdn.net/weixin_45426836/a
'/api': {
//反向代理基础路径
target: 'https://blog.csdn.net/weixin_45426836',
//路径重写(把/api从路径中去掉)
pathRewrite: { '^/api': '' }
}
}
}
}
上面反向代理配置情况下需要在请求接口时将地址中的 'blog.csdn.net/weixin_4542…' 改成 '/api'
webpack多入口多输出配置
在项目中如果需要引入多个入口文件,例如/src(源代码目录)下面有两个入口文件 one.js和two.js,两个入口文件独立存在,没有引用关系
配置 webpack.config.js:
const path = require('path');
//导出配置对象
module.exports = {
//entry:入口文件配置(从哪个文件开始打包)
//用对象的方式配置多个入口
entry: {
one: './src/one.js',
two: './src/two.js'
},
//output:出口文件配置(打包到哪里)
output: {
//打包输出的目录(绝对路径)
path: path.resolve(__dirname, 'dist'),
//打包后生成的文件名
//[name]动态读取entry的属性(one,two)
filename: 'js/[name].bundle.js'
}
}
执行打包后 /dist/js 文件夹下会有 one.bundle.js 和 two.bundle.js 两个打包后的文件
提取公共模块
在项目中如果引入多个文件,这些文件中如果有相同的模块(例如:都引入了jQuery库),就会被重复打包,为了避免这些模块被重复打包,减小打包后文件的体积,需要把公共模块提取到单独的文件中
配置 webpack.config.js:
//导出配置对象
module.exports = {
......
//optimization:优化配置
optimization: {
//代码块分割配置
splitChunks: {
//分割所有代码块
chunks: 'all',
//代码块分割后的名称,true表示基于块和缓存组密钥自动生成一个名称
name: true
}
}
}
公共模块的大小必须大于30kb才会被打包到独立的文件中 执行打包后 /dist/js 文件夹下会有提取公共模块的文件
分离 开发环境(development)和 生产环境(production)的配置文件
开发环境(development)用于开发过程中的本地运行,而 生产环境(production)用于运行在线上服务器,为了打包后运行在线上服务器的打包文件尽可能小,需要对开发环境和生产环境的 webpack 配置文件进行拆分,并抽离出公共配置部分
使用 webpack-merge 对开发环境 / 生产环境与公共的 webpack 配置文件进行合并
安装 webpack-merge:
npm install webpack-merge -D
新建 /config 文件夹用于存放拆分的 webpack 配置文件:
- /config
- webpack.common.js ------ 公共配置文件
- webpack.dev.js ------ 开发环境配置文件
- webpack.pro.js ------ 生产环境配置文件
公共配置文件 webpack.common.js:
const path = require('path');
//引入自动生成html插件:html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
//引入分离css文件插件:mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
//引入清除dist文件夹插件:clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
//导出配置对象
module.exports = {
//entry:入口文件配置(从哪个文件开始打包)
entry: './src/main.js',
//output:出口文件配置(打包到哪里)
output: {
//打包输出的目录(绝对路径)
path: path.resolve(__dirname, 'dist'),
//打包后生成的文件名
filename: 'js/bundle.js'
},
//module:模块加载规则
module: {
rules: [
//处理css文件
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有css文件
test: /\.css$/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//css-loader:让webpack能够识别解析css文件
//mini-css-extract-plugin:分离css文件
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
//公共资源加载路径
publicPath: '../'
}
},
'css-loader'
]
},
//处理less文件
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有less文件
test: /\.less$/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//less-loader:将less文件转换成css文件
//css-loader:让webpack能够识别解析css文件
//mini-css-extract-plugin:分离css文件
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
//公共资源加载路径
publicPath: '../'
}
},
'css-loader',
'less-loader'
]
},
//处理图片
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有以.png .jpg .gif结尾的文件
test: /\.(png|jpg|gif)$/i,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
//url-loader:让webpack能够识别解析图片文件
//图片会默认转成base64字符串,如果图片太大再转base64会让图片体积增大,可以通过options配置limit限制图片的转换
//图片打包后默认直接输出到dist目录下,可以通过options配置输出到指定目录下
use: [
{
loader: 'url-loader',
options: {
//图片小于8k,转换成base64,节约请求次数,大于8k,不转换成base64
limit: 8 * 1024,
//输出文件名
name: '[name].[ext]',
//静态资源引用路径
publicPath: '../images/',
//输出的文件目录
outputPath: 'images/'
}
}
]
},
//使用Babel降级处理高版本的js语法
{
//test:标识出被loader进行转换的文件
//正则表达式,匹配所有js文件
test: /\.js$/,
//排除文件(排除node_modules文件夹)
exclude: /(node_modules)/,
//use:配置转换时使用的loader
//处理顺序:从右向左执行
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
//plugins:插件配置
plugins: [
//自动生成html插件:html-webpack-plugin
new HtmlWebpackPlugin({
//html模板文件路径
templte: './public/index.html'
}),
//分离css文件插件:mini-css-extract-plugin
new MiniCssExtractPlugin({
//打包好文件的存放路径和文件名(/dist/css/index.css)
filename: 'css/index.css'
}),
//清除dist文件夹插件:clean-webpack-plugin
new CleanWebpackPlugin()
]
}
开发环境配置文件 webpack.dev.js:
//引入公共配置文件:webpack.common.js
const common = require('./webpack.common.js')
//引入合并配置文件的插件:webpack-merge
const merge = require('webpack-merge')
//webpack-merge可以接受多个参数, 会把参数对象合并成一个对象,如果有重复,后面的对象属性, 会覆盖前面的对象属性
//导出配置对象
module.exports = merge(common, {
//devServer:开发服务器配置
devServer: {
//端口号
port: 9999,
//自动打开浏览器
open: true
},
//mode:打包模式:开发环境
mode: 'development'
})
生产环境配置文件配置文件 webpack.pro.js:
//引入公共配置文件:webpack.common.js
const common = require('./webpack.common.js')
//引入合并配置文件的插件:webpack-merge
const merge = require('webpack-merge')
//webpack-merge可以接受多个参数, 会把参数对象合并成一个对象,如果有重复,后面的对象属性, 会覆盖前面的对象属性
//导出配置对象
module.exports = merge(common, {
//mode:打包模式:生产环境
mode: 'production'
})
对开发环境和生产环境的 webpack 配置文件进行拆分后,可以删除 webpack.config.js 配置 package.json,修改配置文件路径:
{
......
"scripts": {
//执行打包:npm run build
//修改打包文件路径为 config/webpack.pro.js(打包生产环境的配置文件)
"build": "webpack --config config/webpack.pro.js",
//执行启动服务器:npm run dev(启动开发服务器执行开发环境的配置文件)
//修改服务器启动文件路径为 config/webpack.dev.js
"dev": "webpack-dev-server --config config/webpack.dev.js"
}
}
参考文档
webpack中文文档:www.webpackjs.com/concepts/