Git Product home page Git Product logo

babel-ioc-dep-wrap-plugin's Introduction

Babel IoC Dependency Wrapper Plugin

Wraps module content into a container that overwrites require()(i.e. works only with CommonJS modules) calls with custom calls to intercept dependency loading. It provides two wrapper versions for async and generator wrapper functions.

Async Wrapper

Async wrapper allows providing custom require() replacement and all calls to it are done via await statement. Source:

require('init');

const b = require('b.js');

Result:

async function moduleinitFunction(require) {
  await require('init');
  const b = await require('b.js');
  return exports;
}

Generator Wrapper

Generator wrapper, replaces all require() calls into yeilds, so you module pauses until dependencies are resolved and control flow returned. Source:

require('init');

const b = require('b.js');

Result:

async function* moduleinitFunction() {
  yield {
    require: 'init',
  };
  const b = yield {
    require: 'b.js',
  };
  return exports;
}

Limitations

  1. Import declarations cannot be processed, so source must be a CommonJs module. Since import delcarations could be only found in top level/scope of the module, it is a good target for future update.
  2. Nested require() calls, like const stuff = (() => require('stuff'))(), since require calls are being transformed into await calls or generator yields, covering nested require() calls does not seem doable. However, nested dynamic imports are supported with async wrapper, because they return Promise anyway.

    This also seems like a target for update, to return a list of such requires if any and warning instead of error. Modules from this list could be pre-loaded and provided immediately.

  3. No AMD/UMD wrapping.

Example require() using fetch()

When module is required, it loads module code from ./modules?name=<package name> and returns promise which resolves with module exports.

const moduleCache = new Map();

/**
 * Load and evaluate module
 * @private
 */
const asyncRequire = async (moduleName, exports) =>
  fetch(`./modules?name=${encodeURIComponent(moduleName)}`)
    .then((response) => response.text())
    .then((code) => {
      eval(code);

      return moduleInitFunction(require, exports);
    });

/**
 * Cache module or return cached module
 * 
 * @param {String} moduleName
 * @returns {Promise<Object>} Module exports
 */
const require = (moduleName) => {
  if (moduleCache.has(moduleName)) {
    return moduleCache.get(moduleName);
  }

  const exports = {};

  /**
   * This helps to resolve circular dependencies.
   * We return module exports early and fill it when it is ready.
   * This way it won't block loading other modules.
   */
  moduleCache.set(moduleName, exports);

  return asyncRequire(moduleName, exports);
};

To use such require, just call it and wait for promise to resolve

const dependencies = async () => {
  const { moduleFn } = await require('my-module'); 

};

This way requiring modules works in this example.

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.