Files
pear-docs/reference/bare/nodejs-compatibility-with-bare.md
Vivek Singh 03fee03bba fix json
2024-10-15 11:55:04 +05:30

314 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Node.js Compatibility with Bare
Bare offers great compatibility with Node.js counterparts.
Most of the modules and APIs used by developers are covered and supported.
## Currently supported modules
* `assert`: [`bare-assert`](https://github.com/holepunchto/bare-assert) (through `npm:bare-node-assert)`
* `buffer`: [`bare-buffer`](https://github.com/holepunchto/bare-buffer) (through `npm:bare-node-buffer)`
* `child_process`: [`bare-subprocess`](https://github.com/holepunchto/bare-subprocess) (through `npm:bare-node-child-process)`
* `console`: [`bare-console`](https://github.com/holepunchto/bare-console) (through `npm:bare-node-console)`
* `crypto`: [`bare-crypto`](https://github.com/holepunchto/bare-crypto) (through `npm:bare-node-crypto)`
* `events`: [`bare-events`](https://github.com/holepunchto/bare-events) (through `npm:bare-node-events)`
* `fs`: [`bare-fs`](https://github.com/holepunchto/bare-fs) (through `npm:bare-node-fs)`
* `http`: [`bare-http1`](https://github.com/holepunchto/bare-http1) (through `npm:bare-node-http)`
* `https`: [`bare-https`](https://github.com/holepunchto/bare-https) (through `npm:bare-node-https)`
* `inspector`: [`bare-inspector`](https://github.com/holepunchto/bare-inspector) (through `npm:bare-node-inspector)`
* `module`: [`bare-module`](https://github.com/holepunchto/bare-module) (through `npm:bare-node-module)`
* `os`: [`bare-os`](https://github.com/holepunchto/bare-os) (through `npm:bare-node-os)`
* `path`: [`bare-path`](https://github.com/holepunchto/bare-path) (through `npm:bare-node-path)`
* `process`: [`bare-process`](https://github.com/holepunchto/bare-process) (through `npm:bare-node-process)`
* `readline`: [`bare-readline`](https://github.com/holepunchto/bare-readline) (through `npm:bare-node-readline)`
* `repl`: [`bare-repl`](https://github.com/holepunchto/bare-repl) (through `npm:bare-node-repl)`
* `stream`: [`bare-stream`](https://github.com/holepunchto/bare-stream) (through `npm:bare-node-stream)`
* `timers`: [`bare-timers`](https://github.com/holepunchto/bare-timers) (through `npm:bare-node-timers)`
* `tls`: [`bare-tls`](https://github.com/holepunchto/bare-tls) (through `npm:bare-node-tls)`
* `tty`: [`bare-tty`](https://github.com/holepunchto/bare-tty) (through `npm:bare-node-tty)`
* `url`: [`bare-url`](https://github.com/holepunchto/bare-url) (through `npm:bare-node-url)`
* `util`: [`bare-utils`](https://github.com/holepunchto/bare-utils) (through `npm:bare-node-util)`
* `worker_threads`: [`bare-worker`](https://github.com/holepunchto/bare-worker) (through `npm:bare-node-worker-threads)`
* `zlib`: [`bare-zlib`](bhttps://github.com/holepunchto/bare-zlib) (through `npm:bare-node-zlib)`
## Config for the Node.js stdlib
To get the full Node.js compatible layer that Bare currently supports add the following lines to the package.json file.
```json
{
"dependencies": {
"bare-assert": "^1.0.1",
"assert": "npm:bare-node-assert",
"bare-buffer": "^2.3.0",
"buffer": "npm:bare-node-buffer",
"bare-subprocess": "^2.0.4",
"child_process": "npm:bare-node-child-process",
"bare-console": "^4.1.0",
"console": "npm:bare-node-console",
"bare-crypto": "^1.0.0",
"crypto": "npm:bare-node-crypto",
"bare-events": "^2.2.0",
"events": "npm:bare-node-events",
"bare-fs": "^2.1.5",
"fs": "npm:bare-node-fs",
"bare-http1": "^2.0.3",
"http": "npm:bare-node-http",
"bare-https": "^1.0.0",
"https": "npm:bare-node-https",
"bare-inspector": "^1.1.2",
"inspector": "npm:bare-node-inspector",
"bare-module": "^1.2.5",
"module": "npm:bare-node-module",
"bare-os": "^2.2.0",
"os": "npm:bare-node-os",
"bare-path": "^2.1.0",
"path": "npm:bare-node-path",
"bare-process": "^1.3.0",
"process": "npm:bare-node-process",
"bare-readline": "^1.0.0",
"readline": "npm:bare-node-readline",
"bare-repl": "^1.0.3",
"repl": "npm:bare-node-repl",
"bare-stream": "^1.0.0",
"stream": "npm:bare-node-stream",
"bare-timers" : "^1.0.0",
"timers": "npm:bare-node-timers",
"bare-tls": "^1.0.0",
"tls": "npm:bare-node-tls",
"bare-tty": "^3.2.0",
"tty": "npm:bare-node-tty",
"bare-url": "^1.0.7",
"url": "npm:bare-node-url",
"bare-utils": "^1.0.0",
"util": "npm:bare-node-util",
"bare-worker": "^1.0.0",
"worker_threads": "npm:bare-node-worker-threads",
"bare-zlib": "^1.0.0",
"zlib": "npm:bare-node-zlib"
}
}
```
## Consuming dependencies that use core Node.js modules
If the project dependencies use core [Node.js](https://nodejs.org/en/download) modules, use [NPM aliases](./nodejs-compatibility-with-bare.md#consuming-dependencies-using-npm-aliases) or [import maps](./nodejs-compatibility-with-bare.md#consuming-dependencies-using-import-maps) to consume the Bare version of those modules.
### Consuming dependencies using NPM Aliases
NPM aliasing is a feature that allows developers to define custom names, or aliases, for their dependencies. This enables them to use a more intuitive or project-specific naming convention instead of relying on the packages official name.
In your projects `package.json` file, use the `alias` field to specify package aliases. For example:
```json
{
"dependencies": {
"my-package": "npm:actual-package@1.0.0"
}
}
```
After defining aliases, install the dependencies as usual:
```bash
npm install
```
Then, in the code import the aliased package:
```js
// Instead of using the name of the package, use the alias
const myPackage = require('my-package');
```
### Example of using `fs` in a project using aliases
> Make sure [Node.js](https://nodejs.org/en/download) is installed on your system. This can be checked by running `node -v` in the terminal.
#### Start a new project
Init a new terminal project.
```bash
mkdir test-fs
cd test-fs
pear init --yes --type=terminal
```
Replace the contents of `index.js` with the following:
```js
import * as fs from 'node:fs';
async function test() {
try {
await fs.promises.writeFile('test.txt', `Hello ${global.Bare ? 'Bare' : 'Node'}`);
const content = await fs.promises.readFile('test.txt', 'utf8');
console.log('File content:', content);
await fs.promises.unlink('test.txt');
console.log('Test successful!');
} catch (error) {
console.error('Test failed:', error);
}
}
test();
```
This will create a file called `test.txt` and write a string to it. It will then read the file and log the content to the console.
Now run the file using Node.js.
```bash
node index.js
```
This should output the following.
```bash
File content: Hello Node
Test successful!
```
If we run the same project using Bare, it will fail with the `MODULE_NOT_FOUND` error.
Now to make it compatible with Bare, we will create an alias for `fs` in our project and install the respective Bare package to make it work again. In this case it's [bare-fs](https://github.com/holepunchto/bare-fs).
Add the following lines to the `package.json` file.
```json
{
"dependencies": {
"bare-fs": "^2.1.5",
"fs": "npm:bare-node-fs"
}
}
```
This installs `bare-fs` newer than `^2.1.5`.
Then, adds alias `fs` to the wrapper `npm:bare-node-fs`.
The only thing the wrapper does is `module.exports = require('bare-fs')` and at version `*`,
meaning the version that is specified is used.
Using the wrapper saves space as npm will only include `bare-fs` once if something else installs it.
Now install the dependencies.
```bash
npm install
```
Now run the project using Bare.
```bash
bare index.js
```
This should output the following.
```bash
File content: Hello Bare
Test successful!
```
### Consuming dependencies using Import Maps
When writing a module that uses `fs` the mapping can be specified directly in the module instead of relying on the compatible. This can be achieved using an 'import map'.
For example [Localdrive](https://github.com/holepunchto/localdrive) uses `fs` and to work in both Bare and Node.js it adds the following import map to the `package.json` file.
```json
{
"imports": {
"fs": {
"bare": "bare-fs",
"default": "fs"
},
"fs/*": {
"bare": "bare-fs/*",
"default": "fs/*"
}
},
"optionalDependencies": {
"bare-fs": "^2.1.5"
}
}
```
Let's take the `fs` example and use import maps instead of aliases.
### Example of using `fs` in a project using import maps
Start a new terminal project
```bash
mkdir test-fs
cd test-fs
pear init --yes --type=terminal
```
Replace contents of `index.js` with the code from the NPM aliases [example](./nodejs-compatibility-with-bare.md#example-of-using-fs-in-a-project-using-aliases).
Change the import statement at the top:
```js
import * as fs from 'fs';
```
Add the following fields to the `package.json`:
```json
{
"imports": {
"fs": {
"bare": "bare-fs",
"default": "fs"
}
},
"optionalDependencies": {
"bare-fs": "^2.1.5"
}
}
```
Install the dependencies:
```bash
npm install
```
Now run the file using Node.js.
```bash
node index.js
```
This should output the following.
```bash
File content: Hello Node
Test successful!
```
Run the same file using Bare
```bash
bare index.js
```
It should log the following output:
```bash
File content: Hello Bare
Test successful!
```
This way the module is in full control of exactly which version of `fs` is bound to Bare.
This is the best option, as it provides the best of both worlds. Node.js compatibility, but with full control of the dependencies.