Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opts.glob is not a function #381

Closed
FOZERY opened this issue Oct 22, 2024 · 7 comments · Fixed by #382
Closed

opts.glob is not a function #381

FOZERY opened this issue Oct 22, 2024 · 7 comments · Fixed by #382

Comments

@FOZERY
Copy link

FOZERY commented Oct 22, 2024

I can't use loadModules with TypeScript because it throws the next error

    const result = opts.glob(globPattern, { cwd: opts.cwd });
                        ^

TypeError: opts.glob is not a function
    at _listModules (file:///D:/projects/sdp/node_modules/awilix/lib/awilix.module.mjs:577:25)
    at file:///D:/projects/sdp/node_modules/awilix/lib/awilix.module.mjs:602:48
    at Array.map (<anonymous>)
    at Object.listModules (file:///D:/projects/sdp/node_modules/awilix/lib/awilix.module.mjs:602:37)
    at loadModules (file:///D:/projects/sdp/node_modules/awilix/lib/awilix.module.mjs:1107:34)
    at Object.loadModules$1 [as loadModules] (file:///D:/projects/sdp/node_modules/awilix/lib/awilix.module.mjs:1634:13)
    at <anonymous> (D:\projects\sdp\src\index.ts:13:11)
    at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)

Node.js v20.16.0

awilix.module.mjs uses next imports:

import { camelCase } from 'camel-case';
import * as glob from 'fast-glob';
import * as path from 'path';
import { pathToFileURL } from 'url';
import * as util from 'util';
import { importModule } from './load-module-native.js';

However, the fast-glob and other modules have a namespace for export:

declare namespace FastGlob {
    type Options = OptionsInternal;
    type Entry = EntryInternal;
    type Task = taskManager.Task;
    type Pattern = PatternInternal;
    type FileSystemAdapter = FileSystemAdapterInternal;
    const glob: typeof FastGlob;
    const globSync: typeof sync;
    const globStream: typeof stream;
    const async: typeof FastGlob;
    function sync(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): EntryInternal[];
    function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): string[];
    function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream;
    function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[];
    function isDynamicPattern(source: PatternInternal, options?: OptionsInternal): boolean;
    function escapePath(source: string): PatternInternal;
    function convertPathToPattern(source: string): PatternInternal;
    namespace posix {
        function escapePath(source: string): PatternInternal;
        function convertPathToPattern(source: string): PatternInternal;
    }
    namespace win32 {
        function escapePath(source: string): PatternInternal;
        function convertPathToPattern(source: string): PatternInternal;
    }
}
export = FastGlob;

So, if we change the import statement from import * as glob from 'fast-glob' to import glob from 'fast-glob', everything should work correctly.

@jeffijoe
Copy link
Owner

If you set skipLibCheck: true in your tsconfig that will also resolve it. There's no point in checking library code.

@FOZERY
Copy link
Author

FOZERY commented Oct 22, 2024

I have next tsconfig

{ 
	"include": ["src/**/*.ts"],  
	"exclude": ["**/*.test.*", "**/__mocks__/*", "**/__tests__/*", "node_modules"],
	"compilerOptions": {
	  "target": "ESNext",
	  "module": "NodeNext", 
	  "moduleResolution": "NodeNext",  
	  "esModuleInterop": true, 
	  "declaration": true, 
	  "removeComments": true, 
	  "emitDecoratorMetadata": true,
	  "experimentalDecorators": true,
	  "allowSyntheticDefaultImports": false,
	  "sourceMap": true,
	  "outDir": "./build", 
	  "baseUrl": "./",   
	  "paths": { 
		"app/*": ["./src/app/*"] 
	  },  
	  "incremental": true,
	  "skipLibCheck": true,  
	  "noImplicitAny": true,  
	  "strictBindCallApply": true,
	  "forceConsistentCasingInFileNames": false,
	  "noFallthroughCasesInSwitch": true
	}
}

So, it doesn't work with the type: "module" and ESModules in Node.js. I have the same problem with ESModules, but CommonJS works fine.

I think this is due to the import of the fast-glob library.

@jeffijoe
Copy link
Owner

Can you create a small repro repository so I can debug this?

@FOZERY
Copy link
Author

FOZERY commented Oct 23, 2024

I'm sorry, I won't be able to create the repository for about 9 hours.

It also doesn't work with plain nodejs and esm modules.

Can you check this import in awilix.module.mjs?

import * as glob from 'fast-glob';

Update this import to default import resolve the problem

import glob from 'fast-glob'

@jeffijoe
Copy link
Owner

jeffijoe commented Oct 23, 2024

I've released an alpha build for you to try, please let me know if this works: [email protected]

@FOZERY
Copy link
Author

FOZERY commented Oct 23, 2024

Yes, everything is good. Can you also tell me how to use loadModules in TypeScript? What should I put in the glob paths? Compiled js files?

@jeffijoe
Copy link
Owner

That depends on your development and production setup. If you're using a module loader that supports ts files, you could use a .{ts|js} suffix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants