How to import a module if it exists ?
I have 2 projects, client & server. Both import one same file.
The file imports a node module which is only installed in the server project. The client doesn't have the module.
So the require must return the module typed when opened from the server project.
And it must return undefined
when opened from the client project.
Below an screenshot from the client project. Typescript doesn't compile because it says it cannot find the module.
A simple require
doesn't keep the type:
There are 2 parts to this:
import
means the module must always exist. That doesn't mean it has to be the module you actually need.module | undefined
on the server side. But on the client side module
is unknowable. So to allow for server based calls, we should allow any fields to be used, like {[k:string]:any}
, and we need to be able to select which one is appropriate for the side we are on.So your best bet is probably to add an empty module of the same name to your client side, so a file called type-graphql.ts
in the node_modules
folder on the client side that only contains:
export {}
This way the unconditional import will always work, client will import this empty module file and server will import the actual library. Then you just need to re-assign the variable to consider possible interfaces:
import * as _TypeGraphQL from 'type-graphql';
// don't check methods on the client side, if we had type definitions on both we could just use that
type CLIENT_SIDE_INTERFACE = {[k:string]:any};
// on server side we can check for case that the module is not present.
type SERVER_SIDE_INTERFACE = typeof _TypeGraphQL | {"ISDUMMY":true}
// if the imported module has our indicator key then we are on the client side
type THIS_SIDE_INTERFACE = "ISDUMMY" extends (keyof typeof _TypeGraphQL) ? CLIENT_SIDE_INTERFACE : SERVER_SIDE_INTERFACE
const TypeGraphQL: THIS_SIDE_INTERFACE = _TypeGraphQL;
After having it pointed out that putting files in the normal node_modules
folder is problematic, I can offer a possible solution to this as well.
Node resolves modules (that don't start with ./
or /
) by walking up the folder tree from the current file, each level seeing if there is a folder called node_modules
. Normally this means in the root of your project there is one folder containing all the modules. However you can add another folder in the middle of your project called node_modules
and any imports by files there will search that folder first.
So for a folder structure like this would let you put the dummy file in the project in a way that import * as a from 'test-graphql'
will import from a stable folder:
root
- node_modules
- src
--- SUBFOLDERS
- node_modules
-test-graphql.tsx (dummy code)
- git-sub-module
- wrapper.tsx (containing the import code mentioned above)
Code in the wrapper.tsx
in this case would try to import from the inner node_modules
importing the empty module file.
Just make sure you add sufficient comments in the empty module explaining what sorcery is going on :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With