您的位置:首页 > Web前端 > Vue.js

【vue-cli】vue_shop电商后台管理项目优化,项目上线

2020-04-25 07:46 561 查看

完成项目的开发阶段,进入到发布阶段。

1. 添加进度条,修改代码,执行build

1. 添加进度条
给项目添加进度条效果,在项目控制台中,打开依赖,安装nprogress,打开main.js文件中,在axios请求拦截器和响应拦截器中添加如下代码(包括了携带token代码)

// 导入NProgress包对应的css 和js
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

// axios请求拦截器 请求头中携带token 展示进度条 NProgress.start()
axios.interceptors.request.use(config => {
NProgress.start()
config.headers.Authorization = window.sessionStorage.getItem('token') //Authorization为接口文件要求
return config
});
// axios响应拦截器
axios.interceptors.response.use(config => {
NProgress.done()
return config
});

2. 根据报错修改代码
根据报告中的警告信息查询到具体问题代码
常见问题:

  1. 作用域定义scope未使用或其他变量未使用
  2. eslint与代码格式化冲突,在.prettierrc格式化配置文件内设置一行最多允许字符
{
"semi": false, // 格式化不加分号
"singleQuote": true,// 格式化以单引号为主
"printWidth": 200 // 格式化每行最多允许字符长度
}
  1. 变量最好为驼峰命名
  2. 文件过大,需要优化,可查阅下面的步骤

3. 执行build 移除所有console信息
安装插件,在项目控制台中,安装开发依赖babel-plugin-transform-remove-console,在babel.config.js编写如下代码(包含了懒加载插件代码)

// 这是项目发布阶段需要用到的 babel 插件,防止开发阶段的console也被移除
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')
}

module.exports = {
presets: ['@vue/app'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
// 发布产品时候的插件数组 移除console 懒加载
...prodPlugins,
// 配置路由懒加载
'@babel/plugin-syntax-dynamic-import'
]
}

2. 项目优化

1. 生成打包报告,使用UI面板查看报告
在UI面板的打包报告中,可以看到打包的详细情况

2. 通过vue.config.js修改webpack的默认配置

新建vue.config.js文件来修改webpack的默认配置,主要是当处于开发模式和发布模式不同情况下做不一样的事情,不用模式配置不同的打包入口文件(即以下3-5步)

3. 为开发模式与发布模式指定不同的打包入口

Vue项目的开发模式和发布模式默认公用一个打包的入口文件,即main.js,但是不同开发模式下,入口文件内容可能会略不同,为了将开发过程和打包过程分离,需要配置不同的入口文件,
先将main.js复制一份并将两份分别命名为main-dev.js和main-prod.js,作为不同模式下的入口文件

4. configureWebpack 和 chainWebpack

配置不同的入口文件需要用这两种节点来定义webpack的打包配置

5. 通过chainWebpack自定义打包入口

这里使用其中一种方法来配置入口文件
具体完整代码(包含发布模式下加载CDN资源和定制首页内容)

module.exports = {
css: {
extract: false
},
chainWebpack: config => {
// 发布模式 设置入口文件目录
config.when(process.env.NODE_ENV === 'production', config => {
config
.entry('app')
.clear()
.add('./src/main-prod.js')
// 加载CDN资源
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})// 定制首页内容
config.plugin('html').tap(args => {
args[0].isProd = true
return args
})
})

// 开发模式 设置入口文件目录
config.when(process.env.NODE_ENV === 'development', config => {
config
.entry('app')
.clear()
.add('./src/main-dev.js')

// 定制首页内容
config.plugin('html').tap(args => {
args[0].isProd = false
return args
})
})
}
}

6. 通过externals加载外部CDN资源

默认情况下,通过import语法导入的第三方依赖包,最终会被合并到同一个文件中,从而导致打包成功后,文件体积过大问题。
因此为了解决这种问题,可以通过webpack的externals节点,来配置加载外部的CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包。

  1. 如第五步代码中,将
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})

添加到vue.config.js配置文件中

  1. 将main-prod.js中导入的插件的css样式表删除,并在index.html中导入

index.html文件的完整代码(包含Element UI 和定制首页内容)

<!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="icon" href="<%= BASE_URL %>favicon.ico" />
<title>
<%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>

<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- nprogress 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
<!-- 富文本编辑器 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
<!-- element-ui 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" />

<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
<script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
<!-- 富文本编辑器的 js 文件 -->
<script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>

<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>

<% } %>
</head>

<body>
<noscript>
<strong>We're sorry but vue_shop 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>

7. 通过externals优化Element UI的打包

  1. 在main-prod.js中,注释掉element-ui按需加载的代码

  2. 在index.html的头部区域中,通过CDN加载element-ui的js和css样式,完整代码见第六步代码

8. 首页内容定制
不同的打包环境下,首页内容可能会有所不同,可以通过插件的方式来定制首页内容,例如不同的首页标题title
在vue.config.js文件中对插件进行配置,见第五条中的内容定制代码,

然后在index.html首页中渲染,见第六步中定制内容代码

9. 路由懒加载

  1. 在开发依赖中安装
  2. 在babel.config.js中配置插件
// 这是项目发布阶段需要用到的 babel 插件
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')
}

module.exports = {
presets: ['@vue/app'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
// 发布产品时候的插件数组
// 移除发布阶段的console
...prodPlugins,
// 配置路由懒加载
'@babel/plugin-syntax-dynamic-import'
]
}
  1. 对router文件下的index.js的路由全部进行按需改造
import Vue from 'vue'
import VueRouter from 'vue-router'
// import Login from './components/Login.vue'
const Login = () =>
import ( /* webpackChunkName: "login_home_welcome" */ '../components/Login.vue')

// import Home from './components/Home.vue'
const Home = () =>
import ( /* webpackChunkName: "login_home_welcome" */ '../components/Home.vue')

// import Welcome from './components/Welcome.vue'
const Welcome = () =>
import ( /* webpackChunkName: "login_home_welcome" */ '../components/Welcome.vue')

// import Users from './components/user/Users.vue'
const Users = () =>
import ( /* webpackChunkName: "Users_Rights_Roles" */ '../components/user/Users.vue')

// import Rights from './components/power/Rights.vue'
const Rights = () =>
import ( /* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Rights.vue')

// import Roles from './components/power/Roles.vue'
const Roles = () =>
import ( /* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Roles.vue')

// import Cate from './components/goods/Cate.vue'
const Cate = () =>
import ( /* webpackChunkName: "Cate_Params" */ '../components/goods/Cate.vue')

// import Params from './components/goods/Params.vue'
const Params = () =>
import ( /* webpackChunkName: "Cate_Params" */ '../components/goods/Params.vue')

// import GoodsList from './components/goods/List.vue'
const GoodsList = () =>
import ( /* webpackChunkName: "GoodsList_Add" */ '../components/goods/List.vue')

// import Add from './components/goods/Add.vue'
const Add = () =>
import ( /* webpackChunkName: "GoodsList_Add" */ '../components/goods/Add.vue')

// import Order from './components/order/Order.vue'
const Order = () =>
import ( /* webpackChunkName: "Order_Report" */ '../components/order/Order.vue')

// import Report from './components/report/Report.vue'
const Report = () =>
import ( /* webpackChunkName: "Order_Report" */ '../components/report/Report.vue')

Vue.use(VueRouter)

const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login },
{
path: '/home',
component: Home,
//  进入home时 重定向welcome
redirect: '/welcome',
children: [
{ path: '/welcome', component: Welcome },
{ path: '/users', component: Users },
{ path: '/rights', component: Rights },
{ path: '/roles', component: Roles },
{ path: '/categories', component: Cate },
{ path: '/params', component: Params },
{ path: '/goods', component: GoodsList },
{ path: '/goods/add', component: Add },
{ path: '/orders', component: Order },
{ path: '/reports', component: Report }
]
}
]

const router = new VueRouter({
routes
})

// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数,表示放行
//    next()放行  next('/login')强制跳转
if (to.path === '/login') return next()
// 获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login');
next()
})

export default router

懒加载总结:
开发依赖中下载懒加载插件,在babel.config.js中配置懒加载插件,将路由文件中的按需修改路由,完成!

3. 项目上线

1. 通过node创建web服务器

创建文件夹vue_shop_server,
初始化包管理配置文件 npm init -y,
安装express npm i express -S,
将dist文件复制到vue_shop_server文件夹中,
新建文件app.js入口文件内容如下(包含gzip压缩,和配置https服务):

const express = require('express')
const compression = require('compression')
const https = require('https')
const fs = require('fs')
const app = express()

const options = {
cert: fs.readFileSync('./full_chain.pem'),
key: fs.readFileSync('./private.key')
}

// 一定要把这一行代码,写到 静态资源托管之前 gzip压缩
app.use(compression())
app.use(express.static('./dist'))

app.listen(80, () => {
console.log('server running at http://127.0.0.1')
})

// https.createServer(options, app).listen(443)

配置完成,在终端使用node ./app.js运行,在浏览器输入127.0.0.1可以访问

2. 开启gzip配置
压缩文件

3. 配置HTTPS服务


建议使用多域名通配符

4. 使用pm2管理应用

解决关闭终端窗口就会退出服务器的问题。
在cmd中安装
然后可以再各终端中使用

  • 点赞
  • 收藏
  • 分享
  • 文章举报
Whoopsina 发布了12 篇原创文章 · 获赞 0 · 访问量 335 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: