Rethinking the way we handle dependency imports in deno
Tags: deno, javascript, typescript
Published: 2020-08-17 05:20:58

I've been using deno for a while and I must say I love it, using typescript without compiling it first, using import / export instead of require and the other facilities that deno allows, I love it.

One of the main premises is the non-use of a package manager, since as in a browser you can import locally or from a url, this is a total paradigm shift with respect to nodejs, This has its advantages, since packages and dependencies can be imported literally from anywhere, which fulfills the role of decentralizing the location of the dependencies, now here I want to share some of the disadvantages that the use of urls entails.

using packages in deno is very simple, just import the library or package.

```typescript

import {/* ... */} from "https://deno.land/std@0.65.0/fs/mod.ts";

```

So far so good, but let's say that now we have 50 files that import from the fs package, here it becomes a bit complicated since if we want to update to another version of the package we would have to go to each of the 50 files to change the url. a solution for this that deno offers is to use [import maps](https://deno.land/manual/linking_to_external_code/import_maps), which is a way of giving name aliases to urls in order to shorten and reuse the package.

then it would look like this.

`import_map.json`
```json
{
  "imports": {
    "fs/": "https://deno.land/std@0.65.0/fs/"
  }
}
```

`example file`

```typescript

import {/* ... */} from "fs/mod.ts";

```
much better now, we can use the packages in all the files we want and we just have to update them in one place in the `import_map.json`. actually create a command line tool for deno that wraps all this functionality and creates an experience similar to npm when searching and installing packages [(Trex).](https://github.com/crewdevio/Trex)

But with import maps there are some disadvantages, they cannot be used in packages that are distributed, and also they are still under the unstable flag since as it is not yet a web standard there is much doubt if it deno will continue to support import maps.

Another solution that they recommend and I think is the most used is to use a single `deps.ts` file where all the imports are and from this import everything.

then it would be something like this.

`deps.ts`

```typescript
export * from "https://deno.land/std@0.65.0/fs/mod.ts";
```

`example file`

```typescript

import {/* ... */} from "./deps.ts";

```
here comes the problems of using `deps.ts`, I have these two imports.

```typescript

import { Application } from "./deps.ts";

```
```typescript

import { Application } from "./deps.ts";

```
they look exactly the same, let's look at the deps.ts file

```typescript
export * from "https://deno.land/x/abc@v1.0.3/mod.ts";

export * from "https://deno.land/x/oak@v6.0.1/mod.ts";
```
oak and abc have some methods and functions with the same names, 
this can be fixed as follows.

```typescript
export * as abc from "https://deno.land/x/abc@v1.0.3/mod.ts";

export * as oak from "https://deno.land/x/oak@v6.0.1/mod.ts";
```

```typescript

import { oak } from "./deps.ts";

oak.Application;
```
```typescript

import { abc } from "./deps.ts";

abc.Application;
```

but with this we lose explicitness, since everything is imported from a single deps.ts file, reading and having a clear idea of ​​what is being imported and what package it is becomes more confusing.

### A solution

As the future of using import maps is not clear within deno and that it has some shortcomings, we created a version of Trex which does not use import maps as the central axis. This version focuses on being as explicit and readable as possible when importing.

It works in the following way.

`install a package`
```sh
trex install --map fs@0.65.0
```
this creates the following structure.

```sh
imports/
 |- fs.ts
 |- deps.json
```
where for each installed package a file with the same name is created that exports the complete package.

`fs.ts`
```typescript
export * from "https://deno.land/std@0.65.0/fs/mod.ts"
```
the deps.json file is generated for Trex interoperability, 
to import it would be as follows.

```typescript

import {/* ... */} from "./imports/fs.ts";
                          ^^^^^^^^^^^^^^^
```
This makes it more explicit from where we are importing and helps when reading the code, of course it adds a file for each package but if you don't want to upload this to the repository you just have to add this to the `.gitignore`

```git
imports/*.ts
```
you only have to preserve the `deps.json` file and when the project is downloaded do a `trex install` and this will download and generate the files again.

The advantage of using imports in this way is that it is more explicit, easier to read and can be used by libraries instead of using import maps or deps.ts. For now this version is not available yet, but we already have all the functionalities adapted to this system and we hope to launch it soon.

If you have any opinion or comment I will gladly listen 😊