From 691263cbdb407c760adf69e41a57dc124371beaf Mon Sep 17 00:00:00 2001 From: dazinator Date: Mon, 10 Dec 2018 14:08:50 +0000 Subject: [PATCH 1/7] Added support for running tests in vscode. --- .vscode/launch.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..40a0c50 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run mocha", + "type": "node", + "request": "launch", + "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", + "stopOnEntry": false, + "args": [ + "test/test.js", + "--no-timeouts" + ], + "sourceMaps": true, + "cwd": "${workspaceRoot}", + "runtimeExecutable": null, + "env": { + "NODE_ENV": "testing" + } + } + ] +} \ No newline at end of file From cf89ca51fa1bcac0af03d715a7100a060124f28d Mon Sep 17 00:00:00 2001 From: dazinator Date: Mon, 10 Dec 2018 15:19:44 +0000 Subject: [PATCH 2/7] Typescript resolver honours alternate fs. --- index.js | 20 ++++++++++++++++---- package-lock.json | 39 +++++++++++++++++++++++++++++++++++++++ package.json | 4 +++- test/mockedJSFiles.js | 2 +- test/test.js | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 93 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 88f7b4b..dcd86e7 100644 --- a/index.js +++ b/index.js @@ -45,6 +45,7 @@ const defaultLookups = { * @param {String} [options.webpackConfig] Path to the webpack config * @param {Object} [options.ast] A preparsed AST for the file identified by filename. * @param {Object} [options.tsconfig] Path to a typescript config file + * @param {Object} [options.fileSystem] An alternative filesystem / fs implementation to use for locating files. */ module.exports = function cabinet(options) { const { @@ -173,7 +174,7 @@ function jsLookup({dependency, filename, directory, config, webpackConfig, confi } } -function tsLookup({dependency, filename, tsConfig}) { +function tsLookup({dependency, filename, tsConfig, fileSystem}) { debug('performing a typescript lookup'); const defaultTsConfig = { @@ -186,15 +187,16 @@ function tsLookup({dependency, filename, tsConfig}) { debug('given typescript config: ', tsConfig); + var fileSystem = fileSystem || fs; + if (!tsConfig) { tsConfig = defaultTsConfig; debug('no tsconfig given, defaulting'); } else if (typeof tsConfig === 'string') { debug('string tsconfig given, parsing'); - try { - tsConfig = JSON.parse(fs.readFileSync(tsConfig, 'utf8')); + tsConfig = JSON.parse(fileSystem.readFileSync(tsConfig, 'utf8')); debug('successfully parsed tsconfig'); } catch (e) { debug('could not parse tsconfig'); @@ -212,7 +214,17 @@ function tsLookup({dependency, filename, tsConfig}) { options.module = ts.ModuleKind.AMD; } - const host = ts.createCompilerHost({}); + var host = ts.createCompilerHost({}); + + // Override host methods, to support finding files in provided fs. + const isDirectory = dirPath => fileSystem.lstatSync(dirPath).isDirectory(); + const getDirectories = dirPath => fileSystem.readdirSync(dirPath).map(name => path.join(dirPath, name)).filter(isDirectory); + const pathExists = filePath => fileSystem.existsSync(filePath); + + host.getDirectories = getDirectories; + host.fileExists = pathExists; + host.directoryExists = pathExists; + debug('with options: ', options); const resolvedModule = ts.resolveModuleName(dependency, filename, options, host).resolvedModule; debug('ts resolved module: ', resolvedModule); diff --git a/package-lock.json b/package-lock.json index 9a8ba46..ec90524 100644 --- a/package-lock.json +++ b/package-lock.json @@ -783,6 +783,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-extend": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/fast-extend/-/fast-extend-0.0.2.tgz", + "integrity": "sha1-9exCz0C5Rg9SGmOH37Ut7u1nHb0=", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -858,6 +864,12 @@ "universalify": "^0.1.0" } }, + "fs-monkey": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-0.2.2.tgz", + "integrity": "sha512-iGmwUuLYN6COLpwBqs9RfBREWkMbbRC7Xj+tsqcW/iaRI7KmUcjnScDLJxSIJo4DM85w76fdVWgagQHzClA0WA==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1407,6 +1419,24 @@ "yallist": "^2.1.2" } }, + "memfs": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-2.14.1.tgz", + "integrity": "sha512-lTts32q0cfwIZ7MHK3GjGcpGhp5Nj4LXtc6njEjFj5wQHNNdOYVN/JXeW7PpExa11c6QW+mDPSRuB6EWnoiDMQ==", + "dev": true, + "requires": { + "fast-extend": "0.0.2", + "fs-monkey": "^0.3.3" + }, + "dependencies": { + "fs-monkey": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-0.3.3.tgz", + "integrity": "sha512-FNUvuTAJ3CqCQb5ELn+qCbGR/Zllhf2HtwsdAtBi59s1WeCjKMT81fHcSu7dwIskqGVK+MmOrb7VOBlq3/SItw==", + "dev": true + } + } + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -2621,6 +2651,15 @@ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", "dev": true }, + "unionfs": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unionfs/-/unionfs-3.0.2.tgz", + "integrity": "sha512-PmPNhDthSs60NkvZOj9vUKGacNgZWXpimw5tkqNzNA5Aoan114ISjTnkBxii36b3upQQPKCflz55vQQMQ6z8WQ==", + "dev": true, + "requires": { + "fs-monkey": "^0.2.2" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/package.json b/package.json index eb1a146..ddc6c1b 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,9 @@ "mocha": "^5.0.0", "mock-fs": "^4.4.2", "rewire": "^4.0.1", - "sinon": "^4.1.6" + "sinon": "^4.1.6", + "unionfs": "^3.0.2", + "memfs": "^2.14.1" }, "dependencies": { "app-module-path": "^2.2.0", diff --git a/test/mockedJSFiles.js b/test/mockedJSFiles.js index 654af31..e06befd 100644 --- a/test/mockedJSFiles.js +++ b/test/mockedJSFiles.js @@ -12,7 +12,7 @@ module.exports = { 'ts': { 'index.ts': 'import foo from "./foo";', 'foo.ts': 'export default 1;', - '.tsconfig': '{ "version": "1.0.0", "compilerOptions": { "module": "commonjs" } }' + '.tsconfig': '{ "version": "1.0.0", "compilerOptions": { "module": "commonjs" } }', }, 'amd': { 'foo.js': 'define(["./bar"], function(bar){ return bar; });', diff --git a/test/test.js b/test/test.js index a384e62..562c6ae 100644 --- a/test/test.js +++ b/test/test.js @@ -369,6 +369,31 @@ describe('filing-cabinet', function() { ); }); + it('resolves an import using an alternative fs', function() { + mock.restore(); + const volumeDir = 'app'; + const filename = volumeDir + '/index.ts'; + + const unionfs = require('unionfs'); + const memfs = require('memfs'); + + // mount files specified by "mockedFiles.js.ts" to "app" base directory. + var vol = memfs.Volume.fromJSON(mockedFiles.js.ts, `${volumeDir}`); + var ufs = unionfs.ufs.use(vol); + + const result = cabinet({ + partial: './foo', + filename, + directory, + fileSystem: ufs + }); + //directory + assert.equal( + result, + path.join(path.resolve('app'), 'foo.ts') + ); + }); + describe('when a partial does not exist', function() { it('returns an empty result', function() { const filename = directory + '/index.ts'; @@ -390,7 +415,9 @@ describe('filing-cabinet', function() { ModuleKind: { AMD: 'amd' }, - createCompilerHost: sinon.stub(), + createCompilerHost: sinon.stub().returns({ + getDirectories: null + }), resolveModuleName: sinon.stub().returns({ resolvedModule: '' }), @@ -424,7 +451,9 @@ describe('filing-cabinet', function() { ModuleKind: { AMD: 'amd' }, - createCompilerHost: sinon.stub(), + createCompilerHost: sinon.stub().returns({ + getDirectories: null + }), resolveModuleName: sinon.stub().returns({ resolvedModule: '' }), @@ -456,7 +485,9 @@ describe('filing-cabinet', function() { ModuleKind: { AMD: 'amd' }, - createCompilerHost: sinon.stub(), + createCompilerHost: sinon.stub().returns({ + getDirectories: null + }), resolveModuleName: sinon.stub().returns({ resolvedModule: '' }), From 259b6f93550a1a5bdae8106874d0b22b64ef9542 Mon Sep 17 00:00:00 2001 From: Darrell Tunnell Date: Mon, 18 Mar 2019 00:23:15 +0000 Subject: [PATCH 3/7] #65 - CommonJS Lookup supports alternative fs. --- .vscode/launch.json | 1 + index.js | 33 ++++++++++++++++++++++++--------- package.json | 2 +- test/test.js | 27 ++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 40a0c50..7197efc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,7 @@ { "version": "0.2.0", "configurations": [ + { "name": "Run mocha", "type": "node", diff --git a/index.js b/index.js index f41b08e..140a742 100644 --- a/index.js +++ b/index.js @@ -54,6 +54,7 @@ module.exports = function cabinet(options) { filename, } = options; + options.fileSystem = options.fileSystem || fs; debug('Given filename: ' + filename); const ext = path.extname(filename); @@ -124,7 +125,9 @@ module.exports._getJSType = function(options = {}) { } debug('using the filename to find the module type'); - return getModuleType.sync(options.filename); + // options.fileSystem will be supported after `module-definition` depedendency has this PR merged and is then consumed in package.json: + // https://github.com/dependents/module-definition/pull/28 + return getModuleType.sync(options.filename, options.fileSystem); }; /** @@ -138,14 +141,16 @@ module.exports._getJSType = function(options = {}) { * @param {String} [options.configPath] * @param {Object} [options.nodeModulesConfig] * @param {Object} [options.ast] + * @param {Object} [options.fileSystem] * @return {String} */ -function jsLookup({dependency, filename, directory, config, webpackConfig, configPath, nodeModulesConfig, ast}) { +function jsLookup({dependency, filename, directory, config, webpackConfig, configPath, nodeModulesConfig, ast, fileSystem}) { const type = module.exports._getJSType({ config: config, webpackConfig: webpackConfig, filename: filename, - ast: ast + ast: ast, + fileSystem: fileSystem }); switch (type) { @@ -166,7 +171,7 @@ function jsLookup({dependency, filename, directory, config, webpackConfig, confi case 'commonjs': debug('using commonjs resolver'); - return commonJSLookup({dependency, filename, directory, nodeModulesConfig}); + return commonJSLookup({dependency, filename, directory, nodeModulesConfig, fileSystem}); case 'webpack': debug('using webpack resolver for es6'); @@ -175,7 +180,7 @@ function jsLookup({dependency, filename, directory, config, webpackConfig, confi case 'es6': default: debug('using commonjs resolver for es6'); - return commonJSLookup({dependency, filename, directory, nodeModulesConfig}); + return commonJSLookup({dependency, filename, directory, nodeModulesConfig, fileSystem}); } } @@ -192,8 +197,6 @@ function tsLookup({dependency, filename, tsConfig, fileSystem}) { debug('given typescript config: ', tsConfig); - var fileSystem = fileSystem || fs; - if (!tsConfig) { tsConfig = defaultTsConfig; debug('no tsconfig given, defaulting'); @@ -250,7 +253,7 @@ function tsLookup({dependency, filename, tsConfig, fileSystem}) { return result ? path.resolve(result) : ''; } -function commonJSLookup({dependency, filename, directory, nodeModulesConfig}) { +function commonJSLookup({dependency, filename, directory, nodeModulesConfig, fileSystem}) { if (!resolve) { resolve = require('resolve'); } @@ -287,7 +290,19 @@ function commonJSLookup({dependency, filename, directory, nodeModulesConfig}) { basedir: directory, packageFilter: nodeModulesConfig && nodeModulesConfig.entry ? packageFilter : undefined, // Add fileDir to resolve index.js files in that dir - moduleDirectory: ['node_modules', directory] + moduleDirectory: ['node_modules', directory], + readFile: fileSystem.readFile, + isFile: function isFile(file) { + try { + var stat = fileSystem.statSync(file); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')){ + return false; + } + throw e; + } + return stat.isFile() || stat.isFIFO(); + } }); debug('resolved path: ' + result); } catch (e) { diff --git a/package.json b/package.json index 3f709a5..9c342ae 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "is-relative-path": "^1.0.2", "module-definition": "^3.0.0", "module-lookup-amd": "^6.1.0", - "resolve": "^1.9.0", + "resolve": "^1.10.0", "resolve-dependency-path": "^2.0.0", "sass-lookup": "^3.0.0", "stylus-lookup": "^3.0.1", diff --git a/test/test.js b/test/test.js index 352e1b7..21ea157 100644 --- a/test/test.js +++ b/test/test.js @@ -405,7 +405,7 @@ describe('filing-cabinet', function() { ); }); - it('resolves an import using an alternative fs', function() { + it('resolves a .ts import using an alternative fs', function() { mock.restore(); const volumeDir = 'app'; const filename = volumeDir + '/index.ts'; @@ -430,6 +430,31 @@ describe('filing-cabinet', function() { ); }); + it('resolves a commonjs import using an alternative fs', function() { + mock.restore(); + const volumeDir = 'commonjs'; + const filename = volumeDir + '/index.js'; + + const unionfs = require('unionfs'); + const memfs = require('memfs'); + + // mount files specified by "mockedFiles.js.ts" to "app" base directory. + var vol = memfs.Volume.fromJSON(mockedFiles.js.commonjs, `${volumeDir}`); + var ufs = unionfs.ufs.use(vol); + + const result = cabinet({ + partial: './bar', + filename, + directory, + fileSystem: ufs + }); + //directory + assert.equal( + result, + path.join(path.resolve('app'), 'foo.ts') + ); + }); + it('resolves the import within a tsx file', function() { const filename = directory + '/module.tsx'; const result = cabinet({ From 9445a422e83c1646ea9e4bd03177c24b629532fb Mon Sep 17 00:00:00 2001 From: Darrell Tunnell Date: Mon, 18 Mar 2019 20:45:48 +0000 Subject: [PATCH 4/7] #65 - Update module-definition dependency. Tests passing. --- index.js | 2 +- package.json | 2 +- test/test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 140a742..773101e 100644 --- a/index.js +++ b/index.js @@ -127,7 +127,7 @@ module.exports._getJSType = function(options = {}) { debug('using the filename to find the module type'); // options.fileSystem will be supported after `module-definition` depedendency has this PR merged and is then consumed in package.json: // https://github.com/dependents/module-definition/pull/28 - return getModuleType.sync(options.filename, options.fileSystem); + return getModuleType.sync(options.filename, options); }; /** diff --git a/package.json b/package.json index 9c342ae..b9125d9 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "debug": "^4.1.1", "enhanced-resolve": "^4.1.0", "is-relative-path": "^1.0.2", - "module-definition": "^3.0.0", + "module-definition": "^3.2.0", "module-lookup-amd": "^6.1.0", "resolve": "^1.10.0", "resolve-dependency-path": "^2.0.0", diff --git a/test/test.js b/test/test.js index 21ea157..f12a29a 100644 --- a/test/test.js +++ b/test/test.js @@ -451,7 +451,7 @@ describe('filing-cabinet', function() { //directory assert.equal( result, - path.join(path.resolve('app'), 'foo.ts') + path.join(path.resolve('commonjs'), 'bar.js') ); }); From c7f7a62ba88de9daf06f4d02a13d356c42e080c8 Mon Sep 17 00:00:00 2001 From: Darrell Tunnell Date: Mon, 18 Mar 2019 21:58:59 +0000 Subject: [PATCH 5/7] Added test for amd resolver and alternate fs. - This won't pass until https://github.com/dependents/node-module-lookup-amd/pull/26 is merged and node-module-lookup dep is updated --- index.js | 3 ++- test/mockedJSFiles.js | 3 ++- test/test.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 773101e..dedd914 100644 --- a/index.js +++ b/index.js @@ -166,7 +166,8 @@ function jsLookup({dependency, filename, directory, config, webpackConfig, confi configPath: configPath, partial: dependency, directory: directory, - filename: filename + filename: filename, + fileSystem: fileSystem }); case 'commonjs': diff --git a/test/mockedJSFiles.js b/test/mockedJSFiles.js index 5c1f95f..16c8d06 100644 --- a/test/mockedJSFiles.js +++ b/test/mockedJSFiles.js @@ -24,7 +24,8 @@ module.exports = { }, 'amd': { 'foo.js': 'define(["./bar"], function(bar){ return bar; });', - 'bar.js': 'define({});' + 'bar.js': 'define({});', + 'config.js': '{};' }, 'commonjs': { 'foo.js': 'var bar = require("./bar");', diff --git a/test/test.js b/test/test.js index f12a29a..f8cad7a 100644 --- a/test/test.js +++ b/test/test.js @@ -207,6 +207,35 @@ describe('filing-cabinet', function() { revert(); }); + it('uses the amd resolver with alternative fs', function() { + mock.restore(); + const volumeDir = 'app'; + const unionfs = require('unionfs'); + const memfs = require('memfs'); + + // mount files specified by "mockedFiles.js.ts" to "app" base directory. + var vol = memfs.Volume.fromJSON(mockedFiles.js.es6, `${volumeDir}`); + var ufs = unionfs.ufs.use(vol); + const result = cabinet({ + partial: './bar', + filename: 'app/foo.js', + directory: 'app', + config: { + baseUrl: './' + } + }); + + // var result = cabinet({ + // partial: './bar', + // configPath: 'amd/config.js', + // filename: 'amd/foo.js', + // fileSystem: ufs + // }); + + assert.equal(result, `${path.join(__dirname, 'amd/bar.js')}`); + + }); + it('passes along arguments', function() { const stub = sinon.stub(); const revert = cabinet.__set__('amdLookup', stub); From 1de6e05f2a2f8b2535b1c042218b3df71a48b202 Mon Sep 17 00:00:00 2001 From: Darrell Tunnell Date: Tue, 19 Mar 2019 14:45:33 +0000 Subject: [PATCH 6/7] #65 - Amd Resolver test passing with aternative fs. --- package.json | 2 +- test/test.js | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index b9125d9..f03ddb2 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "enhanced-resolve": "^4.1.0", "is-relative-path": "^1.0.2", "module-definition": "^3.2.0", - "module-lookup-amd": "^6.1.0", + "module-lookup-amd": "^6.2.0", "resolve": "^1.10.0", "resolve-dependency-path": "^2.0.0", "sass-lookup": "^3.0.0", diff --git a/test/test.js b/test/test.js index f8cad7a..c1e6327 100644 --- a/test/test.js +++ b/test/test.js @@ -213,26 +213,19 @@ describe('filing-cabinet', function() { const unionfs = require('unionfs'); const memfs = require('memfs'); - // mount files specified by "mockedFiles.js.ts" to "app" base directory. - var vol = memfs.Volume.fromJSON(mockedFiles.js.es6, `${volumeDir}`); + // mount files specified by "mockedFiles.js.amd" to "app" base directory. + var vol = memfs.Volume.fromJSON(mockedFiles.js.amd, `${volumeDir}`); var ufs = unionfs.ufs.use(vol); const result = cabinet({ partial: './bar', filename: 'app/foo.js', - directory: 'app', - config: { - baseUrl: './' - } + directory: '', + fileSystem: ufs, + configPath: 'app/config.js' }); - // var result = cabinet({ - // partial: './bar', - // configPath: 'amd/config.js', - // filename: 'amd/foo.js', - // fileSystem: ufs - // }); - - assert.equal(result, `${path.join(__dirname, 'amd/bar.js')}`); + var expected = path.normalize('app/bar.js'); + assert.equal(result, expected); }); From 45e9b75bf7514f59e718a5a279381a04e8a66929 Mon Sep 17 00:00:00 2001 From: Darrell Tunnell Date: Tue, 19 Mar 2019 15:12:54 +0000 Subject: [PATCH 7/7] Fixed jscs code style issues. --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index dedd914..acaf4eb 100644 --- a/index.js +++ b/index.js @@ -297,13 +297,13 @@ function commonJSLookup({dependency, filename, directory, nodeModulesConfig, fil try { var stat = fileSystem.statSync(file); } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')){ + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) { return false; } throw e; } return stat.isFile() || stat.isFIFO(); - } + } }); debug('resolved path: ' + result); } catch (e) {