Webpack5从零搭建Vue2项目
从零搭建Vue2项目
Owner: fredbrock
目的
复习下Webpack基础知识。
初始Webpack项目
mkdir vue2-webpack-template
cd vue2-webpack-template
pnpm init
pnpm add -D webpack webpack-cli webpack-dev-server
创建项目目录结构
├── .gitignore
├── build
│ ├── webpack.dev.config.js
│ └── webpack.prod.config.js
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── favicon.ico
│ ├── img
│ ├── index.html
│ └── robots.txt
├── README.md
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
├── HomeView.vue
└── main.js
webpack.dev.config.js:本地开发服务 webpack.prod.config.js:打包生产环境 public: 静态资源文件夹 src:Vue源码目录
创建源代码
安装 Vue 项目依赖
pnpm add -S vue@2
创建入口文件: src/main.js
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
}).$mount("#app");
创建 Vue 根实例: src/App.vue
<template>
<div id="app">Hello Vue~</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
创建 index.html 模板 public/index.html
<!DOCTYPE html>
<html lang="">
<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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
配置 Vue SFC 支持
安装 Vue SFC 依赖
pnpm add -D html-webpack-plugin
pnpm add -D vue-loader@15 vue-template-compiler css-loader vue-style-loader
pnpm add -D less less-loader
创建webpack基本配置:build/webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
mode: "development",
entry: path.resolve(__dirname, "../src/main.js"),
output: {
filename: "[name].[hash].js",
path: path.resolve(__dirname, "../dist"),
},
module: {
rules: [
// ... other rules
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"],
},
{
test: /\.less$/i,
use: [
// compiles Less to CSS
"vue-style-loader",
"css-loader",
"less-loader",
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: "Vue.js",
template: path.resolve(__dirname, "../public/index.html"),
filename: "index.html",
inject: true,
}),
new VueLoaderPlugin(),
],
};
将css打包到单独的文件
{
test: /\.less$/i,
use: [
MiniCssExtractPlugin.loader,
// "vue-style-loader",
"css-loader",
"less-loader",
],
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
"less-loader",
],
},
配置 Babel
安装 Babel 依赖
pnpm add -D @babel/core @babel/preset-env babel-loader
配置 Babel
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env", { targets: "defaults" }]],
},
},
},
配置 clean-webpack-plugin
pnpm add -D clean-webpack-plugin
plugins: [
new CleanWebpackPlugin(),
],
配置打包命令: package.json
"scripts": {
"build": "webpack --config build/webpack.config.js"
},
配置汇总
完整包依赖安装命令
mkdir vue2-webpack-template
cd vue2-webpack-template
pnpm init
pnpm add -D webpack webpack-cli webpack-dev-server
pnpm add -D html-webpack-plugin
pnpm add -S vue@2
pnpm add -D vue-loader@15 vue-template-compiler css-loader vue-style-loader
pnpm add -D less less-loader
pnpm add -D mini-css-extract-plugin
pnpm add -D @babel/core @babel/preset-env babel-loader
pnpm add -D clean-webpack-plugin
完整 webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
const { VueLoaderPlugin } = require("vue-loader");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "development",
entry: path.resolve(__dirname, "../src/main.js"), //入口文件
output: {
filename: "[name].[hash].js",
path: path.resolve(__dirname, "../dist"),
},
devServer: {
static: {
directory: path.join(__dirname, "public"),
},
compress: true,
hot: true,
port: 9000,
},
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env", { targets: "defaults" }]],
},
},
},
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.less$/i,
use: [
MiniCssExtractPlugin.loader,
// "vue-style-loader",
"css-loader",
"less-loader",
],
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
"less-loader",
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
BASE_URL: "./",
}),
new HtmlWebpackPlugin({
title: "Custom template using Handlebars",
template: path.resolve(__dirname, "../public/index.html"),
filename: "index.html",
inject: true,
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: "style.css",
}),
],
};
package.json
{
"name": "vue-webpack-cli",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"serve": "webpack serve --config build/webpack.dev.config.js",
"build": "webpack --config build/webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"vue": "^2.7.16"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"babel-loader": "^9.1.3",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^7.1.2",
"html-webpack-plugin": "^5.6.0",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"mini-css-extract-plugin": "^2.9.0",
"postcss": "^8.4.41",
"postcss-loader": "^8.1.1",
"postcss-preset-env": "^10.0.0",
"style-loader": "^4.0.0",
"vue-loader": "^15.11.1",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
}
}
完整代码
https://github.com/FredBrock/vue2-webpack-template
效果图