文件名:webpack.conig.js
书写一个 module.exports = { 所有的配置项 }书写一个 module.exports = { 所有的配置项 }
如何打包
以下是在生产
webpack@5 webpack-cli@3
注意这里是webpack-cli@3
直接打开命令行, 切换目录到你的项目根目录
1. 输入指令:
2.需要把这个指令配置在 package.json 文件中去启动
3. 配置 package.json 文件
=> 找到 scripts 字段
=> 添加一条内容
webpack 的默认内容
+ 默认会执行的配置文件叫做 webpack.config.js
=> 如果你的配置文件修改了, 创建指令的时候, 输入 webpack --config 你的配置文件名
+ 默认会把 src 目录下的 index.js 文件当做入口文件使用
+ 默认会把打包结果生成的文件放在一个叫做 dist 目录下
+ 默认会把生成的 js 文件叫做 main.js
单页面应用程序的规则
+ 所有的一切外部资源都书写在 index.js 这个入口文件中
基本配置
1. 入口项配置
+ 字段: entry
+ 值: 你的入口文件
2. 出口的配置
+ 字段: output
+ 值: { path: 路径, filename: 文件名称 }
+ 注意: 配置 path 路径信息的时候, 需要用到一个 绝对路径
3. 配置打包模式
+ 开发环境: development
+ 生产环境: production
+ 字段: mode
+ 值: 环境种类
4. 配置单页面
+ 作为一个单页面应用程序, 总需要一个 html 文件
+ 我们使用一个 html-webpack-plugin 来生成一个 html 文件
=> 下载导入以后得到的是一个 构造函数(类) 使用的时候需要和 new 连用
+ 需要在配置项内填写
=> 字段: plugins
=> 值: 一个数组
5. 配置解析插件
+ 为什么在 index.js 文件内导入了 css 文件以后会报错
=> 因为 webpack 默认的解析器只能解析 js 代码
=> 你导入了一个 index.css 文件, 里面书写的是 css 代码
=> js 解析器不认识, 所以就报错了
+ 解决方案:
=> 想办法让我们的 webpack 可以解析 css 代码
+ 给 webpack 添加各种各样的解析器, 使用 loader
=> 字段: module
=> 值: { loader 的配置 }
+ 解析 css 文件需要用到两个 loader
=> css-loader
-> 作用: 把 入口js文件 内导入的 css 文件里面的代码正常读取解析出来
=> style-loader
-> 作用: 把解析好的 css 文件以一个 style 标签的形式插入到 html 文件内
+ loader 的使用是不需要导入的, 直接配置就可以了
5-2. 配置一个解析 sass 文件的解析器
+ 需要用到的 loader
=> sass-loader
-> 把 sass 语法转化成 css 语法
=> css-loader
-> 作用: 把 入口js文件 内导入的 css 文件里面的代码正常读取解析出来
=> style-loader
-> -> 作用: 把解析好的 css 文件以一个 style 标签的形式插入到 html 文件内
+ 注意:
=> sass-loader 需要依赖一个第三方叫做 sass
5-3. 配置一个解析 less 文件的解析器
+ 需要用到的 loader
=> less-loader
=> css-loader
=> style-loader
+ 注意: less-loader 需要依赖一个第三方叫做 less
代码:
// 导入一个 path 模块用来帮我们组装出绝对路径
const path = require('path')
// 导入 html 插件
const HtmlWebpckPlugin = require('html-webpack-plugin')
// 对应步骤4: 使用 HtmlWebpckPlugin 这个插件生成一个 html 文件信息
// 这个插件什么都不配置的时候, 会自动生成一个 html 文件
const htmlTemplate = new HtmlWebpckPlugin({
// html 文件中的 title 标签內的內容
title: 'webpack 學習',
// 配置生成的 html 文件名
// 如果你不设置默认叫做 index.html
filename: 'index.html',
// 因为这个 HtmlWebpackPlugin 会自动把生成的 js 文件引入到 html 文件
// 默认放在 head 标签内
// head: 表示放在 head 的末尾
// body: 表示放在 body 的末尾
inject: 'body',
// 网站小图标的地址
favicon: './src/assets/icon.ico',
// 模板文件
// HtmlWebpackPlugin 默认是生成一个 空的 html 文件
// 你可以选择一个你写好的 html 文件当做模板使用
template: './index.html'
})
// 当前项目的所有打包配置
module.exports = {
// 1. 入口项配置
entry: './src/index.js',
// 2. 出口配置项
output: {
path: path.resolve(__dirname, './dist'),
filename: 'main.js'
},
// 3. 配置打包模式
mode: 'production',
// mode: 'development',
// 4. 插件的配置
plugins: [
// 使用的是 html 生成的模板
htmlTemplate
],
// 5. 各种解析器的配置
module: {
// 表示各种解析规则的使用
rules: [
// 每一个对象就是一种文件的解析器
// 此配置项的作用, 就是当你在 入口文件内, 导入一个 .css 结尾的文件的时候
// 会先经过 css-loader 解析, 再经过 style-loader 解析
{
// 匹配所有 index.js 文件中导入的以 .css 结尾的文件
test: /\.css/,
// use 的值是一个数组, 配置你所有需要使用的 loader
// 注意: 从后向前使用的
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(sass|scss)/,
use: [ 'style-loader', 'css-loader', 'sass-loader' ]
},
{
test: /\.less/,
use: [ 'style-loader', 'css-loader', 'less-loader' ]
}
]
}
}
6. 配置解析图片
+ 注意: 不管你用那种方式, 我们都需要配置 url-loader 解析器
=> 6-1 方式是必选方式
6-1. 解析图片第一种方式
+ 需要用到的 loader 是 url-loader
+ 照常配置解析器
+ 使用的时候:
=> 需要在 入口js 文件内以导入图片的形式来使用
=> 不能直接在 html 文件内引入
=> 注意: 这种使用方式, 默认是把 图片转换成 base64 编码的形式插入到页面上
=> 导致: 编码可能比原图还要大
=> 合理情况应该是:
-> 小图片, 变成编码
-> 大图片, 变成图片文件引入
+ 解决图片引入是 base64 编码形式
=> 需要依赖一个 file-loader 的解析器
-> 这个解析器需要下载, 但是不需要引入配置
=> 需要在 url-loader 的配置上进行修改
6-2. 解析图片第二种方式
+ 需要用到的 loader 是 html-loader
=> 前提也是要配置好 url-loader
+ 配置解析器的时候
=> 配置的是 html 文件
=> 因为你需要在 html 文件内引入 图片文件
=> 必须要对 html-loader 进行配置项的书写
=> 注意: 还需要配置一个出口位置的 公共路径
6-3. 图片引入第三种方式
+ 依旧是需要用到 url-loader 和 file-loader
+ 只需要进行 6-1 基础配置即可
+ 注意: 绝对不能书写 6-2 的 html-loader 配置
+ 和 6-1 基本区别不大
=> 只是不需要在 js 文件内导入了
=> 直接在 html 文件内以 CommonJS 的方式导入 图片
+ 重点: 需要在 url-loader 的配置内关闭强制使用 es6 模块化语法
总结图片引入
+ 首先:
=> 下载 url-loader 和 file-loader
+ 必须要配置 url-loader
module: {
rules: [
...,
{
test: /\.(gif|jpg|jpeg|png|webp)/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100,
name: 'images/[hash].[ext]',
esModule: false
}
}
]
}
]
}
+ 此时已经可以正常引入图片了
=> 在 js 内使用导入图片的方式
import img from '图片地址'
const imgTag = document.createElement('img')
imgTag.src = img
xxx.appendChild(imgTag)
=> 也可以直接在 html 文件内引入
<img src="<%= require('图片路径地址') %>" />
+ 如果你想在 html 内按照常规方式引入图片
=> 你需要下载一个 html-loader
=> 在出口位置配置公共路径
output: {
...,
publicPath: './'
}
=> 配置一个 html-loader
module: {
rules: [
...,
{
test: /\.html/,
use: [
{
loader: 'html-loader',
options: {
esModule: false
}
}
]
}
]
}
=> 此时就可以直接在 html 文件内使用了
<img src="图片路径地址" />
7. 处理 css 文件问题
+ 目前对于 css 文件的最后一步处理使用的是 style-loader
=> 这个 loader 的作用 就是把 css 代码转化成 style 标签插入到页面内
=> 如果你需要使用 css 文件的形式, 那么就不能使用这个 loader
+ 想生成 css 文件
=> 需要用到一个插件
=> mini-css-extract-plugin
=> 导入以后和 html-webpack-plugin 是一样的, 都是一个构造函数(类)
+ 替换 loader
=> 这个 类 自己本身带有一个 loader
=> 使用这个 loader 去替换原先使用的 style-loader 即可
// 书写当前项目的打包配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 生成一个 html 模板
const htmlTemplate = new HtmlWebpackPlugin({
filename: 'home.html',
favicon: './src/images/favicon.ico',
inject: 'body',
template: './index.html'
})
// 生成一个 css 解析模板
// 注意: 这个是插件配置, 放在 plugins 配置项内
const cssTemplate = new MiniCssExtractPlugin({
// 配置文件名称
// 将来会在 dist 目录下生成一个叫做 css 的文件夹, 里面存储内容
filename: 'css/[hash].css'
})
module.exports = {
// 1. 入口文件配置
entry: './src/index.js',
// 2. 出口文件配置
// 注意: path 配置需要使用绝对路径
output: {
path: path.resolve(__dirname, './dist/'),
filename: 'main.js',
// 如果你要使用第二种引入图片的方式, 需要在这里配置公共路径
publicPath: './'
},
// 3. 配置打包模式
mode: 'production',
// 4. 插件配置
plugins: [
htmlTemplate,
cssTemplate
],
// 5. loader(解析器) 配置
module: {
rules: [
{
test: /\.css/,
// 你希望解析完的 css 代码单独生成一个文件, 那么我们在这里替换 loader
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
},
{
test: /\.(scss|sass)/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ]
},
{
test: /\.(jpg|jpeg|png|gif|webp)/,
// 换一种方式配置 loader, [ {} ]
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100,
name: 'images/[hash].[ext]',
esModule: false
}
}
]
}
]
}
}
8. 自动删除本地的 dist 目录
+ 每次打包的时候, 都是按照最新的 src 打包出指定的内容
+ 放在 dist 目录内, 并不会删除以前的内容
+ hash 名字的规则
=> 按照文件内的内容多少和内容来生成一个随机的名字
=> 只要你文件内的内容不变, 那么生成的名字不变
+ 缺点:
=> 当你在修改文件的时候, 需要手动删除 dist 目录
=> 在根据当前的 src 生成一个最新的内容
+ 解决:
=> 需要一个插件来帮我们自动删除 dist 目录
=> clean-webpack-plugin
=> 导入以后是一个 构造函数(类), 需要和 new 连用生成模板
+ 注意:
=> clean-webpack-plugin 这个第三方导入的是一个对象
=> 里面的某一个内容才是真正的构造函数
=> { CleanWebpackPlugin: 构造函数 }
// 书写当前项目的打包配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 生成一个 html 模板
const htmlTemplate = new HtmlWebpackPlugin({
filename: 'home.html',
favicon: './src/images/favicon.ico',
inject: 'body',
template: './index.html'
})
// 生成一个 css 解析模板
const cssTemplate = new MiniCssExtractPlugin({
filename: 'css/[hash].css'
})
// 生成一个 clean 删除模板
// 注意: 这个是插件, 需要配置在 plugins 配置项内
const cleanTemplate = new CleanWebpackPlugin({
// 配置一个你要删除的目录
path: './dist/'
})
module.exports = {
// 1. 入口文件配置
entry: './src/index.js',
// 2. 出口文件配置
// 注意: path 配置需要使用绝对路径
output: {
path: path.resolve(__dirname, './dist/'),
filename: 'main.js',
publicPath: './'
},
// 3. 配置打包模式
mode: 'production',
// 4. 插件配置
// 注意: plugins 内的所有插件, 是有顺序关系, 按照数组的索引顺序执行的
plugins: [
cleanTemplate,
htmlTemplate,
cssTemplate
],
// 5. loader(解析器) 配置
module: {
rules: [
{
test: /\.css/,
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
},
{
test: /\.(scss|sass)/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ]
},
{
test: /\.(jpg|jpeg|png|gif|webp)/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100,
name: 'images/[hash].[ext]',
esModule: false
}
}
]
}
]
}
}
// 书写当前项目的打包配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 生成一个 html 模板
const htmlTemplate = new HtmlWebpackPlugin({
filename: 'home.html',
favicon: './src/images/favicon.ico',
inject: 'body',
template: './index.html'
})
// 生成一个 css 解析模板
const cssTemplate = new MiniCssExtractPlugin({
filename: 'css/[hash].css'
})
// 生成一个 clean 删除模板
// 注意: 这个是插件, 需要配置在 plugins 配置项内
const cleanTemplate = new CleanWebpackPlugin({
// 配置一个你要删除的目录
path: './dist/'
})
module.exports = {
// 1. 入口文件配置
entry: './src/index.js',
// 2. 出口文件配置
// 注意: path 配置需要使用绝对路径
output: {
path: path.resolve(__dirname, './dist/'),
filename: 'main.js',
publicPath: './'
},
// 3. 配置打包模式
mode: 'production',
// 4. 插件配置
// 注意: plugins 内的所有插件, 是有顺序关系, 按照数组的索引顺序执行的
plugins: [
cleanTemplate,
htmlTemplate,
cssTemplate
],
// 5. loader(解析器) 配置
module: {
rules: [
{
test: /\.css/,
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
},
{
test: /\.(scss|sass)/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ]
},
{
test: /\.(jpg|jpeg|png|gif|webp)/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100,
name: 'images/[hash].[ext]',
esModule: false
}
}
]
}
]
}
}
9. 对于 css 文件的压缩处理
+ 实现 css 的压缩
+ 需要用到一个第三方
=> optimize-css-assets-webpack-plugin
=> 使用方式不一样了
+ 需要单独配置一项
=> optimization: {}
+ 导入以后就是一个构造函数(类), 直接使用
+ 出现一个小问题: 会导致 js 代码不在压缩了
=> 需要单独一个插件, 让 js 文件单独压缩一遍
=> 叫做 uglifyjs-webpack-plugin
=> 使用方式和 optimize-css-assets-webpack-plugin 是一样的
// 书写当前项目的打包配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const OptimizeWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
// 生成一个 html 模板
const htmlTemplate = new HtmlWebpackPlugin({
filename: 'home.html',
favicon: './src/images/favicon.ico',
inject: 'body',
template: './index.html'
})
// 生成一个 css 解析模板
const cssTemplate = new MiniCssExtractPlugin({
filename: 'css/[hash].css'
})
// 生成一个 clean 删除模板
const cleanTemplate = new CleanWebpackPlugin({
path: './dist/'
})
module.exports = {
// 1. 入口文件配置
entry: './src/index.js',
// 2. 出口文件配置
output: {
path: path.resolve(__dirname, './dist/'),
filename: 'main.js',
publicPath: './'
},
// 3. 配置打包模式
mode: 'production',
// 4. 插件配置
plugins: [
cleanTemplate,
htmlTemplate,
cssTemplate
],
// 5. loader(解析器) 配置
module: {
rules: [
{
test: /\.css/,
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
},
{
test: /\.(scss|sass)/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ]
},
{
test: /\.(jpg|jpeg|png|gif|webp)/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100,
name: 'images/[hash].[ext]',
esModule: false
}
}
]
}
]
},
// 9. 压缩器
optimization: {
// 配置压缩插件
minimizer: [
// 配置压缩 css 文件
new OptimizeWebpackPlugin(),
// 配置压缩 js 文件
new UglifyjsWebpackPlugin()
]
}
}
webpack-cli@3
这个插件用在开发环境
# 开发环境打包
+ 不需要压缩文件
+ 不需要生成过多的额外文件, 只要能在浏览器正常运行就够了
+ 不需要 dist 文件夹
=> 不需要你生成文件出来, 能在 电脑内存 中临时保存运行即可
=> 等到开发完毕, 在打包出来 dist 文件夹就可以了
+ 需要启动一个服务器
=> 来帮我们运行页面
=> 需要一个第三方叫做 webpack-dev-server
=> 注意: 如果你的 webpack-cli 是 3 的版本, 那么这个 webpack-dev-server 也要是 3 的版本
=> 注意: 如果你的 webpack-cli 是 4 的版本, 那么这个 webpack-dev-server 也要是 4 的版本
+ 需要去 package.json 文件中配置一个新的指令
=> 注意: 不要用 webpack 去运行打包命令了, 需要用 webpack-dev-server 去运行打包命令
+ 需要在配置文件内多加一项内容
=> 在 module.exports 内添加一个 devServer: {}
=> 注意: 当你开启了服务器以后, 所有的静态资源都要从服务器访问
-> 你的 output 里面的 publicPath 配置需要修改
# 开发环境打包
+ 不需要压缩文件
+ 不需要生成过多的额外文件, 只要能在浏览器正常运行就够了
+ 不需要 dist 文件夹
=> 不需要你生成文件出来, 能在 电脑内存 中临时保存运行即可
=> 等到开发完毕, 在打包出来 dist 文件夹就可以了
+ 需要启动一个服务器
=> 来帮我们运行页面
=> 需要一个第三方叫做 webpack-dev-server
=> 注意: 如果你的 webpack-cli 是 3 的版本, 那么这个 webpack-dev-server 也要是 3 的版本
=> 注意: 如果你的 webpack-cli 是 4 的版本, 那么这个 webpack-dev-server 也要是 4 的版本
+ 需要去 package.json 文件中配置一个新的指令
=> 注意: 不要用 webpack 去运行打包命令了, 需要用 webpack-dev-server 去运行打包命令
+ 需要在配置文件内多加一项内容
=> 在 module.exports 内添加一个 devServer: {}
=> 注意: 当你开启了服务器以后, 所有的静态资源都要从服务器访问
-> 你的 output 里面的 publicPath 配置需要修改