实现步骤:
// 导入 nprogress 插件 加载进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 请求拦截器
axios.interceptors.request.use(config => {
// console.log(config)
// 使用 NProgress.start() 显示进度条
NProgress.start()
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
// 响应拦截器 使用 NProgress.done() 隐藏进度条
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
{
"semi":false,
"singleQuote":true,
"printWidth":200
}
//项目发布阶段需要用到的babel插件
const productPlugins = []
//通过 process.env.NODE_ENV 判断当前的编译模式,
// 如果是 发布 就需要运行该插件,删除所有的 console
if(process.env.NODE_ENV === 'production'){
//发布阶段
productPlugins.push("transform-remove-console")
}
// 跟 这个插件没关系
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
// 通过展开运算符,把这个数组里的数据放在 plugins里面
...prodPlugins,
// 声明路由懒加载
"@babel/plugin-syntax-dynamic-import"
]
}
vue-cli-service build --report
module.exports = {
devServer: {
port: 8888,
open: true
},
lintOnSave: false,
devServer: {
overlay: {
warning: false,
errors: false
}
},
// 修改打包入口文件, 根据 开发阶段 和 发布阶段的不同 添加不同的打包入口文件
// config.entry('app') 得到默认的打包入口文件,然后清空, 然后添加
chainWebpack: config => {
// 产品发布阶段
config.when(process.env.NODE_ENV === 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
// 只有发布模式才需要使用 externals (声明在externals 中的第三方依赖包,都不会被打包) 配置外部的 CDN 资源
// 第一步
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})
})
// 产品开发阶段
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
},
//
}
//使用externals设置排除项
config.set('externals',{
vue:'Vue',
'vue-router':'VueRouter',
axios:'axios',
lodash:'_',
echarts:'echarts',
nprogress:'NProgress',
'vue-quill-editor':'VueQuillEditor'
})
})
把 element-ui、富文本编辑器、nprogress 的css样式 和 js 注释掉
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// import './plugins/element.js'
//导入字体图标
import './assets/fonts/iconfont.css'
//导入全局样式
import './assets/css/global.css'
//导入第三方组件vue-table-with-tree-grid
import TreeTable from 'vue-table-with-tree-grid'
//导入进度条插件
import NProgress from 'nprogress'
//导入进度条样式
// import 'nprogress/nprogress.css'
// //导入axios
import axios from 'axios'
// //导入vue-quill-editor(富文本编辑器)
import VueQuillEditor from 'vue-quill-editor'
// //导入vue-quill-editor的样式
// import 'quill/dist/quill.core.css'
// import 'quill/dist/quill.snow.css'
// import 'quill/dist/quill.bubble.css'
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
//请求在到达服务器之前,先会调用use中的这个回调函数来添加请求头信息
axios.interceptors.request.use(config => {
//当进入request拦截器,表示发送了请求,我们就开启进度条
NProgress.start()
//为请求头对象,添加token验证的Authorization字段
config.headers.Authorization = window.sessionStorage.getItem("token")
//必须返回config
return config
})
//在response拦截器中,隐藏进度条
axios.interceptors.response.use(config =>{
//当进入response拦截器,表示请求已经结束,我们就结束进度条
NProgress.done()
return config
})
Vue.prototype.$http = axios
Vue.config.productionTip = false
//全局注册组件
Vue.component('tree-table', TreeTable)
//全局注册富文本组件
Vue.use(VueQuillEditor)
<!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>电商后台管理系统</title>
<!-- 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/[email protected]/dist/vue-quill-editor.js"></script>
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
</head>
开发环境的首页和发布环境的首页展示内容的形式有所不同
如开发环境中使用的是import加载第三方包,而发布环境则是使用CDN,那么首页也需根据环境不同来进行不同的实现
module.exports = {
chainWebpack:config=>{
config.when(process.env.NODE_ENV === 'production',config=>{
......
//使用插件 在这里
config.plugin('html').tap(args=>{
//添加参数isProd
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=>{
//添加参数isProd
args[0].isProd = false
return args
})
})
}
}
1.<!-- htmlWebpackPlugin 是参数的具体名称 <% = %> 是输出的意思 -->
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>
2. 用 <% { %> <% }%> 把所以的 js文件和css文件包起来, 这里没有 = 符号
<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- nprogress 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
........
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
<% } %>
当路由被访问时才加载对应的路由文件,就是路由懒加载。
路由懒加载实现步骤:
2.在babel.config.js中声明该插件,打开babel.config.js
module.exports = {
"presets": [
"@vue/app"
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
],
...productPlugins,
//配置路由懒加载插件 在这里声明
"@babel/plugin-syntax-dynamic-import"
]
}
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 User from '../components/user/user.vue'
const User = () =>
import ( /* webpackChunkName: "user_rights_roles" */ '../components/user/user.vue')
// import Rights from '../components/power/Rights.vue'
const Rights = () =>
import ( /* webpackChunkName: "user_rights_roles" */ '../components/power/Rights.vue')
// import Roles from '../components/power/Roles.vue'
const Roles = () =>
import ( /* webpackChunkName: "user_rights_roles" */ '../components/power/Roles.vue')
// import Cate from '../components/goods/Cate.vue'
const Cate = () =>
import ( /* webpackChunkName: "cate_roles" */ '../components/goods/Cate.vue')
// import Params from '../components/goods/Params.vue'
const Params = () =>
import ( /* webpackChunkName: "cate_roles" */ '../components/goods/Params.vue')
// import GoodsList from '../components/goods/GoodsList.vue'
const GoodsList = () =>
import ( /* webpackChunkName: "goodslist_goodsadd" */ '../components/goods/GoodsList.vue')
// import GoodsAdd from '../components/goods/GoodsAdd.vue'
const GoodsAdd = () =>
import ( /* webpackChunkName: "goodslist_goodsadd" */ '../components/goods/GoodsAdd.vue')
// import Orders from '../components/orders/Orders.vue'
const Orders = () =>
import ( /* webpackChunkName: "orders_reports" */ '../components/orders/Orders.vue')
// import Reports from '../components/reports/Reports.vue'
const Reports = () =>
import ( /* webpackChunkName: "orders_reports" */ '../components/reports/Reports.vue')
Vue.use(VueRouter)
const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login },
{
path: '/home',
component: Home,
redirect: '/welcome',
children: [
{ path: '/welcome', component: Welcome },
{ path: '/users', component: User },
{ path: '/rights', component: Rights },
{ path: '/roles', component: Roles },
{ path: '/categories', component: Cate },
{ path: '/params', component: Params },
{ path: '/goods', component: GoodsList },
{ path: '/goods/add', component: GoodsAdd },
{ path: '/orders', component: Orders },
{ path: '/reports', component: Reports }
]
}
]
// 在Vue导航菜单中,重复点击一个菜单,即重复触发一个相同的路由,会报错,但不影响功能 需要以下代码来解决
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
if (to.path == '/login') return next()
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
export default router
const express = require('express')
const app = express()
app.use(express.static('./dist'))
app.listen(8998,()=>{
console.log("server running at http://127.0.0.1:8998")
})
然后再次在终端中输入 node app.js
const express = require('express')
const compression = require('compression')
const app = express()
app.use(compression())
app.use(express.static('./dist'))
app.listen(8998,()=>{
console.log("server running at http://127.0.0.1:8998")
})
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')
}
app.use(compression())
app.use(express.static('./dist'))
// app.listen(8998,()=>{
// console.log("server running at http://127.0.0.1:8998")
// })
//启动https服务
https.createServer(options,app).listen(443)
注意:因为我们使用的证书有问题,所以无法正常使用https服务