现在我们开发Vue项目几乎都是用Vue-CLI去创建项目,因为它提供了几乎我们所有需要的功能,不再需要我们去自己配置像webpack、eslint、sass/less、unit test/e2e test这些功能,大大提升我们的效率。于是我们不会去深究它的技术细节,只知道如何去使用就好了。这对于一个前端肯定是不够的,不说精通,也一定要对其原理有一定了解。所以今天我们不用Vue-CLI,从零去创建一个Vue项目。
创建项目
mkdir vue-webpack
cd vue-webpack
npm init -y
创建入口文件
创建src
文件夹,创建main.js
文件
alert('hello vue')
接着创建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 Webpack</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>
项目目录
src/
main.js
index.html
webpack基本安装配置
npm install webpack webpack-cli -D
接着在根目录创建webpack.config.js
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
}
- entry是webpack读取的入口文件,可以有多个,但一般单页应用只有一个
- output是打包输出配置
- path 打包的目录,这里我配置为dist文件夹
- filename 打包的文件命名
- clean 打包前是否清空文件夹
修改package.json
,将scripts
修改为如下
"scripts": {
"watch": "webpack --watch",
"build": "webpack"
},
- –watch 会监听文件修改,自动打包
测试打包是否成功
npm run build
# 打包成功
asset main.e8760e604a32a49cb09a.js 1.18 KiB [emitted] [immutable] (name: main)
./src/main.js 1 bytes [built] [code generated]
webpack 5.51.2 compiled successfully in 59 ms
打包成功后会生成dist文件夹
dist/
main.e8760e604a32a49cb09a.js
缺少html文件,我们安装一个webpack插件
npm install html-webpack-plugin -D
修改webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
}
- html-webpack-plugin 会自动将打包好的JS注入到index.html中
重新测试打包
npm run build
打包成功后会生成dist文件夹
dist/
index.html
main.e8760e604a32a49cb09a.js
在浏览器中打开index.html,会弹出·‘hello vue’
Vue安装配置
接下来,安装Vue相关的配置
安装Vue和Vue Router
npm install vue vue-router
安装打包.Vue
文件的webpack配置
npm install vue-loader vue-template-compiler -D
这里需要注意vue的版本要和vue-template-compiler的版本一致,否则会出现错误
修改main.js如下
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import Foo from './pages/Foo.vue'
const Bar = () => import(/* webpackChunkName: "group-bar" */ './pages/Bar.vue') // 异步加载文件
Vue.use(VueRouter)
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes
})
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
创建src/App.vue文件
<template>
<div>
<h1>hello vue webpack</h1>
<ul>
<li>
<router-link to="/foo">Go to Foo</router-link>
</li>
<li>
<router-link to="/bar">Go to Bar</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</template>
在src下创建pages文件夹,创建Bar.vue和Foo.vue文件
Bar.vue
<template>
<div>bar</div>
</template>
Foo.vue
<template>
<div>foo</div>
</template>
修改webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
]
},
plugins: [
new webpack.ProgressPlugin(),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' })
]
}
- webpack.ProgressPlugin() 用户在打包时会有个进度条
然后打包
npm run build
可以看到dist目录
dist/
index.html
group-bar.3235a6c307cef33d5703.js
main.406dcc2772a126d0094b.js
在浏览器中打开index.html,测试发现页面正常显示,路由切换没有问题
安装Element UI框架
npm install element-ui
这里选择按需引入
Element UI的组件,不是全量引入,所以要安装下面的一些依赖
npm install @babel/core babel-loader babel-plugin-component css-loader
修改main.js
,引入Button组件和一个Calendar日历组件
import Vue from 'vue'
import VueRouter from 'vue-router'
import { Button, Calendar } from 'element-ui';
import App from './App.vue'
import Foo from './pages/Foo.vue'
const Bar = () => import(/* webpackChunkName: "group-bar" */ './pages/Bar.vue') // 异步加载文件
Vue.use(VueRouter)
// el component
Vue.use(Button)
Vue.use(Calendar)
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes
})
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
在根目录创建.babelrc文件,用于配置Babel的按需引入组件
{
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
修改webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
]
},
plugins: [
new webpack.ProgressPlugin(),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' })
]
}
修改App.vue文件
<template>
<div>
<h1>hello vue webpack</h1>
<ul>
<li>
<router-link to="/foo">Go to Foo</router-link>
</li>
<li>
<router-link to="/bar">Go to Bar</router-link>
</li>
</ul>
<router-view></router-view>
<el-calendar v-model="value"></el-calendar>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</div>
</template>
<script>
export default {
data() {
return {
value: new Date()
}
}
}
</script>
<style scoped>
h1 {
color: blue
}
</style>
打包
npm run build
在浏览器中打开index.html,测试发现路由切换没有问题,element组件正常显示
Webpack其他配置
最后我们还要配一些其他的有用配置
- webpack-dev-server 用于开发时自动刷新,和模块热替换,提升开发效率
- source-map 代码发生报错时,可以直接找到哪个文件的第几行
- optimization的runtimeChunk、splitChunks配置,来配置打包的代码分割,项目依赖、runtime、业务代码分离文件打包。这样如果项目依赖、runtime没有变化的话,每次打包都不会重新生成文件,只有业务代码会生成新的文件。
webpack-dev-server安装
npm install webpack-dev-server -D
最后的webpack.config.js配置
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
devServer: {
static: './dist',
hot: true,
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
]
},
plugins: [
new webpack.ProgressPlugin(),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' })
]
}
修改package.json,增加start命令,用于开发时使用webpack-dev-server的自动刷新功能
"scripts": {
"watch": "webpack --watch",
"start": "webpack serve --open",
"build": "webpack"
},
使用webpack-dev-server开发
npm start
浏览器自动打开,修改代码,浏览器会自动刷新