my-dummy-npm-and-deno-module
A demo project that serve as a tutorial on how to setup Denoify.
NOTE: For a new module name favor ā_ā over ā-ā in the module name as it is a deno requirement not to use ā_ā
Step 1: Provide port for dependencies.
This demo project depends on three modules:
"js-yaml"
: Is is already known by denoify, it is present in : known-ports.jsonc,
There is nothing to do forjs-yaml
. Let us assume however, for the sake of the tutorial that is is not know. We manually add an ādenoPortā entry. inpackage.json
pointing to the available port:
"dependencies": {
"js-yaml": "^3.13.1"
},
"denoPorts": {
"js-yaml": "https://deno.land/x/js_yaml_port/js-yaml.js"
},
"run-exclusive"
: We do not need to specify a deno port as run-exclusive is a denoified module."ts-md5"
: (It is inknown-ports.json
but let us assume it is not ) One way to support this module is to fork the home repo of ts-md5 and setup denoify on this fork. Weāve done it here. We can now specify our fork as a deno port.
"dependencies": {
"ts-md5": "^1.2.7"
}
"denoPorts": {
"ts-md5": "garronej/ts-md5"
},
ipaddr.js
: There is a custom import statements replacer for it, see here. We do not need to specify a custom port.
We can ignore the dev dependencies as they are not mandatory to run the module.
NOTE: denoPorts
entry only accept urls of types https://deno.land/x/...
or https://raw.github.com/...
.
Github repo under the form of <userOrOrg>/<repoName>
will only works with module that have been denoified ( like garronej/tm-md5 )
If you want to use urls from Pika, jspm or UNPKG you can but you have to write custom replacers.
Step 2: Edit tsconfig.json
Make sure you use the āoutDirā option.
Denoify reads the āoutDirā field of the tsconfig.json
filed to determine where to put the de generated source so it must be completed.
The typical value to use is:
{
"compilerOptions": {
"outDir": "./dist"
}
}
Enable strict mode and fixes errors if any.
By default deno has all strict compiler options enabled so if you want your module to run on deno regardless of the context you must set:
{
"compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true
}
}
It might rise a lot of error but they are all very easy to fix even if you are not familiar with the codebase.
Click to expand!
For errors related to this
implicitly having an any type, replace:
function myFun(a): number{
this.doSomething(a);
}
by:
function myFun(this: any, a: any): number{
this.doSomething(a);
}
If you donāt know any better.
For errors relating to something that can be null or undefined, replace:
x.doSomething();
by:
x!.doSomething();
For error related to uninitialized property, replace:
class Foo {
n: number;
}
by:
class Foo {
n!: number;
}
For errors relative to name that cannot be found:
describe(...)
declare const describe: any;
describe(...)
For unused variables:
const x=3;
const x=3; x;
Explicitly excludes the deno files from compilation
tsconfig.json
{
"exclude": [
"node_modules",
"dist",
"./deno_dist",
"./mod.ts"
]
}
npm
scripts
Edit your First off, run $ npm install --save-dev denoify
then add/edit
the npm
scripts.
package.json
"devDependencies": {
"denoify": "^4.0.1",
}
"scripts": {
"build": "tsc && denoify",
}
Building
Now every time you will run $ npm run build
the sources for deno will be updated in /deno_dist/
It is also a good idea to add scripts to run tests on node and on deno.
Note that in this repo we run the tests with the --allow-read
because we use
fs
but if you module do not access files on the disk you donāt need it.
Create a new GitHub release every time you publish on npm.
Just after running $ npm publish
got to your GitHub repo pages -> release -> create new release ( or draft ne release ) and tag version enter v0.2.9
matching the current version in your package.json
file.
(Optional) Publish your module on deno.land
Navigate to deno.land/x, click Add a module
then follow the instruction.
Use deno_dist/
as subdirectory when asked.
Accessing files on the disk.
Keep in mind that in Deno there is no node_modules
sitting on the disk at runtime.
Letās assume for example that you would like to load a database.json
file located
at the root of your project. You would write something like this:
src/index.ts
import * as fs from "fs";
import * as path from "path";
import { TextDecoder } from "util";
export function getDatabase(): Record<string,any> {
return JSON.parse(
new TextDecoder("utf-8").decode(
fs.readFileSync(
path.join(
__dirname,
"..", "database.json"
)
) as Uint8Array
)
);
}
This will work on both Node and Deno when you run your tests but once
your module published this wonāt work on Deno anymore for the same reason
it wonāt work in the Browser, the database.json
file is present
on the disk at runtime.
Conclusion
It is now possible to use your module on node using ( assuming you have published it with npm publish
):
$ npm install --save my-dummy-npm-and-deno-module
then:
import { Cat } from "my-dummy-npm-and-deno-module"
And on deno with:
import { Cat } from "https://deno.land/x/my_dummy_npm_and_deno_module@v0.2.9/mod.ts";
or if you havenāt published on Deno.land:
import { Cat } from "https://raw.githubusercontent.com/garronej/my_dummy_npm_and_deno_module/v0.2.9/deno_dist/mod.ts";
On top of that this module can now be used as a dependency in other modules that uses denoify
.
If you want to avoid tracking the deno_dist/
directory and automates the workflow checkout denoify_ci