主要环境
- node V14.18.0
- npm v8.1.3
- webpack v5.75.0
- webpack-cli v5.0.1
- webpack-merge v5.8.0
- vue2(vue3)
本项目主要实现
- vue 类似的目录
- webpack 拆分配置与merge
构建项目基本目录
demo
├─build
├─public
└─src
安装依赖
- webpack
npm install -D webpack webpack-cli
- webpack服务插件
npm install -D webpack-dev-server
- webpack配置合并插件
npm install -D webpack-merge
- vue 插件
npm install -D vue-loader vue-template-compiler
注意:vue2中vue-loader与vue-template-compiler一致避免版本问题、 vue3不需要vue-template-compiler插件 - css 插件
npm install -D style-loader css-loader
- 图片插件
npm install -D file-loader url-loader
- babel插件
npm install -D@babel/core @babel/cli @babel/preset-env babel-loader, npm install @babel/polyfill
安装vue
npm install vue@版本 vue-router vuex
搭建项目
来个最基础的配置与启动
新建 src/main.js
,并写入
var a =100; console.log(a);
新建 pubilc/index.html
,并写入
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webpack搭建vue</title>
</head>
<body>
<!-- 如果浏览器禁止加载js脚本 -->
<noscript>
<strong>
We're sorry but this site doesn't work properly without JavaScript
enabled. Please enable it to continue.
</strong>
</noscript>
<div id="app"></div>
<!-- build后的文件会在这之后自动引入 -->
</body>
</html>
新建 build/paths.js
,(路径配置文件)
const path = require("path");
const srcPath = path.join(__dirname, "../", "src");
const distPath = path.join(__dirname, "../", "dist");
const publicPath = path.join(__dirname, "../", "public");
module.exports = {srcPath,distPath,publicPath};
新建 build/webpack.common.js
,(为公共配置文件)
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { srcPath, publicPath } = require("./paths");
module.exports = {
entry: path.join(srcPath, "main"), //入口文件
plugins: [
new HtmlWebpackPlugin({
template: path.join(publicPath, "index.html"),//模板html
filename: "index.html",// 生成的文件名
//favicon: 'public/favicon.ico', // 图标
}),
],
};
新建 build/webpack.prod.js
,(打包生产文件)
const webpack = require('webpack')
const webpackCommonConf = require('./webpack.common.js')
const { merge } = require('webpack-merge')
const { distPath } = require('./paths')
module.exports = merge(webpackCommonConf, {
mode: 'production',
output: {
filename: '[name].[contenthash:8].js', // 打包代码时,webpac4 用contentHash,webpack5用contenthash;
path: distPath,
// publicPath: 'http://cdn.abc.com' // 修改所有静态文件 url 的前缀(如 cdn 域名)
},
plugins: [
new webpack.DefinePlugin({
ENV: JSON.stringify('production')// window.ENV = 'production'
})
]
})
新建 build/webpack.dev.js
,(服务启动开发文件)
const commonWebpackConfig = require("./webpack.common");
const webpack = require("webpack");
const { merge } = require("webpack-merge");
module.exports = merge(commonWebpackConfig, {
mode: "development",
plugins: [
new webpack.DefinePlugin({
ENV: JSON.stringify("development"), // window.ENV = 'development'
}),
],
devServer: {
port: 8090,//服务器监听的端口
host:'0.0.0.0', //服务器开起的ip地址
open: true, // 是否打开浏览器提供访问
//hot: true, // 需要配合webpack.HotModuleReplacementPlugin使用 热更新
//compress: true, // 是否为每个静态文件启动gzip压缩 也可以使用命令:npx webpack serve --compress
},
// 设置代理 —— 如果有需要的话!
/**proxy: {
// 将本地 /api/xxx 代理到 localhost:8080/api/xxx
'/api': 'http://localhost:8080',
// 将本地 /api2/xxx 代理到 localhost:8080/xxx
'/api2': {
target: 'http://localhost:8080',
pathRewrite: {
'/api2': ''
}
}
}**/
});
在package.json
中的scripts
中添加一个脚本:
"build": "webpack --config build/webpack.prod.js",
"dev": "webpack serve --config build/webpack.dev.js" //后面用
在命令行中执行npm run build,此时项目目录中出现了dist/main.XXXXX.js,证明执行成功!
配置 vue
vue2.0
打包.vue
文件 需要 vue-loader
和 vue-template-compiler
vue3.0
只需要 vue-loader
版本还是要新的
为了能供解析css 还需要 style-loader
和 css-loader
在build/webpack.common
文件中增加配置
新版本 vue3.0 版本17
const {VueLoaderPlugin} = require("vue-loader");
旧版本 vue2.0 版本15
const VueLoaderPlugin = require("vue-loader/lib/plugin");
module: {
//省略了...
rules: [
{
// *.vue
test: /\.vue$/,
use: 'vue-loader', //webpac4 用laoder:[],webpack5用use:[];
},
{
// `*.vue` 文件中的 `<style>` 块以及普通的`*.css`
test: /\.css$/,
use: ['style-loader', 'css-loader'], //webpac4 用laoder:[],webpack5用use:[];
},
],
},
plugins: [
...
new VueLoaderPlugin(),
],
配置完后新建src/App.vue
<template>
<div>
<p class="example">app{{ msg }}</p>
<button @click="tap">点击</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "我是一条信息",
};
},
methods: {
tap() {
console.log('23234');
},
},
};
</script>
<style>
.example {
color: red;
}
</style>
修改src/main.js
:
//vue2.0:
import Vue from 'vue';
import App from './App.vue';
new Vue({
el: '#app',
render: (h) => h(App),
});
//vue3.0
import {createApp} from 'vue/dist/vue.esm-bundler'
import App from './App.vue';
const app= createApp(app)
app.mount('#app')
然后运行npm run dev
,即可看到页面上显示的我是一条信息
配置图片资源
相同点:file-loader与url-loader都是在webpack中引入图片的解决方案。
不同点:
1、file-loader:返回的是图片的public URL。
2、url-loader:与file-loader不同,url-loader可以在图片大小小于设定的limit的时候返回的是一个bDataURL(base64码),大于limit时会调用file-loader对图片进行处理。
所以我们线上开发环境可以用file-loader,生产环境用url-loader
修改build/webpack.dev.js
//...
module: {
//...
rules: [
// 直接引入图片 url
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'file-loader' //webpac4 用laoder:[],webpack5用use:[];
}
]
},
修改build/webpack.prod.js
//...
module: {
//...
rules: [
// 图片 - 考虑 base64 编码的情况
{
test: /\.(png|jpg|jpeg|gif)$/,
use: { //webpac4 用laoder:[],webpack5用use:[];
loader: 'url-loader',
options: {
// 小于 5kb 的图片用 base64 格式产出
// 否则,依然延用 file-loader 的形式,产出 url 格式
limit: 5 * 1024,
// 打包到 img 目录下
outputPath: '/img/',
// 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
// publicPath: 'http://cdn.abc.com'
}
}
},
]
},
配置 babel
babel 可以将 js 的高版本(es6)语法转换为低版本,使得项目兼容低版本浏览器
修改build/webpack.common.js
const { srcPath} = require('./paths')
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'], //webpac4 用laoder:[],webpack5用use:[];
include: srcPath, //转义文件夹 src中的文件
exclude: /node_modules/ //第三方插件已经处理过 所以忽略这个文件夹
},
]
},
配置完后在项目根目录下创建一个 babel 的配置文件.babelrc
,写入如下内容:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
项目其他的配置
设置文件夹别名
修改build/webpack.common.js
// 解析路径
module.exports={
//..
resolve: {
// 设置src别名
alias: {
'@': srcPath,
'view':path.join(srcPath,'view')
},
//后缀名 可以根据需要自由增减
extensions: ['.js', '.vue'],
},
}
这样我们就可以以如下方式导入 vue 和 js 文件:
import App from '@/App';
import HelloWord from "view/helloWord.vue";
less,sass配置
以less为例
npm install -D less-loader
修改build/webpack.common.js
// ...
module:{
//..
rules: [
{
test:/\.less/,
use:['style-loader','css-loader','less-loader']
},
]
}
wepack一些额外配置
打包清空旧文件夹
npm install -D clean-webpack-plugin
修改build/webpack.prod.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// ...
plugins: [
//...
new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
//...
]