前面我们讲了对项目进行webpack模块化的改造,在改造过程中,我们也进行了各种webpack相关的性能优化,比如,对css和js文件的分离压缩,启动了开发模式,并抽象了公共模板。到现在这个项目其实已经优化的比较到位了,对平常的项目开发和项目上线都是可以满足的。
接下来,我们将进一步升级我们的项目,将我们的项目升级到vue的SPA项目,即vue的单页应用。
我相信很多同学可以初始化一个vue项目,但是很少有同学能拿当前的项目来改造成vue项目,这两者是有很大差别的。因为我们需要对vue的工程化进行一系列的改造。
目前,当我们开发的时候需要同时对html和js进行开发的,我们的逻辑写在js文件当中,但是DOM还是写在html中的。这种开发模式是比较陈旧的开发方式,开发效率是比较低的,我们看业务逻辑的是不是很清晰。而且,我们对业务做修改的时候,还需要对dom进行操作。所以现在的项目都会使用vue进行开发。
-
创建build目录,把webpack.config.js移到build目录中,开始做多配置文件改造
-
修改webpack.config.js中所有路径为绝对路径,完整配置如下:
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CssMiniPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
mode: 'development',
entry: {
index: path.resolve(__dirname, '../src/index.js'),
login: path.resolve(__dirname, '../src/login.js')
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'js/[name].js',
// 打包之前的删除dist目录
clean: true
},
devServer: {
static: {
directory: path.join(__dirname, '../dist')
},
compress: true,
port: 9000,
hot: true
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: 'images/[name].[hash:6][ext]'
}
},
{
test: /\.ejs$/,
use: {
loader: 'ejs-loader',
options: {
esModule: false
}
}
}
]
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false
}),
new CssMiniPlugin({})
],
splitChunks: {
chunks: 'all',
minSize: 30 * 1024,
name: 'common',
cacheGroups: {
jquery: {
name: 'jquery',
test: /jquery\.js/,
chunks: 'all'
},
'lodash-es': {
name: 'lodash-es',
test: /lodash-es/,
chunks: 'all'
}
}
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, '../src/img'),
to: path.resolve(__dirname, '../dist/img')
}
]
}),
new MiniCssExtractPlugin({
filename: 'css/[name].css',
chunkFilename: 'css/[name].chunk.css'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../src/index.html'),
chunks: ['index']
}),
new HtmlWebpackPlugin({
filename: 'login.html',
template: path.resolve(__dirname, '../src/login.html'),
chunks: ['login']
})
]
}
- 修改package.json中的 script 命令
"scripts": {
"start": "webpack-dev-server",
"build": "webpack --config ./build/webpack.config.js"
}
接入vue
- 首先安装vue2.0
npm install -S vue@2.6.14
- 安装vue的编译库和对应loader
npm install @vue/compiler-sfc vue-template-compiler vue-loader@15 -D
- vue-loader的版本必须是15左右,因为需要和vue版本相对应;
- vue-template-compiler用来编译.vue文件;
- @vue/compiler-sfc对一些vue新特性进行编译
- 创建vue相关文件
- 创建main.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
- 创建App.vue
<template>
<div>
{{ message }}
</div>
</template>
<script>
export default {
data() {
return {
message: 'hello world'
}
}
}
</script>
- 创建模板文件 public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>项目改造</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
- 创建build/webpack.vue.config.js,并写入下面配置
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CssMiniPlugin = require('css-minimizer-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const config = {
mode: 'development',
entry: {
index: path.resolve(__dirname, '../src/main.js')
},
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, '../dist'),
clean: true
},
devServer: {
static: {
directory: path.join(__dirname, '../dist')
},
compress: true,
port: 9000,
hot: true
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: 'images/[name].[hash:6][ext]'
}
},
{
test: /\.ejs$/,
use: {
loader: 'ejs-loader',
options: {
esModule: false
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false
}),
new CssMiniPlugin({})
],
splitChunks: {
chunks: 'all',
minSize: 30 * 1024,
name: 'common',
cacheGroups: {
jquery: {
name: 'jquery',
test: /jquery\.js/,
chunks: 'all'
},
'lodash-es': {
name: 'lodash-es',
test: /lodash-es/,
chunks: 'all'
}
}
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, '../src/img'),
to: path.resolve(__dirname, '../dist/img')
}
]
}),
new MiniCssExtractPlugin({
filename: 'css/[name].css',
chunkFilename: 'css/[name].chunk.css'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../public/index.html'),
chunks: ['index']
}),
new VueLoaderPlugin()
]
}
module.exports = config
- 修改package.json的script命令
"scripts": {
"start": "webpack-dev-server",
"start:vue": "webpack-dev-server --config ./build/webpack.vue.config.js",
"build": "webpack --config ./build/webpack.config.js",
"build:vue": "webpack --config ./build/webpack.vue.config.js"
}
- 执行
npm run build:vue,打包成功。