The routing mode before packaging
Total code:
"use strict";
const path = require("path");
const defaultSettings = require("./src/settings.js");
function resolve(dir) {
return path.join(__dirname, dir);
}
const name = defaultSettings.title || "vue Admin Template"; // page title
let cdn = { css: [].js: []};// Use environment variables to distinguish whether to use CDN
const isProd = process.env.NODE_ENV === "production"; // Check whether it is a production environment
let externals = {};
if (isProd) {
// If it is a production environment, it excludes packaging otherwise it does not exclude
externals = {
// key(package name)/value(this value is the name of the global object in the package that needs to be fetched in the CDN)
vue: "Vue".// The following name should be the global object name in JS
"element-ui": "ELEMENT".// are defined globally in js
xlsx: "XLSX" // are defined globally in js
};
cdn = {
css: [
"https://unpkg.com/element-ui/lib/theme-chalk/index.css" // Early introduction of elementUI styles].// Place the CSS file directory
js: [
"https://unpkg.com/vue/dist/vue.js".// vuejs
"https://unpkg.com/element-ui/lib/index.js".// element
"https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js"./ / XLSX related
"https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js" / / XLSX related
] // Place the js file directory
};
}
// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following methods:
// port = 9528 npm run dev OR npm run dev --port = 9528
const port = process.env.port || process.env.npm_config_port || 9528; // dev port
// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
/** * You will need to set publicPath if you plan to deploy your site under a sub path, * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, * then publicPath should be set to "/bar/". * In most cases please use '/' !!! * Detail: https://cli.vuejs.org/config/#publicpath */
publicPath: ". /".outputDir: "dist".assetsDir: "static".lintOnSave: process.env.NODE_ENV === "development".productionSourceMap: false.devServer: {
port: port,
open: true.overlay: {
warnings: false.errors: true
},
proxy: {
"/api": {
// target: "http://ihrm-java.itheima.net",
target: "http://192.168.68.30:66".changeOrigin: true.pathRewrite: {
"^/api": "/api"}}}// before: require("./mock/mock-server.js")
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
name: name,
resolve: {
alias: {
"@": resolve("src")}},externals: externals
},
chainWebpack(config) {
// it can improve the speed of the first screen, it is recommended to turn on preload
config.plugin("preload").tap(() = >[{rel: "preload".// to ignore runtime.js
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
fileBlacklist: [/\.map$/./hot-update\.js$/./runtime\.. *\.js$/].include: "initial"}]); config.plugin("html").tap(args= > {
args[0].cdn = cdn;
return args;
});
// when there are many pages, it will cause too many meaningless requests
config.plugins.delete("prefetch");
// set svg-sprite-loader
config.module
.rule("svg")
.exclude.add(resolve("src/icons"))
.end();
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(resolve("src/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]"}) .end(); config.when(process.env.NODE_ENV ! = ="development".config= > {
config
.plugin("ScriptExtHtmlWebpackPlugin")
.after("html")
.use("script-ext-html-webpack-plugin"[{// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\.. *\.js$/
}
])
.end();
config.optimization.splitChunks({
chunks: "all".cacheGroups: {
libs: {
name: "chunk-libs".test: /[\\/]node_modules[\\/]/,
priority: 10.chunks: "initial" // only package third parties that are initially dependent
},
elementUI: {
name: "chunk-elementUI".// split elementUI into a single package
priority: 20.// the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_? element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: "chunk-commons".test: resolve("src/components"), // can customize your rules
minChunks: 3.// minimum common number
priority: 5.reuseExistingChunk: true}}});// https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
config.optimization.runtimeChunk("single"); }); }};Copy the code
** Target ** configures the routing mode before packaging
In SPA single-page applications, there are two routing modes
Hash mode: # follows the routing path, which is characterized by front-end access, and changes to # do not pass through the server
History mode: Normal/access mode, characterized by back-end access, any change of address will access the server
So far in development, we’ve been using hash mode, packaging and we tried to use history mode
Changing the route mode to history is easy. You only need to change the route mode type to history
const createRouter = () = > new Router({
mode: 'history'.// require service support
scrollBehavior: () = > ({ y: 0 }), // Manage the scrolling behavior if there is a scroll switch let the page go back to the top
routes: [...constantRoutes] // Change to static route only
})
Copy the code
Suppose our address is www.xxxx/com/hr/a www.xxxx/com/hr/b
We will find that the domain name is actually **www.xxxx/com**, and hr is a specific prefix address. In this case, we can configure a base attribute and set it to hr
const createRouter = () = > new Router({
mode: 'history'.// require service support
base: '/hr/'.// Configure the base address of the project
scrollBehavior: () = > ({ y: 0 }), // Manage the scrolling behavior if there is a scroll switch let the page go back to the top
routes: [...constantRoutes] // Change to static route only
})
Copy the code
At this point, we will find that the address has changed to what we want
Submit code
Performance analysis and application of CDN
Objective: To analyze the performance of developed applications and the application of CDN
Performance analysis
We integrate features, we write a lot of components, we end up in a bunch of files, so how does it perform in the real world?
We can use vue-CLI’s own performance analysis tools to package and analyze all the features we developed
Its application is very simple
$ npm run preview -- --report
Copy the code
This command will do dependency analysis from our main. Js ** entry to get the largest package available for observation and optimization
After executing this command, we should see the following page
As shown in the figure, the larger the square is, the larger the file occupies, and the larger the file, the higher the requirement for network bandwidth and access speed, which is the direction of our optimization
So in this case, how do we optimize
Webpack excludes packaging
CDN is a better way
Isn’t the file big? We don’t need to package these large files and those small files together, such as XLSX, Element plug-ins with full functions, we can put them on the CDN server, on the one hand, reduce the size of the overall package, and on the other hand, the CDN acceleration service can speed up our access to the plug-in
use
Go to vue.config.js and add externals so that webPack doesn’t pack XLSX and Element
vue.config.js
// Exclude elementUI XLSX and vue
externals:
{
'vue': 'Vue'.'element-ui': 'ELEMENT'.'xlsx': 'XLSX'
}
Copy the code
Running again, we see that the package size has been greatly reduced
CDN file configuration
But what about the modules that are not packaged?
CDN can be used in the page template in advance
vue.config.js
const cdn = {
css: [
// element-ui css
'https://unpkg.com/element-ui/lib/theme-chalk/index.css' / / the style sheet].js: [
// vue must at first!
'https://unpkg.com/vue/dist/vue.js'.// vuejs
// element-ui js
'https://unpkg.com/element-ui/lib/index.js'.// elementUI
'https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js'.'https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js']}Copy the code
However, please note that this configuration actually takes effect for both the development environment and the production environment. In the development environment, there is no need to use THE CDN. In this case, we can use environment variables to distinguish
let cdn = { css: [].js: []}// Use environment variables to distinguish whether to use CDN
const isProd = process.env.NODE_ENV === 'production' // Check whether it is a production environment
let externals = {}
if (isProd) {
// If it is a production environment, it excludes packaging otherwise it does not exclude
externals = {
// key(package name)/value(this value is the name of the global object in the package that needs to be fetched in the CDN)
'vue': 'Vue'.// The following name should be the global object name in JS
'element-ui': 'ELEMENT'.// are defined globally in js
'xlsx': 'XLSX' // are defined globally in js
}
cdn = {
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css' // Early introduction of elementUI styles].// Place the CSS file directory
js: [
'https://unpkg.com/vue/dist/vue.js'.// vuejs
'https://unpkg.com/element-ui/lib/index.js'.// element
'https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js'./ / XLSX related
'https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js' / / XLSX related
] // Place the js file directory}}Copy the code
Inject the CDN file into the template
This is then injected into index.html via the html-webpack-plugin:
config.plugin('html').tap(args= > {
args[0].cdn = cdn
return args
})
Copy the code
Find public/index. HTML. Inject CSS and JS via your Config CDN.
<head> <! - introduction of style - > < % for (var CSS of htmlWebpackPlugin. Options. The CDN. CSS) {% > < link rel = "stylesheet" href = "< % = CSS % >" > < %} % > </head> <! - the introduction of JS - > < % for (var JS of htmlWebpackPlugin. Options. The CDN. JS) {% > < script SRC = "< % = JS % >" > < / script > < %} % >Copy the code
Finally, pack
$ npm run build:prod
Copy the code
Application and proxy across domains in nodeJS environment
The ** target ** packages the packaged code online and proxies it across domains in NodeJS
Deploy projects using the KOA framework
So far, we have completed a front-end engineer development process. As usual, at this point, o&M will deploy our code to the NGIx service of Ali Cloud. For us, we can deploy it to the native NodeJS environment
Deployment Automatic deployment or manual deployment
The first step is to create the Web services folder hrServer
$ mkdir hrServer Create hrServer folder
Copy the code
Second, in this folder, initialize NPM
$ npm init -y
Copy the code
Step 3: Install the server framework KOA (express or Egg)
$ npm i koa koa-static
Copy the code
Step 4: Copy the dist directory packaged in the previous section to **hrServer/public**
Step 5: Create app.js in the root directory
const Koa = require('koa')
const serve = require('koa-static');
const app = new Koa();
app.use(serve(__dirname + "/public")); // Static the code under public
app.listen(3333.() = > {
console.log('Human Resources Programme Launch')})Copy the code
At this point, we can go to http://localhost:3333
So here’s the page
Resolve the history page access problem
But there are two problems.
- When we refresh the page, we find 404
This is because we use the history mode, the change of address will cause the server to refresh, we just need to process all the addresses in app.js
Install koA middleware
$ npm i koa2-connect-history-api-fallback Middleware that specifically handles the History pattern
Copy the code
Registered middleware
const Koa = require('koa')
const serve = require('koa-static');
const { historyApiFallback } = require('koa2-connect-history-api-fallback');
const path = require('path')
const app = new Koa();
// All requests except the interface are sent to index.html
app.use(historyApiFallback({
whiteList: ['/prod-api']}));// There is a whiteList
app.use(serve(__dirname + "/public")); // Static the code under public
app.listen(3333.() = > {
console.log('Human Resources Programme Launch')})Copy the code
Solve cross-domain problems in production environment
- When you click login, interface 404 is found
As mentioned earlier, vue-CLI agents only exist during development, and when we go live in a Node or NGIx environment, we need to re-agent the environment
Proxy in NodeJS
Install cross-domain proxy middleware
$ npm i koa2-proxy-middleware
Copy the code
Configuring the spanning proxy
const proxy = require('koa2-proxy-middleware')
app.use(proxy({
targets: {
// (.*) means anything
'/prod-api/(.*)': {
target: 'http://ihrm-java.itheima.net/api'.// Back-end server address
changeOrigin: true.pathRewrite: {
'/prod-api': ""}}}}))Copy the code
Note: pathRewrite is used here because the production environment’s request base address is /prod-api, which needs to be removed
At this point, our project can be accessed across domains!
Up to now, we are more than ten days, completed a more complex middle anatomy and development of the project, any project is a complicated by reasonable design and layout of all sorts of function of assembled, so we each student to master the ability of the future is regardless of the difficulty and complexity of the project, all learn to decoupling and design technology, So our development capability will become stronger and stronger
That is All !
Thank you! ! !