From 438b638a68e2842d50f460b5ad3aa6089beb842d Mon Sep 17 00:00:00 2001 From: cxtom Date: Tue, 28 Jul 2020 10:56:05 +0800 Subject: [PATCH] fix: support parent mod --- package.json | 2 +- src/index.ts | 47 ++++++++++++++++++++++++++++--- test/fixtures/mainModule.js | 2 +- test/fixtures/mod2.js | 1 + test/fixtures/mod3.js | 3 ++ test/index.test.ts | 55 +++++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/mod3.js diff --git a/package.json b/package.json index ad7057a..a1e13c9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "prebuild": "rimraf dist", "build": "tsc --module commonjs && rollup -c rollup.config.ts && typedoc --out docs --target es6 --theme minimal --mode file src", "start": "rollup -c rollup.config.ts -w", - "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' node --expose-gc ./node_modules/.bin/nyc mocha --require ts-node/register --require source-map-support/register --full-trace --bail test/index.test.ts", + "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' nyc mocha --require ts-node/register --require source-map-support/register --full-trace --bail test/index.test.ts", "deploy-docs": "ts-node tools/gh-pages-publish", "report-coverage": "cat ./coverage/lcov.info | coveralls", "commit": "git-cz", diff --git a/src/index.ts b/src/index.ts index d262274..7d1941d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,9 +7,14 @@ import {join} from 'path'; import batchdelcache from 'batchdelcache'; interface IFileMap { - [fileName: string]: string; + [fileName: string]: IFileMapItem; } +type IFileMapItem = string | { + key: string; + parents?: string[]; +}; + export interface IOptions { /* 项目所在根目录 */ @@ -52,18 +57,33 @@ export default class Reloader { } reload(newFileMap: IFileMap) { + const reloadModules = new Set(); - for (const [name, md5] of Object.entries(newFileMap)) { - if (this.filter(name) && (name in this.fileMap) && this.fileMap[name] !== md5) { - reloadModules.add(require.resolve(join(this.context, name))); + + for (const [name, item] of Object.entries(newFileMap)) { + const hasKey = name in this.fileMap; + const md5 = this.getKey(item); + if (hasKey && this.getKey(this.fileMap[name]) !== md5 && this.filter(name)) { + const parents = this.getParents(item); + if (parents.length > 0) { + parents.forEach(filename => reloadModules.add(join(this.context, filename))); + } + else { + reloadModules.add(join(this.context, name)); + } } } + + // 删除缓存 batchdelcache( Array.from(reloadModules) ); + + /* istanbul ignore next */ if (typeof global.gc === 'function') { global.gc(); } + const errors: IError[] = []; for (const mod of reloadModules) { try { @@ -77,7 +97,9 @@ export default class Reloader { }); } } + this.updateFileMap(Object.assign(this.fileMap, newFileMap)); + return { reloadModules: Array.from(reloadModules), errors, @@ -89,6 +111,23 @@ export default class Reloader { this.updateFiles(); } + private getKey(item: IFileMapItem): string { + if (typeof item === 'string') { + return item; + } + else if (item) { + return item.key; + } + return ''; + } + + private getParents(item: IFileMapItem): string[] { + if (typeof item === 'object' && item.parents) { + return item.parents; + } + return []; + } + private updateFiles() { this.files = Object.keys(this.fileMap); } diff --git a/test/fixtures/mainModule.js b/test/fixtures/mainModule.js index f34c2c4..b758248 100644 --- a/test/fixtures/mainModule.js +++ b/test/fixtures/mainModule.js @@ -1,2 +1,2 @@ require('./mod1'); -require('./mod2'); \ No newline at end of file +require('./mod2'); diff --git a/test/fixtures/mod2.js b/test/fixtures/mod2.js index 51bc090..0fc3f8c 100644 --- a/test/fixtures/mod2.js +++ b/test/fixtures/mod2.js @@ -1,3 +1,4 @@ +require('./mod3'); module.exports = { num: 2, }; diff --git a/test/fixtures/mod3.js b/test/fixtures/mod3.js new file mode 100644 index 0000000..c131ecd --- /dev/null +++ b/test/fixtures/mod3.js @@ -0,0 +1,3 @@ +module.exports = { + num: 3, +}; diff --git a/test/index.test.ts b/test/index.test.ts index 8d3af70..657f6be 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -6,12 +6,28 @@ import {resolve} from 'path'; import Reloader from '../src/index'; import {expect} from 'chai'; +import batchdelcache from 'batchdelcache'; +// import {symlinkSync, existsSync} from 'fs'; /** * Dummy test */ describe('Reloader test', () => { + // before(() => { + // const lnPath = resolve(__dirname, './fixtures/lns.js'); + // if (!existsSync(lnPath)) { + // symlinkSync( + // resolve(__dirname, './fixtures/mod3.js'), + // lnPath + // ); + // } + // }); + + afterEach(() => { + batchdelcache(['./fixtures/mainModule.js']); + }); + it('reload success', () => { require('./fixtures/mainModule'); @@ -46,5 +62,44 @@ describe('Reloader test', () => { expect(require('./fixtures/mod2').num).to.be.equal(2); }); + it('reload success', () => { + require('./fixtures/mainModule'); + + const reloader = new Reloader({ + fileMap: { + mod3: { + key: '2', + parents: [ + 'mod2.js' + ] + }, + }, + context: resolve(__dirname, './fixtures'), + commonRootPath: resolve(__dirname, './fixtures/mainModule.js'), + }); + + require('./fixtures/mod2').num++; + require('./fixtures/mod3').num++; + + expect(require('./fixtures/mod2').num).to.be.equal(3); + expect(require('./fixtures/mod3').num).to.be.equal(4); + + let {errors, reloadModules} = reloader.reload({ + mod3: { + key: '3', + parents: [ + 'mod2.js' + ] + }, + }); + + expect(errors.length).to.be.equal(0); + expect(reloadModules.length).to.be.equal(1); + expect(reloadModules.includes(resolve(__dirname, './fixtures/mod2.js'))).to.be.equal(true); + expect(require('./fixtures/mod2').num).to.be.equal(2); + expect(require('./fixtures/mod3').num).to.be.equal(3); + + }); + });