npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dumber-module-loader

v1.2.5

Published

A modern module loader (loose AMD implementation), designed to work with dumber.

Downloads

383

Readme

dumber-module-loader CI

A modern AMD module loader, used by dumber bundler internally.

dumber-module-loader is a loose AMD implementation, does not strictly follow the AMD spec.

For users of dumber bundler, you only need to know that the internal module loader is an AMD loader, similar to requirejs. The good old AMD gives dumber bundler intuitive code splitting, and flexible runtime composition.

Our violation on AMD spec:

  • AMD spec doesn't allow defining module id starting with '..', define('../package.json', ...). We allow it. This is to support dependency '../package.json' that could be required by src/app.js. We say module id '../package.json' is above surface.
  • Only supports plugin's load() function, doesn't support normalize() function, doesn't support load.fromText() function (not in spec, but some requirejs plugins use it). Note there is built-in support of traditional text! and json! plugins out of the box.
  • Special RegExp support for mass require, mainly for test runner.
requirejs([/\.spec$/], function() {
});

Our touch on AMD:

  • Mimic Node.js module resolving behaviour so dumber bundler can do less work.

    • require('foo/bar') could load module foo/bar, foo/bar.js, foo/bar.json, foo/bar/index.js, or foo/bar/index.json.
    • if there is a package.json file in folder foo/bar/, it can load file foo/bar/resolved/main.js, dumber will build an alias foo/bar/index to foo/bar/resolved/main.js.
  • Two module spaces: user (default, for local source file) and package (for npm packages and local packages).

    • module in user space can acquire user or package modules.
    • module in package space can only acquire package modules.
    • both user and package space can contain module with the same id. This is designed to avoid local src/util.js over-shadowing Node.js core module util.
  • Full support of Node.js circular dependencies (for packages like yallist, note yallist 3.0.3 has removed circular dependency).

  • Besides normal plugin, we support ext plugin which targets ext name.

    • by default, dumber-module-loader ships with ext plugins for json/html/svg/css/wasm (do not yet support wasm importObjects).
    • all ext plugins should resolve the underneath content using one of our three predefined plugins: text!, json!, and raw!.
    • text!some.fie will resolve to the text content of the file, at runtime it uses fetch API reponse.text() to get the content.
    • json!some.fie will resolve to the parsed json, at runtime it uses fetch API reponse.json() to parse the content.
    • raw!some.fie will resolve to fetch API reponse, note the result is a promise, not final value.
    • for instance, our default html support is implemented as
    define('ext:html', {load: function(name, req, load) {
      req(['text!' + name], text => load(text));
    }});
    • note, our default css support is just returning the text content, same as our html support. By default, it doesn't inject style sheet to html head. However dumber bundler by default overrides the default 'ext:css' plugin to support style sheet injection.

Difference from requirejs:

  • No multi-contexts.
  • Only supports config on baseUrl, paths, and bundles.
  • data-main attribute on script tag doesn't affect baseUrl, data-main is purely a module id.
  • paths support is simplified.
    • supports absolute path like "foo": "/foo"
    • supports normal "foo": "common/foo", resolve foo/bar/lo to common/foo/bar/lo. Note we treat common/foo/bar/lo as the real module id, it could result to an existing known module, otherwise go through remote fetch.
    • doesn't support "foo": ["common/foo", "shared/foo"] the fail-over array.
    • relative module resolution is simplified. This is a breaking change. We changed the behaviour because we think our behaviour is less surprising.
define('common/foo', ['./bar'], function (bar) { /* ... */ });
requirejs.config({paths: {'foo': 'common/foo'}});
requirejs(['foo'], function (foo) {
  // requirejs resolves './bar' to 'bar',
  // we resolves './bar' to 'common/bar'.
});
  • No automatic commonjs wrapping for runtime fetched module. For any module loaded remotely at runtime, we only support AMD anonymous module format, unless you supply a plugin to deal with the raw content.
  • bundles config is different, it needs two arrays, 'user' and 'package' for the two module spaces.
    • for example, {"a-bundle": {"user": ['a', 'b'], "package": ["lodash", "jquery"]}}.
    • if no module in package space, it can be written in requirejs compatible format, {"a-bundle": ['a', 'b']}.
  • require([...], callback, errback) doesn't support optional config, errback only gets one error object.
  • We only support browser/Worker/Node.js environments, didn't test on Rhino or any other environments.
  • Note there is no support of package or map config.
  • There is no support of shim. Shim is all done by dumber bundler.

API

There globals, define, requirejs (same as require).

define(id? :string, deps?: string[], callback: function | any)

Ref: https://github.com/amdjs/amdjs-api/blob/master/AMD.md

When id is absent, it defines an anonymous module. Anonymous module is only for runtime dynamically module loading.

requirejs(deps: string[], callback?: function, errback?: function)

Ref: https://github.com/amdjs/amdjs-api/blob/master/require.md

When errback is called, it only gets one error object (an instance of Error);

define.switchToUserSpace()

Switch to user module space, define() call after this will define module in user space. User module space is the default module space.

define.switchToPackageSpace()

Switch to package module space, define() call after this will define module in package space.

define.currentSpace()

Returns "user" if current space is user space, or "package" if current space is packaeg space. Current space only affects define() call, it doesn't affect requirejs() call.

define.nameAnonymous(id)

Provide a module id for the last anonymous module defined like define([deps], function() {}). The new module id is defined on current space (either user space or package space). When there is no anonymous module defined, this method will do nothing.

define.reset()

Reset all config, remove all registered and defined modules, switch to default user space.

requirejs.config(options)

Options supports:

1. optional baseUrl

The default baseUrl is empty string "", the behaviour is same as requirejs default baseUrl "./".

When dumber-module-loader tries to load a missing module 'foo/bar' at runtime, it will call fetch API fetch("foo/bar.js").

The real url is relative to app's current route. If there is <base href="/some/folder/"> in html head, the real url is relative to "/some/folder/", note the ending "/" is significant.

If you set baseUrl to some/folder, the resulting fetch call fetch("some/folder/foo/bar.js") is still relative to current route or <base> tag.

To ignore app's current route and <base> tag, set baseUrl to an absolute value like /some/folder, the resulting fetch call fetch("/some/folder/foo/bar.js") hits absolute URL.

2. optional paths

Similar to requirejs paths, but simplified, see above.

3. optional bundles

Tells dumber-module-loader what remote bundle file contains certain missing module. Note user and package space modules are listed separately.

nameSpace is optional, it's designed to load foreign bundle file at runtime.

When nameSpace is in use, all modules in user module space will be prefixed with optional-name-space/. For instance, app module is name spaced as optional-name-space/app. Note all modules in package module space are not affected, for instance, lodash will still be lodash.

bundles: {
  'app-bundle': {
    nameSpace: 'optional-name-space',
    user: ['app', 'app.html', 'util', 'common/index'],
    package: ['lodash', 'lodash/map', 'util']
  }
}

for bundles only contain user space modules, a simplified config can be used.

bundles: {
  'app-bundle': ['app', 'app.html', 'util', 'common/index']
}

requirejs.definedValues()

Return all defined module values {"id": val, "id2": val2}, excluding registered but not evaluated. This is to match existing behaviour of requirejs and webpack. Note if there is duplicated module id in user and package space, the user space module value will show up.

requirejs.defined(id: string)

Check whether a module id is defined, excluding registered but not evaluated. This is to match existing behaviour of requirejs.

requirejs.specified(id: string)

Check whether a module id is defined or registered but not evaluated. This is to match existing behaviour of requirejs.