Skip to content

Commit

Permalink
feat: add ts-node example (#105)
Browse files Browse the repository at this point in the history
Adds an example with the minimum config required to run Helia using ts-node.
  • Loading branch information
achingbrain authored Aug 7, 2023
1 parent ae3c713 commit 4f4ae68
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ jobs:
- helia-parcel
- helia-nextjs
- helia-script-tag
- helia-ts-node
- helia-vite
- helia-vue
- helia-webpack
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- [Basics](#basics)
- [Frameworks](#frameworks)
- [Bundlers](#bundlers)
- [Other tooling](#other-tooling)
- [Prerequisites](#prerequisites)
- [IPFS Tutorials at ProtoSchool](#ipfs-tutorials-at-protoschool)
- [Documentation](#documentation)
Expand Down Expand Up @@ -71,6 +72,10 @@ Feel free to jump directly into the examples, however going through the followin
- [Helia with esbuild](/examples/helia-esbuild/): Bundle helia with esbuild
- [Helia with Webpack](/examples/helia-webpack/): Bundle helia with webpack

#### Other tooling

- [Helia with ts-node](/examples/helia-ts-node/): Run Helia using ts-node

### Prerequisites

Make sure you have installed all of the following prerequisites on your development machine:
Expand Down
191 changes: 191 additions & 0 deletions examples/helia-ts-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
<p align="center">
<a href="https://github.com/ipfs/helia" title="Helia">
<img src="https://github.com/raw/ipfs/helia/main/assets/helia.png" alt="Helia logo" width="300" />
</a>
</p>

<h3 align="center"><b>Running Helia with ts-node</b></h3>

<p align="center">
<img src="https://github.com/raw/jlord/forkngo/gh-pages/badges/cobalt.png" width="200">
<br>
<a href="https://ipfs.github.io/helia/modules/helia.html">Explore the docs</a>
·
<a href="https://github.com/ipfs-examples/helia-examples/issues">Report Bug</a>
·
<a href="https://github.com/ipfs-examples/helia-examples/issues">Request Feature/Example</a>
</p>

## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation and Running example](#installation-and-running-example)
- [Usage](#usage)
- [tsconfig.json](#tsconfigjson)
- [target](#target)
- [module](#module)
- [moduleResolution](#moduleresolution)
- [package.json](#packagejson)
- [type](#type)
- [ts-node](#ts-node)
- [esm flag](#esm-flag)
- [Putting it all together](#putting-it-all-together)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Want to hack on IPFS?](#want-to-hack-on-ipfs)

## About The Project

- Read the [docs](https://ipfs.github.io/helia/modules/helia.html)
- Look into other [examples](https://github.com/ipfs-examples/helia-examples) to learn how to spawn a Helia node in Node.js and in the Browser
- Visit https://dweb-primer.ipfs.io to learn about IPFS and the concepts that underpin it
- Head over to https://proto.school to take interactive tutorials that cover core IPFS APIs
- Check out https://docs.ipfs.io for tips, how-tos and more
- See https://blog.ipfs.io for news and more
- Need help? Please ask 'How do I?' questions on https://discuss.ipfs.io

## Getting Started

### Prerequisites

Make sure you have installed all of the following prerequisites on your development machine:

- Git - [Download & Install Git](https://git-scm.com/downloads). OSX and Linux machines typically have this already installed.
- Node.js - [Download & Install Node.js](https://nodejs.org/en/download/) and the npm package manager.

### Installation and Running example

```console
> npm install
> npm start
```

## Usage

[ts-node](https://typestrong.org/ts-node/) is a [TypeScript](https://www.typescriptlang.org/) execution and [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) tool for running TypeScript files from the command line, similar to how you would run JavaScript files with node.js.

It gives the illusion of compilation-free code execution by using [JIT compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation) to turn your TypeScript code into JavaScript at runtime and is a useful development tool.

Because TypeScript outputs [CommonJS](https://en.wikipedia.org/wiki/CommonJS) by default, and Helia is written using more modern [ECMAScript Modules](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/) it's necessary to override the default configuration `ts-node` uses.

### tsconfig.json

This is the minimum config that is required.

#### target

The [target](https://www.typescriptlang.org/tsconfig#target) to `ES2021` - this will ensure ESM is output and not CJS.

#### module

[module](https://www.typescriptlang.org/tsconfig#module) should be set to at least `ES2022` - this is necessary to support things like [private class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields).

#### moduleResolution

[moduleResolution](https://www.typescriptlang.org/tsconfig#moduleResolution) should be set to `node` or `node16` to enable use of `import` as well as `require`.

### package.json

We have to tell node that this is an ESM project.

#### type

The `type` field in your `package.json` should be set to `module`. This means the `.js` extension is interpreted as ESM by default.

It also means that import paths within your own project need file extensions, so any `import foo from './bar/baz'` will need to be changed to `import foo from './bar/baz.js'`.

TypeScript [will not add this for you](https://github.com/microsoft/TypeScript/issues/16577).

### ts-node

#### esm flag

`ts-node` has an `--esm` flag that is slightly counter-intuitively necessary to enable loading `.ts` files for JIT compilation via `import`:

```console
% npx ts-node --help | grep esm
--esm Bootstrap with the ESM loader, enabling full ESM support
```

It is necessary to pass this flag when running `ts-node`

### Putting it all together

`tsconfig.json`

```js
{
"compilerOptions": {
"module": "ES2022",
"target": "ES2021",
"moduleResolution": "node"
},
// other settings here
}
```

`package.json`

```js
{
"type": "module",
// other settings here
}
```

You can now run ts code using ts-node:

```bash
> npx ts-node --esm ./src/index.ts

Helia is running
PeerId: 12D3KooWMUv1MYSYrgsEg3ykfZ6nDZwaT72LtVCheRNhH15kzroz
```

That's it! You just ran an ESM-only module using ts-node with JIT compilation!

_For more examples, please refer to the [Documentation](#documentation)_

## Documentation

- [IPFS Primer](https://dweb-primer.ipfs.io/)
- [IPFS Docs](https://docs.ipfs.io/)
- [Tutorials](https://proto.school)
- [More examples](https://github.com/ipfs-examples/helia-examples)
- [API - Helia](https://ipfs.github.io/helia/modules/helia.html)
- [API - @helia/unixfs](https://ipfs.github.io/helia-unixfs/modules/helia.html)

## Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.

1. Fork the IPFS Project
2. Create your Feature Branch (`git checkout -b feature/amazing-feature`)
3. Commit your Changes (`git commit -a -m 'feat: add some amazing feature'`)
4. Push to the Branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## Want to hack on IPFS?

[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)

The IPFS implementation in JavaScript needs your help! There are a few things you can do right now to help out:

Read the [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md) and [JavaScript Contributing Guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md).

- **Check out existing issues** The [issue list](https://github.com/ipfs/helia/issues) has many that are marked as ['help wanted'](https://github.com/ipfs/helia/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22) or ['difficulty:easy'](https://github.com/ipfs/helia/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Adifficulty%3Aeasy) which make great starting points for development, many of which can be tackled with no prior IPFS knowledge
- **Look at the [Helia Roadmap](https://github.com/ipfs/helia/blob/main/ROADMAP.md)** This are the high priority items being worked on right now
- **Perform code reviews** More eyes will help
a. speed the project along
b. ensure quality, and
c. reduce possible future bugs
- **Add tests**. There can never be enough tests

[cid]: https://docs.ipfs.tech/concepts/content-addressing "Content Identifier"
[Uint8Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
[libp2p]: https://libp2p.io
[IndexedDB]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[S3]: https://aws.amazon.com/s3/
19 changes: 19 additions & 0 deletions examples/helia-ts-node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "helia-ts-node",
"version": "1.0.0",
"private": true,
"type": "module",
"description": "Running Helia with ts-node",
"scripts": {
"start": "ts-node --esm ./src/index.ts",
"test": "test-node-example test/*"
},
"dependencies": {
"helia": "^1.3.12"
},
"devDependencies": {
"ts-node": "^10.9.1",
"test-ipfs-example": "^1.0.0",
"typescript": "^5.1.6"
}
}
8 changes: 8 additions & 0 deletions examples/helia-ts-node/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* eslint-disable no-console */

import { createHelia } from 'helia'

const node = await createHelia()

console.info('Helia is running')
console.info('PeerId:', node.libp2p.peerId.toString())
7 changes: 7 additions & 0 deletions examples/helia-ts-node/test/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import path from 'path'
import { fileURLToPath } from 'url'
import { waitForOutput } from 'test-ipfs-example/node'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

await waitForOutput('Helia is running', 'ts-node', ['--esm', path.resolve(__dirname, '../src/index.ts')])
12 changes: 12 additions & 0 deletions examples/helia-ts-node/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "ES2022",
"target": "ES2021",
"moduleResolution": "node",

// only necessary for the example linting check, your project may not need
// these settings
"strictNullChecks": true,
"skipLibCheck": true
}
}

0 comments on commit 4f4ae68

Please sign in to comment.