【vue-cli】vue_shop电商后台管理项目优化,项目上线
完成项目的开发阶段,进入到发布阶段。
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. 根据报错修改代码
根据报告中的警告信息查询到具体问题代码
常见问题:
- 作用域定义scope未使用或其他变量未使用
- eslint与代码格式化冲突,在.prettierrc格式化配置文件内设置一行最多允许字符
{ "semi": false, // 格式化不加分号 "singleQuote": true,// 格式化以单引号为主 "printWidth": 200 // 格式化每行最多允许字符长度 }
- 变量最好为驼峰命名
- 文件过大,需要优化,可查阅下面的步骤
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中的第三方依赖包,都不会被打包。
- 如第五步代码中,将
config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios', lodash: '_', echarts: 'echarts', nprogress: 'NProgress', 'vue-quill-editor': 'VueQuillEditor' })
添加到vue.config.js配置文件中
- 将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的打包
-
在main-prod.js中,注释掉element-ui按需加载的代码
-
在index.html的头部区域中,通过CDN加载element-ui的js和css样式,完整代码见第六步代码
8. 首页内容定制
不同的打包环境下,首页内容可能会有所不同,可以通过插件的方式来定制首页内容,例如不同的首页标题title
在vue.config.js文件中对插件进行配置,见第五条中的内容定制代码,
然后在index.html首页中渲染,见第六步中定制内容代码
9. 路由懒加载
- 在开发依赖中安装
- 在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' ] }
- 对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中安装
然后可以再各终端中使用
- 点赞
- 收藏
- 分享
- 文章举报
- 最新VueCli3.0全栈项目-资金管理系统带权限(完整)
- 在 vue-cli 项目中渲染表格使 thead 固定, tbody出现滚动条并优化
- vue后台管理项目中element-ui中的upload组件
- Vue后台管理里系统项目前端解决跨域问题
- Vue后台管理项目踩坑
- vue初始化项目,构建vuex的后台管理项目架子
- vue-cli3 项目从搭建优化到docker部署的方法
- 在vue-cli搭建的项目中增加后台mock接口
- 详解vue-cli 构建项目 vue-cli请求后台接口 vue-cli使用axios、sass、swiper
- npm包管理 vue-cli创建vue项目
- 使用Vue-cli搭建后台简单管理系统vue.js2.0
- 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚
- vue脚手架项目结合adminLTE框架做单页面应用后台管理项目
- vue项目--iview企业项目后台管理----问题及解决
- Vue项目(vue-cli)和 node后台跨域(CORS)的问题
- vue-cli3+adminlte快速搭建后台管理模板...
- 20150115--SHOP项目架构+后台权限管理
- 【vue】MongoDB+Nodejs+express+Vue后台管理项目Demo
- vue-cli2.x项目优化之引入本地静态库文件的方法
- vue vue-cli webpack打包部署上线前的配置操作,初建vue项目 webpack打包需要注意的配置