目录
2、在命令行中修改打包的默认入口文件名、默认出口文件名和默认出口文件
3、在webpack.config.js 配置文件中修改webpack 的配置
4、修改了webpack.config.js 的文件名称后,如何运行配置文件?
1、autoprefixer 自动为有兼容性问题的css 样式添加前缀
2、postcss-preset-env 为开发时的主要功能预设配置(功能更强大,包括css 的浏览器兼容性问题)
六、webpack 搭建本地服务器(自动打包,自动刷新浏览器)
一、webpack 的基本配置
1、 webpack 的默认配置
- 默认入口文件 src/index.js
- 默认出口文件 dist/main.js
- 默认出口文件夹 dist
- 可以在命令行中通过 npx webpack 进行打包
2、在命令行中修改打包的默认入口文件名、默认出口文件名和默认出口文件
- --entry 修改文件的默认入口文件名
- --output-filename 修改文件的默认出口文件名
- --output-path 修改文件的默认出口文件夹
npx webpack --entry ./src/main.js --output-filename bundle.js --output-path ./build
3、在webpack.config.js 配置文件中修改webpack 的配置
const path = require("path")
// 因为webpack 是运行在node中,所以要使用node 的commonJS 模块化语法
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
// __dirname 获取当前文件所在路径
// path 的值需要使用绝对路径
path: path.resolve(__dirname, "./build")
}
}
4、修改了webpack.config.js 的文件名称后,如何运行配置文件?
- 如果将webpack.config.js 修改为wp.config.js 后在命令行中输入npx webpack 是找不到默认的配置文件的
- 可以再命令行中输入npx webpack --config wp.config.js 运行改名后的webpack配置文件 或者在package.json 文件中写脚本
// 默认的打包方式 webpack.config.js
"scripts": {
"build": "webpack"
}
// 然后在命令行中运行脚本
npm run build
// 修改配置文件名后的打包方式
"scripts": {
"build": "webpack --config wb.config.js"
}
// 然后在命令行中运行脚本
npm run build
二、loader
1、对于css 文件的处理
npm install css-loader -D
// css-loader 只负责解析css 文件,不会将文件插入到页面中
// 所以这时需要用到style-loader
npm install style-loader -D
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
// 告诉webpack 匹配什么类型的文件, 通常会设置成正则表达式
test: /\.css$/,
// 告诉webpack 使用什么样的loader 来处理匹配到的文件
// use 中多个loader 的使用顺序是从后往前的
use: [
{ loader: "style-loader", "css-loader" }
// { loader: "style-loader" },
// { loader: "css-loader" }
]
}
]
}
}
2、对于less 文件的处理
npm install less-loader -D
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader", "css-loader" }
]
},
{
test: /\.less$/,
use: [
{ loader: "style-loader", "less-loader", "less-loader"}
]
}
]
}
}
3、PostCSS 中的插件
1、autoprefixer 自动为有兼容性问题的css 样式添加前缀
当使用user-selece: none; (用户是否能选中)这样的具有兼容性问题的css 样式时,需要在该样式前加浏览器前缀,PostCSS 可以自动检测该css 样式是否具有兼容性问题,并自动添加浏览器前缀
npm install postcss-loader -D
// 自动添加浏览器前缀的插件
npm install autoprefixer -D
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [ "autoprefixer" ]
}
}
}
]
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader",
"postcss-loader"
]
}
]
}
}
或通过postcss.config.js 文件来配置postcss-loader
npm install postcss-loader -D
// 自动添加浏览器前缀的插件
npm install autoprefixer -D
// webpack.config.js
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader",
"postcss-loader"
]
}
]
}
}
// postcss.config.js
module.exports = {
plugins: [
"autoprefixer"
]
}
2、postcss-preset-env 为开发时的主要功能预设配置(功能更强大,包括css 的浏览器兼容性问题)
npm install postcss-loader -D
npm install postcss-preset-env -D
// webpack.config.js
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader",
"postcss-loader"
]
}
]
}
}
// postcss.config.js
module.exports = {
plugins: [
"postcss-preset-env"
]
}
4、webpack 处理图片
1、asset module type 资源模块类型
- 在webpack5 之前加载资源需要用到一些loader,比如:raw-loader、url-loader、file-loader
- 在webpack5 开始,可以直接通过资源模块类型,来替代上面的loader
资源模块类型,通过添加4种新的模块类型,来替换loader
- asset/resource 发送一个单独的文件并导出URL,之前通过file-loader 实现(打包图片并且该图片有自己的地址,将地址设置到img/bgi 中的url 中。缺点:多了对图片加载的网络请求,几张图片就请求几次)
- asset/inline 导出一个资源的data URI,之前通过url-loader 实现(将图片进行base64 的编码,并且直接将编码后的源码放到对应打包的js 文件中。缺点:造成打包后的js 文件比较大,造成对js 文件的下载和解析时间比较长) (合理的图片加载规范:对于小图片可以进行base64 编码,对于大图片,可以进行单独的图片打包,形成url 地址,单独的请求这个url 的图片。)
- asset/source 导出资源的源代码,之前通过使用raw-loader 实现(不常用)
- asset 在导出一个data URI 和发送一个单独的文件之间自动选择,之前通过url-loader,并且配置资源体积限制实现;
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [ "style-loader", "css-loader", "postcss-loader" ]
},
{
test: /\.less$/,
use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
// 资源模块类型
type: "asset"
}
]
}
}
2、对打包的图片重命名、根据图片大小区分打包方式
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.(png|jpe?g|svg|gif)$/,
// 资源模块类型
type: "asset",
// 为不用大小的图片区分打包的方式
parser: {
dataUrlCondition: {
// 小于60kb 就使用base64, 大于64kb 就单独进行打包
maxSize: 60 * 1024
}
}
// 对打包后的图片重新命名
generator: {
// img/: 表示将图片资源单独放到img 文件夹
// name: 用于指向原来的图片名称
// hash: webpack 生成的唯一的hash 值(:8 截取前8位)
// ext: 用于指向原来的图片后缀名
filename: "img/[name]_[hash:8][ext]"
}
}
]
}
}
5、webpack 对vue 文件的处理
npm install vue-loader -D
const path = require("path")
const { VueLoaderPlugin } from = require('vue-loader/dist/index')
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [ "style-loader", "css-loader", "postcss-loader" ]
},
{
test: /\.less$/,
use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
// 资源模块类型
type: "asset"
},
{
test: /\.vue$/,
use: [ "vue-loader" ]
}
]
},
plugins: [
new VueLoaderPlugin()
]
}
6、webpack 解析文件或文件夹
- 如果是文件,当省略文件后缀名时,通过webpack 配置默认添加文件后缀名。当引用App.vue 文件时,省略.vue 文件后缀名,如:import App from '@/views/App',可以通过webpack 的resolve.extensions 进行配置后默认添加文件后缀名
- 如果是文件夹,webpack 会根据resolve.mainFiles 查找index 文件,再通过resolve.extensions 来解析扩展名
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.css$/,
use: [ "style-loader", "css-loader", "postcss-loader" ]
},
{
test: /\.less$/,
use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
},
{
test: /\.(png|jpe?g|svg|gif)$/,
// 资源模块类型
type: "asset"
},
{
test: /\.vue$/,
use: [ "vue-loader" ]
}
]
},
resolve: {
extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
// 为固定的目录配置重命名
alias: {
src: path.resolve(__dirname, "./src")
}
}
plugins: [
new VueLoaderPlugin()
]
}
三、babel
当遇到ES6+ 、ts、jsx 的代码时通过babel 进行处理转成es5 的代码
babel 和postcss 一样可以单独拿出来配置,放到babel.config.js 配置文件中
babel 的预设:@babel/preset-env
npm install babel-loader -D
// babel 的预设
npm install @babel/preset-env -D
// webpack.config.js
const path = require("path")
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
// options: {
// presets: [
// "@babel/preset-env"
// ]
}
}
}
]
}
}
// babel.config.js
module.exports = {
presets: [
"@babel/preset-env"
]
}
四、plugin
1、loader 和plugin 的区别:
- loader 是用于特定的模块类型进行转换;
- plugin 可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;
2、CleanWebpackPlugin
当重新打包时,都需要手动删除dist 文件夹,可以通过clean-webpack-plugin 在打包时自动删除dist 文件夹
npm install clean-webpack-plugin -D
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack=plugin");
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
plugins: [
new CleanWebpackPlugin()
]
}
3、HtmlWebpackPlugin
当进行打包时,不会打包index.html 文件,可以通过html-webpack-plugin 在打包时自动生成index.html 文件,并进行打包
npm install clean-webpack-plugin -D
npm install html-webpack-plugin -D
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack=plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: '网页标题',
// 当不想使用默认生成的index.html 模板时,可以自己设置要使用的index.html 文件
template: './index.html'
})
]
}
4、DefinePlugin (注入变量)
npm install clean-webpack-plugin -D
npm install html-webpack-plugin -D
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack=plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { DefinePlugin } = require("webpack");
module.exports = {
mode: "development",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build")
}
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: '网页标题',
// 当不想使用默认生成的index.html 模板时,可以自己设置要使用的index.html 文件
template: './index.html'
}),
new DefinePlugin({
BASE_URL: "'./'",
coderwhy: "'why'",
counter: "123"
})
]
}
// 定义的是全局变量,可以在任何地方直接使用
// main.js
console.log(BASE_URL);
console.log(process.env.NODE_ENV);
五、Mode 模式
- 默认值是production
- 可选值有:"none" | "development" | "production"
- 当设置为"development",是会在DefinePlugin 中的process.env.NODE_ENV 设置为"development",并为模块和chunk 启用有效的名
- 当设置为 "production" 时,是会在DefinePlugin 中的process.env.NODE_ENV 设置为"production",并为模块和chunk 启用确定性的混淆名
六、webpack 搭建本地服务器(自动打包,自动刷新浏览器)
1、webpack-dev-server
开启一个本地服务器,供开发时使用
npm install webpack-dev-server -D
// package.json
"scripts": {
"serve": "webpack serve --config webpack.config.js"
}
npm run serve
2、devServer 配置
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./build");
}
devServer: {
// 默认为true
hot: true,
// 默认为localhost(127.0.0.1),也可以修改为0.0.0
host: "0.0.0",
// 默认是8080
port: 8888,
// 运行代码后自动打开浏览器
open: true
// 是否对文件进行压缩
compress: true
}
}
3、认识模块热替换(HMR)
- HMR 的全程是Hot Module Replacement, 翻译为模块热替换;
- 模块热替换是指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面;
- 当某一个模块发生变化,只需要加载该模块的变化,不需要刷新整个浏览器
// main.js
if(module.hot) {
module.hot.accept("./utils.js", () => {
console.log("utils更新了")
})
}
七、proxy
1、proxy 代理的配置
proxy 是用来设置代理来解决跨域访问的问题:
- 比如我们的一个api 请求的是http://localhost:8888,但是本地启动服务器的域名是http://localhost"8000, 这个时候发送网络请求会出现跨域的问题
- 那么我们可以将请求先发送到一个代理服务器,代理服务器和API服务器没有跨域问题,就可以解决跨域问题了
我们可以进行如下的设置:
- target:表示的是代理到的目标地址,比如/api-hy/moment会被代理到http://localhost:8888/api-hy/moment;
- pathRewrite:默认情况下,我们的/api-hy 也会被写入到URL 中,如果希望删除,可以使用pathRewrite
- secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false;
- changeOrigin:表示是否更新代理后请求的headers 中的host 地址
2、changeOrigin 的解析
changeOrigin 是要修改代理请求中的headers 中的host 属性
- 因为我们真是的请求,其实是需要通过http://localhost:8888来请求的
- 但是因为使用了代码,默认情况下它的值是http://localhost:8000
- 如果我们需要修改,那么可以将changeOrigin 设置为true 即可
3、historyApiFallback
- historyApiFallback 是开发中一个非常常见的属性,它主要的作用是解决SPA 页面在路由跳转之后,进行页面刷新时,返回404 的错误
- boolean 值:默认是false,如果设置为true,那么在刷新时,返回404错误时,会自动返回index.html 的内容
- object 类型的值,可以配置rewrites 属性:可以配置from 来匹配路径,决定要跳转到哪一个页面
- 事实上devServer 中实现historyApiFallback 功能是通过connect-history-api-fallback 库的;
八、webpack 区分环境
npm install webpack-merge -D
"scripts": {
"serve": "webpack serve --config ./webpack.dev.config.js",
"build": "webpack --config ./webpack.prod.config.js"
}
npm run serve
npm run build
// webpack.dev.config.js
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.comn.config.js");
module.exports = merge(commonConfig, {
mode: "development",
entry: "",
output: ""
})
// webpack.prod.config.js
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.comn.config.js");
module.exports = merge(commonConfig, {
mode: "production",
entry: "",
output: ""
})
// webpack.comn.config.js
// 用于书写公共配置