使用Webpack搭建项目(vue篇)
本篇承接使用Webpack搭建项目(react篇)
由于大部分配置一样,我们从上一篇react项目中,复制webpack.dev.js以及webpack.prod.js
开发模式
1.删除ReactRefreshWebpackPlugin
2.自动补充拓展名修改为.vue文件,同时处理js文件,不是jsx
const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
//返回处理样式的loader函数
let getStyleLoaders=function(pre){
return[
"style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: undefined,
filename: "static/js/[name].js",
chunkFilename: "static/js/[name].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]"
},
module: {
rules: [
// 处理css
{
test: /\.css$/,
use: getStyleLoaders(),
},
{
test: /\.less$/,
use: getStyleLoaders('less-loader'),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders('sass-loader'),
},
{
test: /\.styl$/,
use: getStyleLoaders('stylus-loader'),
},
//处理图片
{
test:/\.(jpe?g|png|gif|webp|svg)$/,
type:"asset",
parser:{
dataCondition:{
maxSize:10*1024, //小于10kb以下可以转为base64,减少请求数量
}
}
},
// 处理其他资源
{
test:/\.(woff2?|ttf)$/,
type:"asset/resource",
},
//处理js
{
test:/\.js$/,
include:path.resolve(__dirname,'../src'),
loader:"babel-loader",
options:{
cacheDirectory:true,
cacheCompression:false,
}
}
]
},
plugins:[
new EslintWebpackPlugin({
context:path.resolve(__dirname,'../src'),
exclude:'node_modules',
cache:true,
cacheLocation:path.resolve(__dirname,'../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template:path.resolve(__dirname,"../public/index.html"),
}),
],
mode:"development",
devtool:"cheap-module-source-map",
optimization:{
splitChunks:{
chunks:"all" //代码分割
},
runtimeChunk:{
name:entrypoint=>`runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
}
},
//webpack解析块加载选项
resolve:{
//自动补全文件拓展名
extensions:[".vue",".js",".json"]
},
devServer:{
host:"localhost",
port:3000,
open:true,
hot:true,
historyApiFallback:true//解决前端路由刷新404的问题
}
}
3.配置vue loader
npm init -y
npm install -D vue-loader vue-template-compiler
const { VueLoaderPlugin } = require('vue-loader')
let getStyleLoaders = function (pre) {
return [
"vue-style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre
].filter(Boolean)
}
{
test: /\.vue$/,
loader: 'vue-loader'
}
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
new VueLoaderPlugin()
],
接下来下载依赖:
npm i eslint-webpack-plugin html-webpack-plugin vue-style-loader css-loader postcss-loader postcss-preset-env -D
npm i less-loader sass-loader stylus-loader sass babel-loader vue-loader webpack webpack-cli webpack-dev-server -D
新建配置.eslintrc.js
npm i @babel/eslint-parser -D
module.exports={
root:true, //根目录就是当前
env:{
node:true //启用node中的变量
},
extends:["plugin:vue/vue3-essential","eslint:recommended"],//无需安装,已经内置有
parserOptions:{
parser:"@babel/eslint-parser" //需要安装
}
}
新建配置babel.config.js
npm i @vue/cli-plugin-babel -D
module.exports={
presets:["@vue/cli-plugin-babel/preset"]
}
补全src文件以及public文件,下载vue(默认vue3)
npm i vue
//main.js
import {createApp} from "vue"
import App from "./App"
createApp(App).mount(document.getElementById("app"))
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue-cli</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
//App.vue
<template>
<h1 class="title">hello app!</h1>
</template>
<script>
export default{
name:"App"
}
</script>
<style lang="less">
.title{
color:red
}
</style>
配置package.json
npm i cross-env -D
"scripts": {
"start":"npm run dev",
"dev":"cross-env NODE_ENV=development webpack serve --config ./config/webpack.dev.js"
},
npm i eslint-plugin-vue -D
然后输入 npm start ,发现如下警告:
我们需要定义这两个标识:
const {DefinePlugin} = require("webpack")
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
在编译就解决了,热模块更新HMR,都已内置,无需再配置了。
下面配置一下路由:
npm i vue-router
router.js
import { createRouter, createWebHistory } from "vue-router";
export default createRouter({
history:createWebHistory(),
routes:[
{
path:"/home",
component:()=>import ("../views/Home/Home.vue")
},
{
path:"/about",
component:()=>import ("../views/About/About.vue")
}
]
})
main.js
import {createApp} from "vue"
import App from "./App"
import router from "./router/router"
createApp(App).use(router).mount(document.getElementById("app"))
以上就是开发环境的基本配置,webpack.dev.js代码如下:
const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
return [
"vue-style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: undefined,
filename: "static/js/[name].js",
chunkFilename: "static/js/[name].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]"
},
module: {
rules: [
// 处理css
{
test: /\.css$/,
use: getStyleLoaders(),
},
{
test: /\.less$/,
use: getStyleLoaders('less-loader'),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders('sass-loader'),
},
{
test: /\.styl$/,
use: getStyleLoaders('stylus-loader'),
},
//处理图片
{
test: /\.(jpe?g|png|gif|webp|svg)$/,
type: "asset",
parser: {
dataCondition: {
maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
}
}
},
// 处理其他资源
{
test: /\.(woff2?|ttf)$/,
type: "asset/resource",
},
//处理js
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
mode: "development",
devtool: "cheap-module-source-map",
optimization: {
splitChunks: {
chunks: "all" //代码分割
},
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
}
},
//webpack解析块加载选项
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"]
},
devServer: {
host: "localhost",
port: 3000,
open: true,
hot: true,
historyApiFallback: true//解决前端路由刷新404的问题,主要解决history模式i,hash模式没有该问题。
}
}
生产模式
修改和优化webpack.prod.js,修改只处理js文件,添加vue-loader,修改devtool,修改文件补充的拓展
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
},
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
plugins: [
...
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
devtool: "source-map",
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"]
}
添加favicon.ico图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>vue-cli</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
下载依赖:
npm i mini-css-extract-plugin css-minimizer-webpack-plugin copy-webpack-plugin -D
npm install image-minimizer-webpack-plugin imagemin --save-dev
//无损
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
开发模式基本配置完毕,webpack.prod.js代码如下:
const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
return [
MiniCssExtractPlugin.loader, "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "../dist"),
filename: "static/js/[name].[contenthash:10].js",
chunkFilename: "static/js/[name].[contenthash:10].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]",
clean: true
},
module: {
rules: [
// 处理css
{
test: /\.css$/,
use: getStyleLoaders(),
},
{
test: /\.less$/,
use: getStyleLoaders('less-loader'),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders('sass-loader'),
},
{
test: /\.styl$/,
use: getStyleLoaders('stylus-loader'),
},
//处理图片
{
test: /\.(jpe?g|png|gif|webp|svg)$/,
type: "asset",
parser: {
dataCondition: {
maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
}
}
},
// 处理其他资源
{
test: /\.(woff2?|ttf)$/,
type: "asset/resource",
},
//处理js
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
}),
new CopyWebpackPlugin({//复制到dist文件下
patterns: [
{
from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
},
}
]
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
mode: "production",
devtool: "source-map",
optimization: {
splitChunks: {
chunks: "all" //代码分割
},
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
},
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
new ImageMinimizerWebpackPlugin({
minimizer: {
implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
],
},
],
],
},
},
}),
]
},
//webpack解析块加载选项
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"]
}
}
合并开发和生产模式
复制webpack.prod.js为webpack.config.js
const isProduction = process.env.NODE_ENV == "production"
output: {
path: isProduction?path.resolve(__dirname, "../dist"):undefined,
filename:isProduction? "static/js/[name].[contenthash:10].js":"static/js/[name].js",
chunkFilename: isProduction? "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].[contenthash:10].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]",
clean: true
},
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
isProduction && new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyWebpackPlugin({//复制到dist文件下
patterns: [
{
from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
},
}
]
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
].filter(Boolean),
devtool: isProduction? "source-map":"cheap-module-source-map",
optimization: {
splitChunks: {
chunks: "all" //代码分割
},
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
},
minimize:isProduction,
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
new ImageMinimizerWebpackPlugin({
minimizer: {
implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
],
},
],
],
},
},
}),
]
},
devServer: {
host: "localhost",
port: 3000,
open: true,
hot: true,
historyApiFallback: true//解决前端路由刷新404的问题
}
修改package.json指令:
"scripts": {
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js"
},
然后输入指令尝试打包和编译,合并就是这些,webpack.config.js完整代码如下:
const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
const isProduction = process.env.NODE_ENV == "production"
console.log(isProduction);
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
return [
isProduction?MiniCssExtractPlugin.loader:"vue-style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: isProduction?path.resolve(__dirname, "../dist"):undefined,
filename:isProduction? "static/js/[name].[contenthash:10].js":"static/js/[name].js",
chunkFilename: isProduction? "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].[contenthash:10].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]",
clean: true
},
module: {
rules: [
// 处理css
{
test: /\.css$/,
use: getStyleLoaders(),
},
{
test: /\.less$/,
use: getStyleLoaders('less-loader'),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders('sass-loader'),
},
{
test: /\.styl$/,
use: getStyleLoaders('stylus-loader'),
},
//处理图片
{
test: /\.(jpe?g|png|gif|webp|svg)$/,
type: "asset",
parser: {
dataCondition: {
maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
}
}
},
// 处理其他资源
{
test: /\.(woff2?|ttf)$/,
type: "asset/resource",
},
//处理js
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
isProduction && new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyWebpackPlugin({//复制到dist文件下
patterns: [
{
from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
},
}
]
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
].filter(Boolean),
mode:isProduction? "production":"development",
devtool: isProduction? "source-map":"cheap-module-source-map",
optimization: {
splitChunks: {
chunks: "all" //代码分割
},
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
},
minimize:isProduction,
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
new ImageMinimizerWebpackPlugin({
minimizer: {
implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
],
},
],
],
},
},
}),
]
},
//webpack解析块加载选项
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"]
},
devServer: {
host: "localhost",
port: 3000,
open: true,
hot: true,
historyApiFallback: true//解决前端路由刷新404的问题
}
}
拓展:配置element-plus
npm i element-plus
我们配置按需引入:
npm install -D unplugin-vue-components unplugin-auto-import
修改webpack.config.js文件
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
isProduction && new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyWebpackPlugin({//复制到dist文件下
patterns: [
{
from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
},
}
]
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
].filter(Boolean),
引入即可:
<template>
<h1 class="title">hello app!</h1>
<ElButton>按钮</ELButton>
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
<!-- <Home />
<About /> -->
<router-view></router-view>
</template>
<script>
import Home from "./views/Home/Home"
import About from "./views/About/About"
import {ElButton} from 'element-plus'
export default{
name:"App",
components:{Home,About,ElButton}
}
</script>
<style lang="less">
.title{
color:red
}
</style>
修改主题:
创建index.scss文件在src下:
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': green,
),
),
);
配置webpack.config.js
let getStyleLoaders = function (pre) {
return [
isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre &&{
loader:pre,
options:pre=="sass-loader"?{
additionalData: `@use "@/styles/elementPlus/index.scss" as *;`,
}:{}
}
].filter(Boolean)
}
配置别名:
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"],
alias:{
"@":path.resolve(__dirname,"../src")
}
},
Components({
resolvers: [ElementPlusResolver({
//自定义主题配置引入sass
importStyle: "sass"
})],
}),
配置后即可查看页面,配置成功。Button 按钮 | Element Plus
优化一下cacheGroup的配置:我们希望打包可以分开打包:
optimization: {
splitChunks: {
chunks: "all", //代码分割
cacheGroups:{
vue:{ // 一起打包成一个js文件
test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
name:'chunk-vue',
priority:40, //打包优先级权重
},
elementPlus:{ //antd单独打包
test:/[\\/]node_modules[\\/]element-plus[\\/]/,
name:'chunk-elementPlus',
priority:30,
},
lib:{ //node_modules单独打包
test:/[\\/]node_modules[\\/]/,
name:'chunk-lib',
priority:20,
},
}
},
关闭性能分析:
performance:false,
webpack内部做一下缓存:
{
test: /\.vue$/,
loader: 'vue-loader',
options:{
//开启缓存提高第二次打包速度
cacheDirectory:path.resolve(__dirname,"../node_modules/.cache/vue-loader")
}
}
开启webpack内部缓存,有助于下次的打包编译节省时间:
cache: { //可开启webpack5内置缓存
type: 'filesystem',
allowCollectingMemory: true
}
我们就完成了配置:
const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const { DefinePlugin } = require("webpack")
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
const isProduction = process.env.NODE_ENV == "production"
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
return [
isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader", "css-loader", {
//处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
},
pre &&{
loader:pre,
options:pre=="sass-loader"?{
additionalData: `@use "@/styles/elementPlus/index.scss" as *;`,
}:{}
}
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: isProduction ? path.resolve(__dirname, "../dist") : undefined,
filename: isProduction ? "static/js/[name].[contenthash:10].js" : "static/js/[name].js",
chunkFilename: isProduction ? "static/js/[name].[contenthash:10].chunk.js" : "static/js/[name].[contenthash:10].chunk.js",
assetModuleFilename: "static/media/[hash:10][ext][query]",
clean: true
},
module: {
rules: [
// 处理css
{
test: /\.css$/,
use: getStyleLoaders(),
},
{
test: /\.less$/,
use: getStyleLoaders('less-loader'),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders('sass-loader'),
},
{
test: /\.styl$/,
use: getStyleLoaders('stylus-loader'),
},
//处理图片
{
test: /\.(jpe?g|png|gif|webp|svg)$/,
type: "asset",
parser: {
dataCondition: {
maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
}
}
},
// 处理其他资源
{
test: /\.(woff2?|ttf)$/,
type: "asset/resource",
},
//处理js
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
loader: "babel-loader",
options: {
cacheDirectory: true,
cacheCompression: false,
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
}
]
},
plugins: [
new EslintWebpackPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache')
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
isProduction && new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyWebpackPlugin({//复制到dist文件下
patterns: [
{
from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
},
}
]
}),
new VueLoaderPlugin(),
//cross-env定义的环境变量给webpack使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
new DefinePlugin({
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}),
//按需加载element-plus
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver({
//自定义主题配置引入sass
importStyle: "sass"
})],
}),
].filter(Boolean),
mode: isProduction ? "production" : "development",
devtool: isProduction ? "source-map" : "cheap-module-source-map",
optimization: {
splitChunks: {
chunks: "all", //代码分割
cacheGroups:{
vue:{ // 一起打包成一个js文件
test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
name:'chunk-vue',
priority:40, //打包优先级权重
},
elementPlus:{ //antd单独打包
test:/[\\/]node_modules[\\/]element-plus[\\/]/,
name:'chunk-elementPlus',
priority:30,
},
lib:{ //node_modules单独打包
test:/[\\/]node_modules[\\/]/,
name:'chunk-lib',
priority:20,
},
}
},
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
},
minimize: isProduction,
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
new ImageMinimizerWebpackPlugin({
minimizer: {
implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
],
},
],
],
},
},
}),
]
},
//webpack解析块加载选项
resolve: {
//自动补全文件拓展名
extensions: [".vue", ".js", ".json"],
alias:{
"@":path.resolve(__dirname,"../src")
}
},
devServer: {
host: "localhost",
port: 3000,
open: true,
hot: true,
historyApiFallback: true//解决前端路由刷新404的问题
},
performance:false,
cache: { //可开启webpack5内置缓存
type: 'filesystem',
allowCollectingMemory: true
}
}