Skip to content

Instantly share code, notes, and snippets.

@developit
Created March 25, 2017 18:24
Show Gist options
  • Save developit/63466862f1aa808b1438ca86019eb9bd to your computer and use it in GitHub Desktop.
Save developit/63466862f1aa808b1438ca86019eb9bd to your computer and use it in GitHub Desktop.
factory-loader

Factory Loader

This is a tiny webpack loader that invokes a given module with another as an argument.

What's that useful for? Dependency Injection! Maybe this is how we can solve the VDOM fragmentation issue.

Example

Here's a library-agnostic VDOM component. Notice that it doesn't import react/preact/inferno/whatever - instead, it takes the VDOM library as an argument.

awesome-list.js:

export default ({ createElement, cloneElement, Component }) => {
  // Example pure functional Component:
  const Item = props => (
    <li>{props.item}</li>
  );

  // Example stateful/classful Component:
  return class AwesomeList extends Component {
    render() {
      return (
        <ul>
        { this.props.items.map( item =>
          <Item item={item} />
        ) }
        </ul>
      );
    }
  }
}

app.js - in our app, we import preact and the component. In order to "late-bind" the component to Preact, we run it through factory-loader:

import { h, render } from 'preact';
import AwesomeList from 'factory-loader?module=preact!./awesome-list';

render((
  <AwesomeList items={['a', 'b', 'c']} />
), document.body);

factory-loader is extremely simple. It just does this:

var factory = require('whatever-you-called-it-on.js')
module.exports = factory(require('value-of-module-parameter.js'));

In the above example, it would (literally) produce this module:

var factory = require('./awesome-list');
module.exports = (factory.default || factory)(require('preact'));

The factory.default || factory bit there is to account for ES Module default exports in Webpack 2.

var loaderUtils = require("loader-utils");
(module.exports = function() {}).pitch = function(req) {
var q = loaderUtils.parseQuery(this.query);
this.cacheable && this.cacheable();
return "var req = require("+JSON.stringify("!!"+req)+");\n"+
"module.exports = (req['default'] || req)(require("+JSON.stringify(q.module)+"))";
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment