The cause of
There is a requirement that a single page application (Vue, React) can automatically generate a version output to the target directory (dist) when performing packaging. In this way, when a Bug occurs online, you can know which version to modify and locate the problem.
To solve the process
Manually add version information
Of course, you can manually add some version information in the output directory version. TXT, but every release package needs to be manually added, it is obviously not in line with the style of programmers, repeated things of course need to use code to replace the solution
Write anodejs
The script
- So the first thing that comes to mind is we could write one
nodejs
To invoke thegit
Related commands get the current version information and write toversion.txt
In, the execution time is executenpm run build
After.package.json
Modified as follows:
"script:": {
"build": "script/build.js && node script/version.js"
}
Copy the code
- The js script is as follows:
// version.js
const execSync = require('child_process').execSync;
const fs = require('fs');
// Get git information
const COMMITHASH_COMMAND = 'rev-parse HEAD';
const VERSION_COMMAND = 'describe --always';
const BRANCH_COMMAND = 'rev-parse --abbrev-ref HEAD';
try {
const d = new Date(a);const versionStr =`
Revision: ${execSync(`git ${COMMITHASH_COMMAND}`)}
Branch: ${execSync(`git ${BRANCH_COMMAND}`)}
Release: ${execSync(`git ${VERSION_COMMAND}`)}
X-PackingTime: ${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}${d.getHours()}:${d.getMinutes()}
`;
fs.writeFileSync(`dist/version.txt`, versionStr);
} catch (e) {
throw new Error(e);
}
Copy the code
- With the above two steps directly execute
npm run build
Execution can then be executedWebpack
Automatic execution after packagingversion.js
Script that automatically writes version information todist/version.txt
In, free hands.
Through the analysis of the above two steps, you can already implement a script that automatically generates version information, but there are still some problems:
- Script execution is inflexible and there is no way to pass in parameters to suit different projects
- Every project needs to be combined
version.js
The file is copied to the specified directory and then added to the command line to be executed using Node - Different projects may require separate manual maintenance scripts, which is not conducive to the maintenance of the script. If there is a uniform change, it needs to be modified for each project, and there is still a lot of repetitive work to do
throughWebpack
The plug-in writes version information
The above analysis of our protagonist is clear, my solution is:
- Write a
Webpack
The NPM package of the plugin, which uses the hook function provided by WebPack to get the version information after the build and write it locally - Publish to the company’s private repository (it is not high enough to publish to the public NPM 😅)
- Use NPM to install and configure directly to
Webpack
theplugins
Different parameters can be passed in to suit different projects
Developing an NPM package that can be published to AN NPM or NPM private repository requires some knowledge of the NPM package development and distribution process
Development process (usenpm link
) :
- Under the package and directory
npm link
To establish a global link to the developed NPM package - In the project root directory used
npm line package-name
Package-name is the package name configured in package.json - cancel
npm unlink
Release process:
- Prepare the NPM account. For private servers, set the address of the local NPM repository to the private server address
- The login
npm login
- release
npm publish
- use
npm install xxx [options]
Write the Webpack plug-in
The best teacher to learn something new should be the official documentation, through the documentation can quickly write their own need for plug-in functions
- First, plugins all have an apply method, which has a compiler parameter:
const pluginName = 'RepoRevisionWebpackPlugin';
// Get git information
const COMMITHASH_COMMAND = 'rev-parse HEAD';
const VERSION_COMMAND = 'describe --always';
const BRANCH_COMMAND = 'rev-parse --abbrev-ref HEAD';
class RepoRevisionWebpackPlugin {
constructor (options = {}) {}
apply(compiler) {
// Compiler instances have hooks for each lifecycle of WebPack execution
// The first argument to the tap method is the humped name of the plug-in, and the callback function can do whatever business logic it wants
compiler.hooks.run.tap(pluginName, (compilation) = > {
console.log('Webpack build process begins! ');
});
// I'm using the done event to execute my business logic after the build is complete
compiler.hooks.done.tap(pluginName, () = > {
console.log('Webpack build process finished! ');
try {
const d = new Date(a);const versionStr =`
Revision: ${execSync(`git ${COMMITHASH_COMMAND}`)}
Branch: ${execSync(`git ${BRANCH_COMMAND}`)}
Release: ${execSync(`git ${VERSION_COMMAND}`)}
X-PackingTime: ${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}${d.getHours()}:${d.getMinutes()}
`;
// Compiler instances can get the parameters passed in when the plugin is used
fs.writeFileSync(`${compiler.options.output.path}/version.txt`, versionStr);
} catch (e) {
throw new Error(e); }}}})module.exports = RepoRevisionWebpackPlugin;
Copy the code
- This is easy to use, as you can create an NPM link through the development process described above, and import and configure it directly into plugins in the WebPack configuration file
const RepoRevisionWebpackPlugin = require('RepoRevisionWebpackPlugin');
module.exports = {
plugins: [
new RepoRevisionWebpackPlugin({}),
]
}
Copy the code
The webpack plugin can be used to obtain git version information, and can be used to release a crude NPM package for other projects.
Of course, the above function is very simple, only as a hint, there are also a lot of places to improve, such as:
- Unit testing
- Do more with compiler and compilation hooks (both of which provide event functions that enable developers to do more, as mentioned below)
One day
- Need to pay attention to
Webpack
Version issues,Webpack4
The previous hook function is not the same as the later hook function, and you need to determine whether you need to be compatible with the lower versionWebpack
- Install the NPM private repository, which can be accessed through
Docker
The way fastThe installationA NPM private server of your own
To move the brick
- Webpack Plugins
- Compilation hooks
- The compiler hooks
- Use Verdaccio to build a private NPM repository