0.0.4 • Published 1 year ago

import-mapper v0.0.4

Weekly downloads
-
License
Apache 2.0
Repository
-
Last release
1 year ago

import-mapper

Inject require()'d modules into dynamic imports()

import-mapper allows you to inject pretty much anything into dynamically import()ed modules.

Please report issues to https://github.com/seanmorris/import-mapper/issues

install

Install with npm:

$ npm install import-mapper

Or, include with unpkg:

<script src = "https://unpkg.com/commonjs-require-definition/require.js"></script>
<script src = "https://unpkg.com/import-mapper/dist/ImportMapper.js"></script>

Usage

Basic

Let's say you've got the following module, Bar.mjs. It exports one class, Bar, which extends Foo from module @foo/Foo.

Bar.mjs

import { Foo } from '@foo/Foo';

export class Bar extends Foo{}

The Foo class is brought into Bar via an ESM import {...}. However, the Foo class already exists in our namespace, possibly brought in via require().

The objective here is to inject the existing @foo/Foo, and prevent the need to pull the module via HTTP if it already exists in our bundled script.

Now, in main.js, we can create an ImportMapper to inject @foo/Foo into Bar.mjs:

main.js

const { ImportMapper } = require('import-mapper');

// pretend this came from elsewhere
class Foo{};

// Create the ImportMapper.
const importMapper = new ImportMapper({
    '@foo/Foo': { Foo } // "@foo/Foo" has one export: "Foo".
});

// Register it.
importMapper.register();

// Import Bar.
import('/Bar.mjs').then( module => {

    // Get the class...
    const { Bar } = module;

    // Create the instance
    const barInstance = new Bar;

    // Check that Bar extends Foo
    console.log(barInstance instanceof Foo);
});

Use with require()

Longhand

If the module @foo/Foo is available via require(), then we can declare our ImportMapper like so:

const importMapper = new ImportMapper({
    '@foo/Foo': require('@foo/Foo')
});

Shorthand

If require() is available in the global scope, and you're only importing stuff from require(), then you can just pass an array of module names:

const importMapper = new ImportMapper( ['@foo/Foo'] );

Short(er)hand

If your bundler is awesome like brunch is, then you can just call require.list() to get an array of all available module names:

const importMapper = new ImportMapper( globalThis.require.list() );

This will map all modules available to require() to dynamic imports.

Scalars

Bare scalar values will be returned as the default export of a module:

const importMapper = new ImportMapper({
    'someString': 'this is a string'
});

importMapper.register();

import('someString').then(module => console.log(module.default));

Wrap the scalar in an object if you need a named export:

const importMapper = new ImportMapper({
    'someString': {someString: 'this is a string'}
});

importMapper.register();

import('someString').then(module => console.log(module.someString));

Multiple Exports

You can pass an object with multiple keys to get a module with multiple exports.

// pretend this came from elsewhere
class Foo{};
class Baz{};

// Create the ImportMapper.
const importMapper = new ImportMapper({
    '@foo/Foo': { Foo, Baz } // "@foo/Foo" has two exports: "Foo" and "Baz".
});

Exporting a Default Object

Astute readers will notice that the above notation does not allow for the export of a default object. This is because the keys of the top level object will always be used as the named exports for the injected module.

const importMapper = new ImportMapper({
    'someObject': {label: 'this is an object'}
});

importMapper.register();

import('someObject').then(module => console.log(module.label));

Pass the module content into the static method ImportMapper.forceDefault() and use the return value to get this behavior:

const importMapper = new ImportMapper({
    'someObject': ImportMapper.forceDefault({label: 'this is an object'})
});

importMapper.register();

import('someObject').then(module => console.log(module.default));

Methods

ImportMapper.constructor(modules)

Create a new ImportMapper.

Parameters

  • modules - A list of modules to inject

    May be one of the following:

    • An object, keyed by module name, each value is an object where the keys are the module's exports.
    • An array of module names to require() and map automatically.

Returns

A newly constructed ImportMapper object

ImportMapper.register()

Register the imports.

Parameters

none

Returns

none

ImportMapper.forceDefault(object)

Static method, returns an object that will be treated as the default export from the module.

Parameters

  • object - The object to use as the default export

Returns

Returns a wrapped module object.

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago

0.0.0

1 year ago