0.1.2 • Published 6 years ago

paxter v0.1.2

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

Paxter

Paxter is a middleware system for Webpack configuration. It aims to move Webpack configuration into the convention-over-configuration mindset, making it easier to get up and running with a new Webpack-based project while still allowing complete customization of your Webpack config.

Let's face it: Webpack configuration sucks. Configuration files can become huge and unwieldy even for typical technology stacks. Wouldn't it be great if there were a way to automatically detect the languages, frameworks, and libraries you are using, and begin with typical configurations?

This is what Paxter does. Paxter sets the groundwork for middleware to modify the Webpack configuration object with sensible defaults.

Usage

$ npm install -D paxter

The only thing you need to do is use a call to paxter() as your Webpack configuration, and then npm install whatever middlewares you need for your project:

// webpack.config.json:
const paxter = require('paxter');
module.exports = paxter();

Now, install your middleware (i.e. any package beginning with paxter-):

$ npm install -D paxter-babel-env paxter-sass paxter-pug

That's it! Webpack will now know what to do with ES6, SASS, and Pug files, with no additional configuration required.

Middleware configuration

Middlewares can be customized with further configuration if necessary. The first parameter to paxter() provides configuration to each middleware:

module.exports = paxter({
  "babel-env": {
    target: "node 6"
  }
});

The object's keys must match the middleware's name (minus the package- prefix). Each middleware defines its own configuration format. See the middleware documentation for details.

A value of false will disable that middleware.

Starter Webpack configuration object

To provide a starter Webpack configuration (an object that Paxter middlewares will modify, instead of creating a new one), pass it as the second parameter to the paxter() method:

module.exports = paxter(
  { /* Paxter configuration */ },
  {
    entry: "...",
    output: { /* ... */ },
    module: {
      rules: [ /* ... */ ]
    }
  }
);

Values provided in the starter configuration will be overwritten (middlewares are encouraged to use a "merge" strategy to not completely overwrite configurations, but this is not guaranteed. See your middleware for details).

Further configuration modifications

Because paxter() simply returns a configuration object, you are free to continue modifying it before it is exported. Paxter provides several utility methods that make configuration modifications easier:

  • paxter.get

    paxter.get(config, path)

    Gets the value at path of the config object.

    const paxter = require('paxter');
    const config = paxter();
    
    const hints = paxter.get(config, 'performance.hints');

    Paxter uses the _.get method provided by lodash (see https://lodash.com/docs#merge for details).

  • paxter.set

    paxter.set(config, path, value)

    Sets the value at path of the config object. The value will completely overwrite the current value at path (as opposed to paxter.merge).

    const paxter = require('paxter');
    const config = paxter();
    
    paxter.set(config, 'performance.hints', 'warning');

    The config object will be modified directly. The modified config value will also be returned.

    Paxter uses the _.set method provided by lodash (see https://lodash.com/docs#merge for details).

  • paxter.push

    paxter.push(config, path, value)

    Pushes value onto the array at path of the config object. If there is no array at path, one will be created.

    const paxter = require('paxter');
    const config = paxter();
    
    paxter.push(config, 'performance.hints', 'warning');
  • paxter.unshift

    paxter.push(config, path, value)

    Same as paxter.push, except it adds the value to the beginning of the array.

  • paxter.merge

    paxter.merge(config, path, value)

    Merges value into the config property specified by path.

    const paxter = require('paxter');
    const config = paxter();
    
    paxter.merge(config, 'performance', {
      hints: "warning",
      maxAssetSize: 200000
    });
    
    // If `config` already had a `performance` property with other values, they will be preserved. 
    
    module.exports = config;

    Paxter uses the _.merge method provided by lodash (see https://lodash.com/docs#merge for details).

module.rules modifications

Because a Webpack configuration's module.rules property can be especially difficult to work with (it may not be easy to know which rules entry to modify), Paxter provides a more convenient way to modify the module.rules property.

The third parameter to paxter() is a callback function that will receive the middleware-modified configuration object. This object will be a standard Webpack configuration object, however the configuration's module.rules property will be an object (instead of an array), with each key corresponding to the name of the middleware that created it. You can modify this object in any way, including with the utility methods mentioned above, as long as the return object is a valid Webpack configuration.

const paxter = require('paxter');

module.exports = paxter(
  { /* starter configuration */ },
  { /* middleware configuration */ },
  config => {
    paxter.set(config, 'module.rules.sass.test', /\.s[ca]ss$/);
    return config;
  }
);

Developing middleware

Paxter middlewares are public npmjs.org node modules named with the prefix paxter-. Middleware modules must export a function that returns a Webpack configuration object. The function will receive the current Webpack config object (which may be an empty object {}), which it may modify in any way as long as the function's return value is a valid Webpack configuration.

The only exception to this is the module.rules property, which Paxter treats as an object instead of an array.
This object's keys are middleware package names (minus the paxter- prefix), and the values are the module.rules entries. Your middleware may add its own entry to this object, using your package's name as the key, or you may modify entries of other packages (but play nice!). You may use an array to create multiple rule entry objects (arrays will be recursively flattened).

The method also accepts a second options parameter, with the middleware options that were provided by the user in the call to paxter(). This value only contains the options specified for your middleware package. The third allOptions parameter provides all middleware options.

You can access the current Webpack 4 "mode" (development or production) using the paxter.mode property.

Paxter middleware packages should specify a peerDependency on paxter.

Example

// paxter-my-middleware/index.js:

let paxter = require('paxter');

module.exports = function(config, options) {
  // Modify the config in some way:
  config.target = 'web';
  
  // Modify the module rules as an object:
  config.module.rules['my-middleware'] = {
    test: /\.ext$/,
    loader: "some-loader"
  };
  
  // Or, use an array of module rules:
  config.module.rules['my-middleware'] = [
    { /* rule */ },
    { /* rule */ },
  ];
  
  // Do something different in development
  config.output === 'development' ? 'dev-output.js' : 'output.js';
  
  return config; 
}

License

MIT

Contributing

Please file a bug or make a pull request to contribute to Paxter core libraries.

To create a Paxter middleware, just create your own project and publish it using paxter- as the package name prefix.

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.2

6 years ago