A: hi! ~ Hello everyone, I am YK bacteria 🐷, a microsystem front-end ✨, love to think, love to summarize, love to record, love to share 🏹, welcome to follow me 😘 ~ [wechat account: Yk2012Yk2012, wechat public account: ykyk2012]
“This is the 14th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
The address of the project: https://gitee.com/ykang2020/vue_shop
The project is finally finished, today we are going to optimize the project we did before, and then put our project online ~
1. Project optimization
1.1 Add progress bar effect at the top of web page
Nprogresst github.com/rstacruz/np…
Main.js imports and configures interceptors
/ / import NProgress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import axios from 'axios'
// Configure the request root path
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
// Request the interceptor to add the token through AXIos to guarantee the access to the data
// Display the progress bar nprogress.start () in the request interceptor
axios.interceptors.request.use(config= > {
// Add the Token authentication Authorization field for the request header object
// console.log(config)
NProgress.start()
config.headers.Authorization = window.sessionStorage.getItem('token')
// You must return config at the end
return config
})
// In response interceptor, hide the progress bar nprogress.done ()
axios.interceptors.response.use(config= > {
NProgress.done()
return config
})
Copy the code
1.2 the console problem
1.2.1 Remove all Console during build command execution
Installation development dependencybabel-plugin-transform-remove-console
babel.config.js
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'].plugins: [['component',
{
libraryName: 'element-ui'.styleLibraryName: 'theme-chalk'}], ['transform-remove-console']]}Copy the code
1.2.2 Remove all Consoles only during release
// This is the Babel plug-in needed during the project release phase
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')}module.exports = {
presets: ['@vue/cli-plugin-babel/preset'].plugins: [['component',
{
libraryName: 'element-ui'.styleLibraryName: 'theme-chalk'}].// An array of plugins when the product is released
[...prodPlugins]
]
}
Copy the code
1.3 Generating a package report
In order to visually discover problems in a project, reports can be generated during packaging in two ways
1.3.1 Generating a Report using COMMAND Line Parameters
/ / by vue-cliCommand options to generate a packaged report // --reportOption to generate report.html to help analyze package content vue-cli-service build --report
Copy the code
1.3.2 Generate and view reports directly from the Visual UI Panel (Recommended)
Console – Analysis panel
1.4 Modifying the WebPack Configuration
By default, all webpack configuration items are hidden in projects generated by visual interface tools. The purpose is to shield the configuration process of projects and let programmers focus on the implementation of specific functions and business logic
If you need to modify the default webPack configuration, you can create the vue.config.js configuration file in the project root directory as required to customize the packaging and publishing process of the project (see cli.vuejs.org/zh/config/#…). .
// vue.config.js
// In this file, you should export an object that contains custom configuration options
module.exports = {
/ / options...
}
Copy the code
1.4.1 Specify different packaging entry for development mode and release mode
By default, the development mode of a Vue project and the publishing mode share the same packaged entry file (SRC /main.js). To separate the development process from the release process of a project, we can specify packaged entry files for each of the two modes, namely:
① The development mode entry file is SRC /main-dev.js
② The entry file for publishing mode is SRC /main-prod.js
1.4.2 configureWebpack and chainWebpack have the same functions and are used differently
A configureWebpack or chainWebpack node is added to the configuration object exported from vue.config.js to customize the packaging configuration of WebPack.
ConfigureWebpack and chainWebpack work the same way, the only difference being how they modify the WebPack configuration:
A chainWebpack configureWebpack configures the default WebPack configuration by manipulating objects
The use of two specific differences, may refer to the following url: cli.vuejs.org/zh/guide/we…
1.4.3 Custom Packaging with chainWebpack
module.exports = {
chainWebpack: config= > {
config.when(process.env.NODE_ENV === 'production'.config= > {
config
.entry('app')
.clear()
.add('./src/main-prod.js')
})
config.when(process.env.NODE_ENV === 'development'.config= > {
config
.entry('app')
.clear()
.add('./src/main-dev.js')}}}Copy the code
1.5 Loading External CDN Resources
By default, third-party dependency packages imported through the import syntax are packaged and merged into the same file. As a result, the size of a single file becomes too large after the package is successfully packaged.
To solve the above problems, external CDN resources can be configured and loaded through the externals node of webpack. Any third-party dependencies declared in externals will not be packaged.
1.5.1 Externals Configure and load external CDN resources
- Add it in vue.config.js
module.exports = {
chainWebpack: config= > {
// Publish mode
config.when(process.env.NODE_ENV === 'production'.config= > {
config
.entry('app')
.clear()
.add('./src/main-prod.js')
config.set('externals', {
vue: 'Vue'.'vue-router': 'VueRouter'.axios: 'axios'.lodash: '_'.echarts: 'echarts'.nprogress: 'NProgress'.'vue-quill-editor': 'VueQuillEditor'})})// Development mode
config.when(process.env.NODE_ENV === 'development'.config= > {
config
.entry('app')
.clear()
.add('./src/main-dev.js')}}}Copy the code
- Remove the imported stylesheet code in main.js
- At the same time, add the following CDN resource reference to the header of the public/index.html file:
<! -- NProgress style sheet file -->
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
<! -- Rich text editor style sheet file -->
<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" />
Copy the code
<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>
<! -- Rich text editor js file -->
<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>
Copy the code
1.5.2 effect
1.5.3 Optimize ElementUI packaging
Although we enabled on-demand loading of element-UI components during the development phase to minimize the volume of packaging, components that were loaded on demand still occupied a large file volume.
At this point, we can also load the components in the Element-UI through the CDN, which further reduces the size of the packaged file. The specific operation process is as follows:
In the header area of index.html, load the JS and CSS styles of Element-UI through the CDN
<! -- Element-UI style sheet file -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" />
<! -- Element-ui js file -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
Copy the code
1.5.4 effect
1.6 Homepage Title Content Customization
The content of the home page may vary depending on the packaging environment. We can customize this by means of plug-ins, which are configured as follows
In the public/index.html home page, you can decide how to render the page structure according to the value of isProd:
module.exports = {
chainWebpack: config= > {
// Publish mode
config.when(process.env.NODE_ENV === 'production'.config= > {
config
.entry('app')
.clear()
.add('./src/main-prod.js')
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
})
})
// Development mode
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
})
})
}
}
Copy the code
<! Render page title on demand -->
<title><%= htmlWebpackPlugin.options.isProd ? ': 'dev -' %> E-commerce backend management system</title>
<! -- Load external CDN resources on demand -->
<% if(htmlWebpackPlugin.options.isProd) { %>
<! External CDN resources loaded via externals -->The < %} % >Copy the code
1.7 Implementing lazy Route loading
JavaScript packages can become very large when packaging build projects, affecting page loading. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed.
There are three specific steps:
① Installation and development rely on @babel/plugin-syntax-dynamic-import package
② Declare the plug-in in the babel.config.js configuration file
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'].plugins: [['component',
{
libraryName: 'element-ui'.styleLibraryName: 'theme-chalk'}].// An array of plugins when the product is released
[...prodPlugins],
['@babel/plugin-syntax-dynamic-import']]}Copy the code
③ An example code for changing the route to load on demand is as follows:
const Foo = () = > import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () = > import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () = > import(/* webpackChunkName: "group-boo" */ './Baz.vue')
Copy the code
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'
// import Rights from '.. /components/power/Rights.vue'
// import Roles from '.. /components/power/Roles.vue'
const Users = () = > import(/* webpackChunkName: "Users_Rights_Roles" */ '.. /components/user/Users.vue')
const Rights = () = > import(/* webpackChunkName: "Users_Rights_Roles" */ '.. /components/power/Rights.vue')
const Roles = () = > import(/* webpackChunkName: "Users_Rights_Roles" */ '.. /components/power/Roles.vue')
// import Cate from '.. /components/goods/Cate.vue'
// import Params from '.. /components/goods/Params.vue'
const Cate = () = > import(/* webpackChunkName: "Cate_Params" */ '.. /components/goods/Cate.vue')
const Params = () = > import(/* webpackChunkName: "Cate_Params" */ '.. /components/goods/Params.vue')
// import GoodsList from '.. /components/goods/List.vue'
// import Add from '.. /components/goods/Add.vue'
const GoodsList = () = > import(/* webpackChunkName: "GoodsList_Add" */ '.. /components/goods/List.vue')
const Add = () = > import(/* webpackChunkName: "GoodsList_Add" */ '.. /components/goods/Add.vue')
import Order from '.. /components/order/Order.vue'
import Report from '.. /components/report/Report.vue'
const Order = () = > import(/* webpackChunkName: "Order_Report" */ '.. /components/order/Order.vue')
const Report = () = > import(/* webpackChunkName: "Order_Report" */ '.. /components/report/Report.vue')
Vue.use(VueRouter)
Copy the code
before
after
For detailed documentation on route lazy loading, see the links below
Router.vuejs.org/zh/guide/ad…
2. Project launch
2.1 Creating a Web Server using a Node
- Create the Node project and install Express
Express is used to quickly create a Web server, package the vUE into the generated Dist folder, and host it as a static resource
Create a folder of the same level as vue_shop. Vue_shop_server Run the vue_shop_server command
npm init -y
cnpm install express -S
Copy the code
- Copy the dist folder from the vue_shop folder to vue_shop_server
- Create the app.js file in vue_shop_server
const express = require('express')
// Create web server
const app = express()
// Manage static resources
app.use(express.static('./dist'))
// Start the Web server
app.listen(80.() = > {
console.log("server running at http://127.0.0.1")})Copy the code
- perform
node app.js
- The project can be accessed at http://127.0.0.1
2.2 Enabling Gzip network Transmission Compression for Files
You can use gzip to reduce file size and make transfers faster. Gzip compression can be done using Express on the server side.
- Install compression will package
cnpm install compression -S
Copy the code
- use
const compression = require('compression')
// Write before static resource hosting
app.use(compression())
Copy the code
- The effect
2.3 Configuring HTTPS Services
Why enable the HTTPS service?
- The traditional HTTP protocol transmits data in plain text, which is not secure
- HTTPS is used to encrypt the transmitted data, preventing the data from being stolen by the middleman
Applying for an SSL Certificate (freessl.org or freessl.cn/)
① Go to freessl.cn/ official website, enter the domain name to apply for and select the brand.
② Enter your email address and select relevant options.
③ Verify DNS (add TXT records in the domain name management background).
4. After the authentication succeeds, download the SSL certificate (full_chain.pem public key; Private. key Indicates the private key.
Import the certificate in the background project
const https = require('https');
const fs = require('fs');
const options = {
cert: fs.readFileSync('./full_chain.pem'),
key: fs.readFileSync('./private.key')}// app.listen(80, () => {
// console.log("server running at http://127.0.0.1")
// })
https.createServer(options, app).listen(443);
Copy the code
2.4 Using PM2 to Manage Applications
Closing the terminal window allows the project to run normally
① Install pM2 on the server: CNPM install pm2 -g
② Start project: pm2 start script –name User-defined name
pm2 start ./app.js --name web_vueshop
Copy the code
③ Check the running project: PM2 LS
④ Restart project: pm2 restart User-defined name/ID
⑤ Stop project: pM2 stop custom name
⑥ Delete an item: pm2 delete User-defined name
The address of the project: https://gitee.com/ykang2020/vue_shop
Finally, welcome to my column and make friends with YK bacteria