Technical background
The framework used for the project is VUe2 and the construction tool is WebPack
The problem
The project iterates frequently. After each online launch, sales personnel (users) need to be notified to manually refresh before the system can be used, otherwise the old version will be used all the time and some unpredictable errors will occur.
why
Vue framework development is a single page Web application (SPA)
Popular accounts
Load the appropriate HTML, JavaScript, and CSS when the Web page is initialized. Once the page is loaded, SPA will not reload or jump the page because of the user’s operation. Instead, routing mechanisms are used to change HTML content, interact with the user, and avoid page reloading.
advantages
User experience is good, fast, content change does not need to reload the whole page, avoid unnecessary jump and repeated rendering; Even at the point above, the SPA exerts less pressure on the server; The responsibilities of the front and back end are separated, and the architecture is clear. The front end carries out interactive logic, and the back end is responsible for data processing
disadvantages
The initial loading is time-consuming; To achieve the single-page Web application function and display effect, you need to load JavaScript and CSS in a unified manner, load some pages as required, and manage forward and backward routes.
conclusion
Because it is a single page application, the user enters the website, will use the HTML and the corresponding resources of the browser cache mechanism, stay in the local, such a benefit, is to enter the website again, can use the cache mechanism, can quickly enter the website. As a result, after the iteration of our project version, users will continue to use the old iteration version due to the caching mechanism, and users need to manually refresh to request the server to obtain new HTML to use the new iteration version.
The user manually refreshes the HTML to get the new version (this needs to be configured in nginx, in the nginx.conf file, so that the index.html is not cached).
demand
After project iteration, users will be prompted for version update or automatically refresh to realize version upgrade
plan
Schematic diagram
Version number: the version number obtained by the current timestamp interface when the package is automatically created: the version number is automatically created when the Webpack is built. The static page version number is automatically created during the webpack build and is automatically written into the meta information of the index. HTML pageCopy the code
code
nginx
Configuration – Set the nginx.conf file so that index.html is not cached
location = /index.html {
root /usr/share/nginx/html;
add_header Cache-Control "no-cache, no-store";
}
Copy the code
version.js
Creating a version file
const fs = require('fs') // Import the file module
const Timestamp = new Date().getTime()
fs.writeFile('public/version.json'.'{"version":' + Timestamp + '}\n'.function (err) {
if (err) {
return console.log(err)
}
})
Copy the code
package.json
Vue build command:
"build:prodb": "node version.js && vue-cli-service build --mode prodb"
Copy the code
Version. js is a file automatically generated by the version number and used by the requesting interface.
vue.config.js
Vue2 – Configuration file -vue.config.js
// Get version number data
const bpmVersion = process.env.NODE_ENV === 'production'
|| process.env.NODE_ENV === 'prodb' ? require('./public/version.json') : {
version: 'dev'
}
module.exports = {
pages: {
index: {
// Page entry
entry: 'src/main.js'.// Template source
template: 'public/index.html'.// Output in dist/index.html
filename: 'index.html'.version: bpmVersion.version, / / version number
// The blocks contained in this page are contained by default
// The extracted generic chunk and Vendor chunk.
chunks: ['chunk-vendors'.'chunk-common'.'index']}}Copy the code
index.html
Index.html – Page configuration version number field storage
<meta name="version" content="<%= htmlWebpackPlugin.options.version%>" />
Copy the code
generate-asset-webpack-plugin
It can also be created by the generate-asset-webpack-plugin plugin
const GeneraterAssetPlugin = require('generate-asset-webpack-plugin');
const {
name
} = require('./package.json');
const timestamp = new Date().getTime();
const version = `v${timestamp}`;
const createJson = function () {
const data = {
app: {
name,
version
}
};
return JSON.stringify(data);
};
plugins: [
// Generate a version id
new GeneraterAssetPlugin({
filename: 'app.json'.fn: (compilation, cb) = > {
cb(null, createJson()); }})].chainWebpack: (config) = > {
config
.plugin('html')
.tap(args= > {
args[0].name = name;
args[0].version = timestamp;
return args
});
}
Copy the code
Generate app.json file contents as follows:
{"app": {"name":"app-name"."version":"v1649818515910"}}
Copy the code
Currently, the version number of the page and the version number of the interface are ready. All that’s left is two versions to match. For comparison, in order to avoid unnecessary interface comparison, the comparison time is deliberately fixed after entering the route-load page, so that the user experience will be better (purely personal experience).
router.js
The comparison code
router.js
router.afterEach(async (to, form) => {
// The production environment prompts an upgrade
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'prodb') {
const checkVersion = await store.dispatch('checkVersion')
if(! checkVersion) {// The obtained version number varies
Message.warning('New versions are being automatically upgraded... '.2.() = > {
window.location.reload() Refresh to obtain the latest version}}}})Copy the code
store.js
store.js
actions: {
checkVersion ({ commit, state }) {
return new Promise(resolve= > {
Axios.get('/version.json? v=' + new Date().getTime(),
{ headers: { 'Cache-Control': 'no-cache' },
baseURL: window.location.origin })
// Request the contents of the JSON file, and disable caching
.then(res= > {
const version = res.version
const clientVersion = Number(document.querySelector('#BPMVersion').content
|| ' ')
resolve(version === clientVersion)
})
})
}
}
Copy the code
To optimize the
The function can meet the requirements at present, but we can also add the version number to check, so that we can know which version is currently used and when it was launched
store.js
checkVersion ({ commit, state }) {
return new Promise(resolve= > {
Axios.get('/version.json? v=' + new Date().getTime(),
{ headers: { 'Cache-Control': 'no-cache' },
baseURL: window.location.origin })
// Request the contents of the JSON file, and disable caching
.then(res= > {
const version = res.version
const clientVersion = Number(document.querySelector('#BPMVersion')
.content || ' ')
// The following is to check the version number online time - start
console.info('%c Environment ' + '%c ' + process.env.NODE_ENV + ' '.'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060'.'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#42c02e')
console.info('%c Build Date ' + '%c ' +
dateFtt('yyyy-MM-dd hh:mm:ss'.new Date(clientVersion)) + ' '.'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060'.'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#1475b2')
console.info('%c Last Build Date ' + '%c ' +
dateFtt('yyyy-MM-dd hh:mm:ss'.new Date(version)) + ' '.'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060'.'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#1475b2')
// -end
resolve(version === clientVersion)
})
})
}
Copy the code
Version View effect
Page prompt
Console output
Next up
In view of the current project using Webpack packaging speed is getting slower and slower, I hope to make more attempts in vite tool, after stepping on the pit. At the end of April, there will be a comparison of Vite and Webpack articles and examples, as well as all the pits to share with you
Wrote last
Currently the code only applies to vue2 version, the principles can be borrowed from other frameworks. Because the front end only participates in the whole process, it will need to request interface comparison of version number every time when switching routes, which will cause some waste of interface. At present, I have not come up with a better solution to solve this problem, looking forward to the subsequent optimization of this aspect of the plan.
Team to introduce
GFE trading Compliance Front End Team (GFE), which belongs to the BUSINESS line R&D Department of Trading Compliance business of GFE (Beijing), is a team with passion, creativity and adherence to technology-driven comprehensive growth. The average age of the team is 27 years old. Some of them have been working in their fields for many years, and some of them have just graduated. We actively explore in engineering, coding quality, performance monitoring, micro-service, interactive experience and other directions, pursuing the purpose of technology-driven product landing, and creating a perfect front-end technology system.
- Vision: To be the most trusted and influential front-end team
- Mission: Adhere to customer experience first, create more possibilities for business
- Culture: courage to undertake, in-depth business, brainstorming, simple and open
Github:github.com/gfe-team
Team email: [email protected]
Author: GFE Team
Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.