Trex π¦
Package management for deno (pronounced βtee rexβ)
About
Trex is a package management tool for deno similar to npm but keeping close to
the deno philosophy. Packages are cached and only one import_map.json
file is
generated.
// import_map.json
{
"imports": {
"http/": "https://deno.land/std/http/"
}
}
For more information about the import maps in deno see import maps.
Additional topics
Installation
deno install -A --unstable --import-map=https://deno.land/x/trex/import_map.json -n trex --no-check https://deno.land/x/trex/cli.ts
note: Works with deno >= 1.10.2
we shorten the install command so itβs not that long
The permissions that Trex uses are:
- βallow-net
- βallow-read
- βallow-write
- βallow-run
- βallow-env
You can give those permissions explicitly.
Updating Trex
Install new version with the -f
flag:
deno install -f -A --unstable --import-map=https://deno.land/x/trex/import_map.json -n trex --no-check https://deno.land/x/trex/cli.ts
Or use the upgrade
command:
trex upgrade
note: available for versions 0.2.0 or higher. note: if you want to try the latest features before release you can use -the
--canary
flag.
Verify the installation of Trex:
trex --version
and the console should print the Trex version.
For help on the commands that Trex provides, use:
trex --help
Usage
Installing from deno.land
Install the fs
, http
and fmt
modules from std:
trex install --map fs http fmt
note: you can use
trex i --map fs http fmt
--map
installs packages from the standard library and those hosted at
deno.land/x
Installing from nest.land
Install a package hosted on nest.land:
trex install --nest opine@0.13.0
note: if you want to install a package using nest.land you must specify a version explicitly as above
You can install packages from std hosted in nest.land by specifying the package and the version:
trex install --nest fs@0.61.0
Installing from a repository
trex install --pkg [user]/[repo or repo@tag/branch]/[path/to/file] [packageName]
Example:
trex install --pkg oakserver/oak@main/mod.ts oak
note: In the event that the repository uses a branch other than master as the main branch, this must be specified
The above downloads oak directly from its repository.
Example import map
All installation methods produce an import_map.json file:
{
"imports": {
"fs/": "https://deno.land/std/fs/",
"http/": "https://deno.land/std/http/",
"fmt/": "https://deno.land/std/fmt/"
}
}
Downloading packages
Download all the packages listed in the import_map.json
similar to
npm install
:
trex install
Adding custom packages
Install a package from a custom URL source:
trex --custom React=https://dev.jspm.io/react/index.js
import_map.json
:
{
"imports": {
"http/": "https://deno.land/std/http/",
"fmt/": "https://deno.land/std/fmt/",
"oak": "https://deno.land/x/oak/mod.ts",
"React": "https://dev.jspm.io/react/index.js"
}
}
Deleting packages
trex delete React
Remove a specific version from the cache and the import_map.json
file:
trex delete fs@0.52.0
import_map.json
:
{
"imports": {
"fs/": "https://deno.land/std/fs/",
"http/": "https://deno.land/std/http/",
"fmt/": "https://deno.land/std/fmt/",
"oak": "https://deno.land/x/oak/mod.ts"
}
}
Removing from cache only works with standard packages and those installed from
deno.land/x
Selecting a specific version of a package
Specify a packageβs version:
trex install --map fs@0.54.0
import_map.json
{
"imports": {
"fs/": "https://deno.land/std@0.54.0/fs/"
}
}
note: can be used with third party packages.
Check if a dependencie is outdate
if you want to check if one or more dependencies are out of date, only run trex check command.
trex check
this checks the dependencies and if there are updates for that dependency.
for now only works for deno.land/std
and
deno.land/x
but eventually should work with many
registers an cdn
Run Scripts
now you can create command aliases similar to npm run, you just have to create a run.json file with the following structure:
{
"scripts": {
"welcome": "deno run https://deno.land/std@0.71.0/examples/welcome.ts"
}
}
note: to run command aliases you must use the command
trex run <aliases>
now you can call a command within another or call a deno script like denopack
or eggs
within a command alias
{
"scripts": {
"start": "trex run welcome",
"welcome": "deno run https://deno.land/std@0.71.0/examples/welcome.ts",
"dev": "denon run ./app.ts",
"build": "aleph build"
}
}
Installation life cycle
when the command trex install
or trex i
executed, you can perform actions
before and after the execution of trex install
.
execution order:
- preinstall
- install
- postinstall
{
"scripts": {
"start": "trex run welcome",
"welcome": "deno run https://deno.land/std@0.71.0/examples/welcome.ts",
"dev": "denon run ./app.ts",
"build": "aleph build",
"preinstall": "deno --version",
"postinstall": "deno test --unstable"
}
}
note: you can use the βwatch flag to monitor the changes and rerun the script, example:
deno run --watch --unstable https://deno.land/std@0.71.0/examples/welcome.ts
you can pass arguments in the command alias and these will be resisted by the file to execute
trex run start --port=3000 --env
console.log(Deno.args); // ["--port=3000", "--env"]
Reboot script alias protocol (rsap)
with trex you can create script aliases that are reloaded every time a file is
changed, this can be done using denoβs --watch
flag. If you would like to have
this same functionality but with any command alias you want, you can use trex
reboot script protocol which reruns the command alias every time changes are
detected in the files and folders you specify
example:
{
"scripts": {
"start": "trex run welcome",
"welcome": "deno run https://deno.land/std@0.71.0/examples/welcome.ts",
"dev": "denon run ./app.ts",
"build": "aleph build"
},
"files": ["./app.ts"]
}
You only have to add the files
option in the run.json
file and it will only
observe the files and folders that you specify, if you leave the array empty it
will observe all the files.
for the script alias to use rsap
you just need to add the --watch
or -w
flag to the end of the command alias.
example:
{
"scripts": {
"dev": "go build"
},
"files": ["./main.go"]
}
trex run dev --watch ...args
and of course it can be used with any cli tool, compiler or interpreter.
note: you can create the run file in yaml format
- scripts:
dev: go build
- files:
- ./main.go
a limitation of watch mode is that they do not restart the processes that never end as http servers, in those cases we recommend other alternatives such as denon
Virtual cli tool execution (experimental)
trex exec allows you to run many cli tools hosted at deno.land/x
trex exec aleph init hello_world
trex will fetch alephβs cli and run without installing it locally using
deno install
, you can also specify the version you want to use.
trex exec aleph@v0.2.28 init hello_world
You can also specify the permissions that the cli will use
trex exec --perms env,read,write,net denon run ./app.ts
you just have to pass the --perms
flag followed by the permissions separated
by commas
perms
env
: βallow-envwrite
: βallow-writeread
: βallow-readnet
: βallow-netrun
: βallow-runreload
: βreloadplugin
: βallow-pluginhrtime
: βallow-hrtimeA
: βallow-all
note: if you donβt specify the permissions, they are all automatically granted to you
you can also use this combined with the command alias
example
// run.json
{
"scripts": {
"denon": "trex exec denon run"
},
"files": ["./app.ts"]
}
trex run denon ./app.ts
and yes you can do this:
trex exec trex exec trex exec ....
even this:
trex exec land trex exec land trex exec ....
this functionality is heavily inspired by
npx and
land. if you need another alternative to trex exec
to use in deno
, land this is a great option.
Purge a package or URL
if you want delete a package or url package from cache memory in deno, you can use the purge command to remove from cache memory.
example:
trex purge oak
this finds the oak package in the import_map.json
file and removes it from the
cache.
trex purge https://deno.land/x/oak@v6.3.1/mod.ts
also can be used with urls
Checking a packageβs dependency tree
trex tree fs
This prints out something like:
local: C:\Users\trex\AppData\Local\deno\deps\https\deno.land\434fe4a7be02d1875....
type: TypeScript
compiled: C:\Users\trex\AppData\Local\deno\gen\https\deno.land\std\fs\mod.ts.js
map: C:\Users\trex\AppData\Local\deno\gen\https\deno.land\std\fs\mod.ts.js.map
deps:
https://deno.land/std/fs/mod.ts
βββ¬ https://deno.land/std/fs/empty_dir.ts
β βββ¬ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/path/_constants.ts
β βββ¬ https://deno.land/std/path/win32.ts
β β βββ https://deno.land/std/path/_constants.ts
β β βββ¬ https://deno.land/std/path/_util.ts
β β β βββ https://deno.land/std/path/_constants.ts
β β βββ https://deno.land/std/_util/assert.ts
β βββ¬ https://deno.land/std/path/posix.ts
β β βββ https://deno.land/std/path/_constants.ts
β β βββ https://deno.land/std/path/_util.ts
β βββ¬ https://deno.land/std/path/common.ts
β β βββ¬ https://deno.land/std/path/separator.ts
β β βββ https://deno.land/std/path/_constants.ts
β βββ https://deno.land/std/path/separator.ts
β βββ https://deno.land/std/path/_interface.ts
β βββ¬ https://deno.land/std/path/glob.ts
β βββ https://deno.land/std/path/separator.ts
β βββ¬ https://deno.land/std/path/_globrex.ts
β β βββ https://deno.land/std/path/_constants.ts
β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/_util/assert.ts
βββ¬ https://deno.land/std/fs/ensure_dir.ts
β βββ¬ https://deno.land/std/fs/_util.ts
β βββ https://deno.land/std/path/mod.ts
βββ¬ https://deno.land/std/fs/ensure_file.ts
β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/fs/ensure_dir.ts
β βββ https://deno.land/std/fs/_util.ts
βββ¬ https://deno.land/std/fs/ensure_link.ts
β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/fs/ensure_dir.ts
β βββ https://deno.land/std/fs/exists.ts
β βββ https://deno.land/std/fs/_util.ts
βββ¬ https://deno.land/std/fs/ensure_symlink.ts
β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/fs/ensure_dir.ts
β βββ https://deno.land/std/fs/exists.ts
β βββ https://deno.land/std/fs/_util.ts
βββ https://deno.land/std/fs/exists.ts
βββ¬ https://deno.land/std/fs/expand_glob.ts
β βββ https://deno.land/std/path/mod.ts
β βββ¬ https://deno.land/std/fs/walk.ts
β β βββ https://deno.land/std/_util/assert.ts
β β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/_util/assert.ts
βββ¬ https://deno.land/std/fs/move.ts
β βββ https://deno.land/std/fs/exists.ts
β βββ https://deno.land/std/fs/_util.ts
βββ¬ https://deno.land/std/fs/copy.ts
β βββ https://deno.land/std/path/mod.ts
β βββ https://deno.land/std/fs/ensure_dir.ts
β βββ https://deno.land/std/fs/_util.ts
β βββ https://deno.land/std/_util/assert.ts
βββ https://deno.land/std/fs/read_file_str.ts
βββ https://deno.land/std/fs/write_file_str.ts
βββ https://deno.land/std/fs/read_json.ts
βββ https://deno.land/std/fs/write_json.ts
βββ https://deno.land/std/fs/walk.ts
βββ https://deno.land/std/fs/eol.ts
Integrity checking & lock files
Letβs say your module depends on a remote module. When you compile your module for the first time, it is retrieved, compiled and cached. It will remain this way until you run your module on a new machine (e.g. in production) or reload the cache.
But what happens if the content in the remote url is changed? This could lead to your production module running with different dependency code than your local module. Denoβs solution to avoid this is to use integrity checking and lock files.
Create a lockfile:
deno cache --lock=lock.json --lock-write file.ts
The above generates a lock.json
file.
If you use import_map.json
in input file, you can specify it:
deno cache --lock=lock.json --lock-write --import-map=import_map.json --unstable file.ts
See deno document for more info.
Complete example
A simple std server
Install http
and fmt
:
trex install --map http fmt
Create a simple server:
// server.ts
import { serve } from "http/server.ts";
import { green } from "fmt/colors.ts";
const server = serve({ port: 8000 });
console.log(green("http://localhost:8000/"));
for await (const req of server) {
req.respond({ body: "Hello World\n" });
}
Run the server:
deno run --allow-net --import-map=import_map.json --unstable server.ts
note: it is important to use βimport-map=import_map.json βunstable
Adding third party packages
Example using oak
Add the master version of oak:
trex i --map oak
This adds oak
to the import_map.json
file:
{
"imports": {
"http/": "https://deno.land/std/http/",
"fmt/": "https://deno.land/std/fmt/",
"oak": "https://deno.land/x/oak/mod.ts"
}
}
Then create an oak application. Note the import
statement.
// app.ts
import { Application } from "oak";
const app = new Application();
app.use((ctx) => {
ctx.response.body = "Hello World!";
});
await app.listen({ port: 8000 });
Run the server:
deno run --allow-net --import-map=import_map.json --unstable app.ts
Contributing
Contributions are welcome, see CONTRIBUTING GUIDELINES.
Licensing
Trex is licensed under the MIT license.