val-loader

Executes the given module to generate source code on build time

Install

npm i -D val-loader

Usage

The module that is loaded with this loader must stick to the following interfaces

##

The loaded module must export a function as default export with the following Function Interface

module.exports = function () {...};

Modules transpiled by Babel are also supported

export default function () {...};

Function Interface

The function will be called with the loader options and must either return

{Object}

Following the Object Interface

{Promise}

Resolving to an {Object} following the Object Interface

Object Interface

Name
Type
Default
Description
Name
code
Type
{String|Buffer}
Default
undefined
Description
(Required) The code that is passed to the next loader or to webpack
Name
sourceMap
Type
Default
undefined
Description
(Optional) Will be passed to the next loader or to webpack
Name
ast
Type
{Array<{Object}>}
Default
undefined
Description
(Optional) An Abstract Syntax Tree that will be passed to the next loader. Useful to speed up the build time if the next loader uses the same AST
Name
dependencies
Type
{Array<{String}>}
Default
[]
Description
An array of absolute, native paths to file dependencies that need to be watched for changes
Name
contextDependencies
Type
{Array<{String}>}
Default
[]
Description
An array of absolute, native paths to directory dependencies that need to be watched for changes
Name
cacheable
Type
{Boolean}
Default
false
Description
Flag whether the code can be re-used in watch mode if none of the dependencies have changed

Options

val-loader itself has no options. The options are passed as they are (without cloning them) to the exported function

Examples

If you have a module like this

answer.js

function answer () {
  return {
    code: 'module.exports = 42;'
  }
};

module.exports = answer;

you can use the val-loader to generate source code on build time

webpack.config.js

module.exports = {
  ...
  module: {
    rules: [
      {
        test: require.resolve('path/to/answer.js'),
        use: [
          {
            loader: 'val-loader'
          }
        ]
      }
    ]
  }
};

Complete

A complete example of all available features looks like this

answer.js

const ask = require('./ask.js');
const generate = require('./generate.js');

function answer(options) {
  return ask(options.question)
    .then(generate)
    .then(result => ({
      ast: result.abstractSyntaxTree,
      code: result.code,
      // Mark dependencies of answer().
      // The function will be re-executed if one of these
      // dependencies has changed in watch mode.
      dependencies: [
        // Array of absolute native paths!
        require.resolve('./ask.js'),
        require.resolve('./generate.js')
      ],
      // Flag the generated code as cacheable.
      // If none of the dependencies have changed,
      // the function won't be executed again.
      cacheable: true
      sourceMap: result.sourceMap,
    })
  );
}

module.exports = answer;

webpack.config.js

module.exports = {
  ...
  module: {
    rules: [
      {
        test: require.resolve('path/to/answer.js'),
        use: [
          {
            loader: 'val-loader',
            options: {
              question: 'What is the meaning of life?'
            }
          }
        ]
      }
    ]
  }
};

Maintainers


Juho Vepsäläinen


Joshua Wiens


Kees Kluskens


Johannes Ewald