diff --git a/README.md b/README.md index e89b124..844ac87 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ directoryImport('./sample-directory', (moduleName, modulePath, moduleData) => { | importPattern | RegExp | RegExp pattern to filter files | | importMode | String | The import mode. Can be 'sync' or 'async' | | limit | Number | Limit the number of imported modules | +| forceReload | Boolean | If true, reload modules disabling require cache | [back to top](#top) @@ -335,6 +336,11 @@ directoryImport(options, (moduleName, modulePath, moduleData) => { ## Change Log +### [3.3.2] - 2024-12-25 + +#### Added +- Add forceReload option. + ### [3.3.1] - 2024-03-27 #### Fixed diff --git a/package-lock.json b/package-lock.json index d3d9e70..e91cbe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "directory-import", - "version": "3.2.1", + "version": "3.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "directory-import", - "version": "3.2.1", + "version": "3.3.2", "license": "ISC", "devDependencies": { "@types/jest": "^29.5.8", @@ -29,7 +29,6 @@ "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-sonarjs": "^0.23.0", "eslint-plugin-unicorn": "^49.0.0", - "husky": "^8.0.3", "jest": "^29.7.0", "prettier": "^3.1.0", "ts-jest": "^29.1.1", @@ -5838,21 +5837,6 @@ "node": ">=10.17.0" } }, - "node_modules/husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", diff --git a/package.json b/package.json index 281ac3a..2e1f4b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "directory-import", - "version": "3.3.1", + "version": "3.3.2", "description": "Module will allow you to synchronously or asynchronously import (requires) all modules from the folder you specify", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -10,7 +10,8 @@ "scripts": { "build": "rimraf ./dist && tsup", "start": "node dist/index.js", - "publish": "npm run build && npm publish", + "prepare": "npm run build", + "publish": "npm run prepare && npm publish", "jest": "jest --silent test/index.test.ts", "jest:watcher": "jest --watchAll", "jest:windows": "jest --silent test-windows/index.test.ts" @@ -59,11 +60,10 @@ "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-sonarjs": "^0.23.0", "eslint-plugin-unicorn": "^49.0.0", - "husky": "^8.0.3", "jest": "^29.7.0", "prettier": "^3.1.0", "ts-jest": "^29.1.1", "tsup": "^8.0.2", "typescript": "^5.2.2" } -} \ No newline at end of file +} diff --git a/src/import-modules.ts b/src/import-modules.ts index 23f1067..edb6738 100644 --- a/src/import-modules.ts +++ b/src/import-modules.ts @@ -77,6 +77,11 @@ function importModule( const relativeModulePath = filePath.slice(options.targetDirectoryPath.length); + if (options.forceReload) { + // eslint-disable-next-line security/detect-non-literal-require, @typescript-eslint/no-var-requires, unicorn/prefer-module + delete require.cache[filePath]; + } + // eslint-disable-next-line security/detect-non-literal-require, @typescript-eslint/no-var-requires, unicorn/prefer-module const importedModule = require(filePath) as unknown; diff --git a/src/prepare-private-options.ts b/src/prepare-private-options.ts index d3a2c97..1883cc2 100644 --- a/src/prepare-private-options.ts +++ b/src/prepare-private-options.ts @@ -16,6 +16,7 @@ const getDefaultOptions = (): ImportedModulesPrivateOptions => { callerFilePath: path.resolve('/'), callerDirectoryPath: path.resolve('/'), targetDirectoryPath: path.resolve('/'), + forceReload: false, }; options.callerFilePath = diff --git a/src/types.d.ts b/src/types.d.ts index 0e5ebff..0d44ff4 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -22,6 +22,7 @@ export interface ImportedModulesPublicOptions { importPattern?: RegExp; importMode?: ImportModulesMode; limit?: number; + forceReload?: boolean; } export interface ImportedModulesPrivateOptions extends Required { diff --git a/test/index.test.ts b/test/index.test.ts index 26a0789..a64325d 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -6,6 +6,7 @@ import { DEFAULT_EXPECTED_RESULT_FROM_SAMPLE_DIRECTORY, DEFAULT_RELATIVE_PATH_TO_SAMPLE_DIRECTORY, } from './constants'; +import fs from 'fs'; test('Import modules from the default (current) directory synchronously', () => { const result = directoryImport(); @@ -221,3 +222,44 @@ test('Import modules with specified options and call the provided callback for e expect(result).toEqual(DEFAULT_EXPECTED_RESULT_FROM_SAMPLE_DIRECTORY); expect(callbackResults).toEqual(DEFAULT_EXPECTED_CALLBACK_RESULTS_FROM_SAMPLE_DIRECTORY); }); + +test('Import modules with cache', () => { + const result = directoryImport(DEFAULT_RELATIVE_PATH_TO_SAMPLE_DIRECTORY) + + expect(result).toEqual(DEFAULT_EXPECTED_RESULT_FROM_SAMPLE_DIRECTORY); + + // change the content of sample-file-2.js + fs.writeFileSync(`${DEFAULT_ABSOLUTE_PATH_TO_SAMPLE_DIRECTORY}/sample-file-2.js`, "// eslint-disable-next-line unicorn/no-empty-file, no-undef, unicorn/prefer-module\nmodule.exports = { testData: 'Hello World Changed!' };\n"); + + // re-import the modules + const result2 = directoryImport({ + targetDirectoryPath: DEFAULT_RELATIVE_PATH_TO_SAMPLE_DIRECTORY, + forceReload: false, + }); + + expect(result2).toEqual(DEFAULT_EXPECTED_RESULT_FROM_SAMPLE_DIRECTORY); + // revert the content of sample-file-2.js + fs.writeFileSync(`${DEFAULT_ABSOLUTE_PATH_TO_SAMPLE_DIRECTORY}/sample-file-2.js`, "// eslint-disable-next-line unicorn/no-empty-file, no-undef, unicorn/prefer-module\nmodule.exports = { testData: 'Hello World!' };\n"); +}); + +test('Import modules without cache', () => { + const result = directoryImport(DEFAULT_RELATIVE_PATH_TO_SAMPLE_DIRECTORY) + + expect(result).toEqual(DEFAULT_EXPECTED_RESULT_FROM_SAMPLE_DIRECTORY); + + // change the content of sample-file-2.js + fs.writeFileSync(`${DEFAULT_ABSOLUTE_PATH_TO_SAMPLE_DIRECTORY}/sample-file-2.js`, "// eslint-disable-next-line unicorn/no-empty-file, no-undef, unicorn/prefer-module\nmodule.exports = { testData: 'Hello World Changed!' };\n"); + + jest.resetModules(); + + // re-import the modules + const result2 = directoryImport({ + targetDirectoryPath: DEFAULT_RELATIVE_PATH_TO_SAMPLE_DIRECTORY, + forceReload: true, + }); + + expect(result2['/sample-file-2.js']).toEqual({ testData: 'Hello World Changed!' }); + + // revert the content of sample-file-2.js + fs.writeFileSync(`${DEFAULT_ABSOLUTE_PATH_TO_SAMPLE_DIRECTORY}/sample-file-2.js`, "// eslint-disable-next-line unicorn/no-empty-file, no-undef, unicorn/prefer-module\nmodule.exports = { testData: 'Hello World!' };\n"); +}); \ No newline at end of file