Skip to content

Commit 362c835

Browse files
committed
Version 1.2.0
1 parent bb80a56 commit 362c835

File tree

5 files changed

+130
-32
lines changed

5 files changed

+130
-32
lines changed

example/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const webpack = require('webpack');
44
const config = require('./webpack.config');
55
const chalk = require('chalk');
66

7-
rm(path.resolve(__dirname, 'dist/'), err=> {
7+
rm(path.resolve(__dirname, 'example/dist/'), err=> {
88
if (err) throw err;
99
webpack(config, (err, stats) => {
1010
if (err) throw err;

example/webpack.config.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ const webpackConfig = {
88
mode: 'production',
99
context: path.resolve(__dirname, './'),
1010
entry: {
11-
main: {
12-
import: ['./src/index.js']
13-
},
11+
main: './src/index.js',
1412
vendor: './src/vendor.js'
1513
},
1614
output: {
@@ -20,7 +18,8 @@ const webpackConfig = {
2018
},
2119
plugins: [
2220
new VersinoCheckPlugin({
23-
versionFilename: 'version/current-version.json'
21+
versionFilename: 'version/current-version.json',
22+
// entryNeedInjectedUpdater: ['main', 'vendor']
2423
}),
2524
new HTMLWebpackPlugin({
2625
filename: 'index.html',

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
{
22
"name": "version-check-webpack-plugin",
3-
"version": "1.0.5",
3+
"version": "1.2.0",
44
"main": "index.js",
55
"repository": "[email protected]:kvsur/version-check-webpack-plugin.git",
66
"author": "kvsur <[email protected]>",
77
"license": "MIT",
8+
"types": "typings.d.ts",
9+
"semistandard": {
10+
"ignore": [
11+
"examples/*/dist/**/*.*"
12+
]
13+
},
14+
"files": [
15+
"index.js",
16+
"versionCheckPlugin.js",
17+
"updater-template.tpl",
18+
"typings.d.ts"
19+
],
820
"devDependencies": {
921
"chalk": "^4.1.1",
1022
"html-webpack-plugin": "^5.3.2",

typings.d.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Compiler } from "webpack";
2+
3+
export = VersionCheckWebpackPlugin;
4+
5+
export type EntryEntries = {[x: string]: string};
6+
7+
declare class VersionCheckWebpackPlugin {
8+
constructor(options?: VersionCheckWebpackPlugin.Options);
9+
10+
private options: VersionCheckWebpackPlugin.Options;
11+
private updaterName: string;
12+
private updaterExtension: string;
13+
private updaterPath: string;
14+
15+
private getPrePath(): string;
16+
17+
private generateFile(compiler: Compiler): void;
18+
19+
private removeFile(): void;
20+
21+
private getEntryEntries(compiler: Compiler): EntryEntries;
22+
23+
public apply(compiler: Compiler): void;
24+
25+
static readonly version: number;
26+
static readonly pluginName: 'VersionCheckWebpackPlugin';
27+
}
28+
29+
declare namespace VersionCheckWebpackPlugin {
30+
interface Options { versionFilename?: string, entryNeedInjectedUpdater?: string | [] }
31+
}

versionCheckPlugin.js

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,46 @@
11
const path = require('path');
2-
const exec = require('child_process').execSync;
32
const fs = require('fs');
43

54
/**
6-
* @typedef {{ versionFilename?: string }} Options
5+
* @typedef {import('./typings').Options} Options
76
*/
87
class VersinoCheckPlugin {
98
/**
109
*
1110
* @param {Options} options
1211
*/
13-
constructor(options) {
12+
constructor(options = {}) {
1413
this.updaterName = 'updater';
1514
this.updaterExtension = '.js';
16-
this.name = 'VersionCheckPlugin';
1715
const defualtVersionFilename = 'version-hash.json';
18-
const defualtUpdaterPath = 'cache-controller';
19-
this.options = Object.assign({ versionFilename: defualtVersionFilename, updaterPath: defualtUpdaterPath },
16+
this.updaterPath = 'cache-controller';
17+
this.options = Object.assign({ versionFilename: defualtVersionFilename },
2018
options);
19+
20+
this.options.entryNeedInjectedUpdater = ['main'];
21+
if (typeof options.entryNeedInjectedUpdater === 'string') {
22+
this.options.entryNeedInjectedUpdater = [options.entryNeedInjectedUpdater];
23+
} else if (Array.isArray(options.entryNeedInjectedUpdater)) {
24+
this.options.entryNeedInjectedUpdater = [...options.entryNeedInjectedUpdater];
25+
}
2126
}
2227

2328
/**
2429
* Get updater file generate dirctory(unclude filename).
2530
* @returns {string}
2631
*/
2732
getPrePath() {
28-
return this.options.updaterPath;
33+
return this.updaterPath;
2934
}
3035

3136
/**
3237
* Inject updater to frontend code as entry
3338
* @param {import('webpack').Compiler} compiler
3439
*/
3540
generateFile(compiler) {
36-
const { context } = compiler;
37-
this.options.updaterPath = path.join(context, 'src', this.options.updaterPath);
41+
const { options } = compiler;
3842
const prePath = this.getPrePath();
39-
let publicPath = compiler.options.output.publicPath;
43+
let publicPath = options.output.publicPath;
4044
publicPath = (!publicPath || publicPath === 'auto') ? '' : publicPath;
4145
try {
4246
fs.mkdirSync(prePath, { recursive: true });
@@ -55,39 +59,88 @@ class VersinoCheckPlugin {
5559
* Remove updater temp code in src dir.
5660
*/
5761
removeFile() {
58-
const rmCommand = `rm -rf ${this.getPrePath()}`;
5962
try {
60-
exec(rmCommand);
63+
fs.unlinkSync(path.join(this.getPrePath(), this.updaterName + this.updaterExtension));
64+
fs.rmdirSync(this.getPrePath());
6165
} catch (e) {
6266
throw e;
6367
}
6468
}
6569

70+
/**
71+
*
72+
* @param {import('webpack').Compiler} compiler
73+
*/
74+
getEntryEntries(compiler) {
75+
const originEntry = compiler.options.entry;
76+
/** @type {import('./typings').EntryEntries} */
77+
const entryResult = {};
78+
if (typeof originEntry === 'string') entryResult['main'] = originEntry;
79+
else if (Array.isArray(originEntry)) entryResult['main'] = originEntry[0];
80+
else {
81+
const entryKeys = Object.keys(originEntry);
82+
entryKeys.forEach(key => {
83+
const val = originEntry[key];
84+
if (typeof val === 'string') entryResult[key] = val;
85+
else if (Array.isArray(val)) entryResult[key] = val[0];
86+
else entryResult[key] = val['import'][0];
87+
});
88+
}
89+
return entryResult;
90+
}
91+
6692
/**
6793
* This plugin entry for webpack.
6894
* @param {import('webpack').Compiler} compiler
6995
*/
7096
apply(compiler) {
71-
compiler.hooks.afterEnvironment.tap(this.name, () => {
97+
const { outputFileSystem, options, context } = compiler;
98+
this.updaterPath = path.join(context, 'src', this.updaterPath);
99+
compiler.hooks.afterEnvironment.tap(VersinoCheckPlugin.pluginName, () => {
72100
this.generateFile(compiler);
73-
const { outputFileSystem, options } = compiler;
74-
const firstEntry = Object.keys(options.entry)[0];
75-
// Deal multiple versions of webpack.
76-
const newEntryPath = path.join(this.options.updaterPath, this.updaterName + this.updaterExtension);
77-
if (typeof options.entry[firstEntry] === 'object' && options.entry[firstEntry].import) {
78-
options.entry[this.updaterName] = { import: [newEntryPath]};
79-
} else {
80-
options.entry[this.updaterName] = newEntryPath;
81-
}
82-
compiler.hooks.thisCompilation.tap(this.name, compilation => {
83-
compilation.hooks.afterChunks.tap(this.name, chunks => {
84-
compilation.hooks.afterHash.tap(this.name, () => {
101+
const entryEntries = this.getEntryEntries(compiler);
102+
const entryKeys = Object.keys(entryEntries);
103+
const entryNeedInjectedUpdaterResource = [];
104+
this.options.entryNeedInjectedUpdater.forEach(entryName => {
105+
const val = entryEntries[entryName];
106+
if (val) entryNeedInjectedUpdaterResource.push(val);
107+
});
108+
compiler.hooks.thisCompilation.tap(VersinoCheckPlugin.pluginName, compilation => {
109+
const originSources = {};
110+
const injectModulePath = path.join(this.getPrePath(), this.updaterName + this.updaterExtension);
111+
compilation.hooks.buildModule.tap(VersinoCheckPlugin.pluginName, moduleSource => {
112+
if (entryNeedInjectedUpdaterResource.indexOf(moduleSource.rawRequest) >= 0) {
113+
try {
114+
const originSource = fs.readFileSync(moduleSource.resource, {encoding: 'utf-8'});
115+
originSources[moduleSource.rawRequest] = originSource;
116+
117+
const injectedSource =
118+
`\nimport '${injectModulePath.replace(/\\/g, '/')}';\n` + originSource;
119+
fs.writeFileSync(moduleSource.resource, injectedSource, {encoding: 'utf-8'});
120+
} catch (e) {
121+
throw e;
122+
}
123+
}
124+
});
125+
compilation.hooks.succeedModule.tap(VersinoCheckPlugin.pluginName, moduleSource => {
126+
if (entryNeedInjectedUpdaterResource.indexOf(moduleSource.rawRequest) >= 0) {
127+
try {
128+
fs.writeFileSync(moduleSource.resource, originSources[moduleSource.rawRequest], {
129+
encoding: 'utf-8',
130+
})
131+
} catch (e) {
132+
throw e;
133+
}
134+
}
135+
});
136+
compilation.hooks.afterChunks.tap(VersinoCheckPlugin.pluginName, chunks => {
137+
compilation.hooks.afterHash.tap(VersinoCheckPlugin.pluginName, () => {
85138
const { entry } = compiler.options;
86139
const chunkHash = Array.from(chunks);
87140
/** @type {{ version: string }} */
88141
const versionHash = { version: '' };
89142
let versionVal = '';
90-
Object.keys(entry).map(entryName => {
143+
entryKeys.map(entryName => {
91144
versionVal += chunkHash.find(({name}) => name === entryName).renderedHash;
92145
});
93146
versionHash.version = versionVal;
@@ -112,4 +165,7 @@ class VersinoCheckPlugin {
112165
}
113166
}
114167

168+
VersinoCheckPlugin.version = 1;
169+
VersinoCheckPlugin.pluginName = 'VersionCheckPlugin';
170+
115171
module.exports = VersinoCheckPlugin;

0 commit comments

Comments
 (0)