Giter Club home page Giter Club logo

webrun's Introduction

WebRun

A custom module loader and global shim for Node to make it compatible with the browser.

The goal is to make code that works in browsers first, but can also run anywhere that Node runs.

Warning: This is still in development. Use at your own risk!

Bug reports welcome!

Usage:

# Install the CLI
npm install -g @rangermauve/webrun

# Run it without installing globally
npx @rangermauve/webrun "https://rangermauve.hashbase.io/example.js"

# Load a module from the web and log to the console
webrun "https://rangermauve.hashbase.io/example.js"

# Run a local file
webrun ./example.js

Then in your JS:

import example from "https://rangermauve.hashbase.io/esm.js";
import p2pexample from "dat://rangermauve.hashbase.io/esm.js";

example();
p2pexample();

You can start a REPL using:

webrun

Then you can load modules using the new dynamic import syntax.

This will return a promise that contains all the exported properties.

If you want to load the default export you can use something like the following:

let {default: example} = await import("https://rangermauve.hashbase.io/esm.js")

example()

You can enable the require global by adding the --allow-require flag. This is disabled by default to encourage use of import and to limit what scripts can do. This behaves differently from the usual require in that it's a global and always requires relative to the current working directory.

STDIO

You can opt-into input from STDIN and output to STDOUT using self.onmessage and self.postMessage.

These are the same APIs that exist for iframes and WebWorkers which means that your worker code can potentially run in webrun and vice-versa.

// Get text from STDIN, uppercase it, send it to STDOUT
self.onmessage = (text) => self.postMessage((text+"").toUpperCase())

CLI arguments

We want to be as close to the web as possible, so instead of adding a non-standard global for CLI arguments, we pass them in as query string params.

You can access the URL of the current module using the new import.meta.url syntax.

For example, given the file example.js:

console.log(`My URL is: ${import.meta.url}`)

Running this:

webrun example.js --foo bar --fizz buzz

Will result in

My URL is file://whatever/the/path/us/example.js?foo=bar&fizz=buzz

You can access these arguemnts using the following

const url = new URL(import.meta.url)

const foo = url.searchParams.get('foo')
const fizz = url.searchParams.get('fizz')

Web API support

Here's a list of the APIs that are supported, or are going to be supported eventually. Feel free to open an issue if you have ideas about other APIs that can be added.

API

Plugins

Help it's not working!

  • Delete the .webrun folder in the current directory. This will clear the cache
  • If that doesn't work, raise an issue.

How it works:

The new experimental-modules feature in Node.js is great, but it currently only works with file: URLs.

This means that modules made for the web are totally incompatible with Node. As a result, there's now four environments to code against: The legacy web with script tags, the web with ESM, Legacy CommonJS modules, and ESM in Node.js.

Luckily, node's vm builtin module now has support for custom ESM loaders. This means that we can now create a context that's separated from Node's globals and use anything we want for loading the contents of modules.

That's exactly how this works. It intercepts calls to https:// imports, downloads the content to the ./.webrun/web-cache folder, and loads it with the VM module.

Some browser APIs have been added to the global scope so hopefully a lot of modules made for browsers should work here, too. Feel free to open an issue to add your favorite missing browser API.

In addition to loading content from https:// URLs, this loader also supports dat:// URLs. This way you can download code right from the peer to peer web!

You can still load Node modules by using require, but this should only be done for APIs that you absolutely can't get on the web because otherwise your code won't be portable.

PRs for additional protocols are welcome! All you need is an async function that takes a URL, and returns the file content string.

Roadmap:

  • Able to load from the filesystem
  • Able to load HTTPS URLs
  • Able to load Dat URLs
  • Able to load using reqire (behind a flag)
  • Browser APIs
  • Dat protocol support
    • Load from Dat URLs
    • DatArchive global
    • Experimental Beaker APIs (does it make sense?)
  • IPFS
    • Load from IPFS / IPNS URLs
    • ipfs global
  • CLI arguments: Add them to searchParams for the URL being loaded

webrun's People

Contributors

allain avatar rangermauve avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.