undo3d
Version:
Undo3D helps you build free-roaming 3D web apps where thousands of users can collaborate creatively in real time. Expect the first public beta mid-2019, and the first production release mid-2020.
53 lines (47 loc) • 2.31 kB
JavaScript
//// Undo3D has a collection of browser shims which mimic the functionality of
//// various Node.js modules. This allows a single codebase to run on the server
//// and the client at the same time.
////
//// Historically, Node would load its filesystem utilities like this:
//// var fs = require('fs')
//// But browsers have no `require()`. Node can be made to understand this ES6:
//// import fs from 'fs'
//// But browsers need to import an actual path, like this:
//// import fs from '../deps/node_modules/undo3d-shim-browser/fs/all.mjs'
//// Browsers and Node happily import the above - in this case, a module which
//// simulates the filesystem using IndexDB. But we need Node to use its own
//// native 'fs' module instead. To make that happen, you’ll need to run Node
//// with the following option:
//// --loader ./support/node-esm-resolve-hook.mjs
////
//// Now Node imports its native 'fs' module, and browsers import the shim.
//// See https://nodejs.org/api/esm.html#esm_resolve_hook for more details.
//// Map the `pathEnd` of browser shims to Node native module names.
const shims = {
'undo3d-shim-browser/assert/all.mjs': 'assert'
// , 'undo3d-shim-browser/fs/all.mjs': 'fs' //@TODO
}
//// Set the default for the `parentModuleURL` argument.
const baseURL = new URL('file://')
baseURL.pathname = process.cwd() + '/'
//// Define the resolve hook.
export async function resolve(
specifier
, parentModuleURL = baseURL
, defaultResolver
) {
//// Get `pathEnd`, which is the last three path-parts of `specifier`:
//// '../deps/node_modules/undo3d-shim-browser/fs/all.mjs'
//// -> ['..','deps','node_modules','undo3d-shim-browser','fs','all.mjs']
//// -> 'undo3d-shim-browser/fs/all.mjs'
//// './just/a/random/module.mjs'
//// -> ['.','just','a','random','module.mjs']
//// -> 'a/random/module.mjs'
const pathEnd = specifier.split('/').slice(-3).join('/')
//// If `pathEnd` is recognised, use Node’s native module instead of the
//// browser shim. For example, 'undo3d-shim-browser/fs/all.mjs' -> 'fs'.
if (shims[pathEnd])
return { format:'builtin', url:shims[pathEnd] }
//// Otherwise, act as if we hadn’t hooked the resolver.
return { format:'esm', url:new URL(specifier, parentModuleURL).href }
}