Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Repository files navigation

npmnodetestscoveragediscussionsize

val-loader

A webpack loader that executes a given module and returns the result of the execution at build-time, when the module is required in the bundle. In this way, the loader changes a module from code into a result.

Another way to view val-loader is that it allows users to implement custom loader logic without needing to write a full custom loader.

The target module is called with two arguments: (options, loaderContext)

  • options: The loader options (for instance provided in the webpack config. See the example below).
  • loaderContext: The loader context.

Getting Started

To begin, you'll need to install val-loader:

npm install val-loader --save-dev
yarn add -D val-loader
pnpm add -D val-loader

Then, add the loader to your webpack configuration. For example:

target-file.js

module.exports=(options,loaderContext)=>{return{code: "module.exports = 42;"};};

webpack.config.js

module.exports={module: {rules: [{test: /target-file.js$/,use: [{loader: `val-loader`,},],},],},};

src/entry.js

constanswer=require("target-file");

Finally, run webpack using the method you normally use (e.g., via CLI or an npm script).

Options

executableFile

Type:

typeexecutableFile=string;

Default: undefined

Allows to specify path to the executable file.

data.json

{
"years": "10"
}

executable-file.js

module.exports=functionyearsInMs(options,loaderContext,content){const{ years }=JSON.parse(content);constvalue=years*365*24*60*60*1000;return{cacheable: true,code: "module.exports = "+value,};};

webpack.config.js

module.exports={module: {rules: [{test: /\.(json)$/i,rules: [{loader: "val-loader",options: {executableFile: path.resolve(__dirname,"fixtures","executableFile.js",),},},],},{test: /\.json$/i,type: "asset/resource",},],},};

Return Object Properties

Targeted modules of this loader must export a function that returns an object, or a Promise resolving to an object (e.g. async function), containing a code property at a minimum, but can also include additional properties.

code

Type:

typecode=string|Buffer;

Default: undefinedRequired

Code passed along to webpack or the next loader that will replace the original module.

sourceMap

Type:

typesourceMap=object;

Default: undefined

A source map passed along to webpack or the next loader.

ast

Type:

typeast=Array<object>;

Default: undefined

An Abstract Syntax Tree (AST) that will be passed to the next loader. Useful to speed up the build time if the next loader uses the same AST.

dependencies

Type:

typedependencies=Array<string>;

Default: []

An array of absolute, native paths to file dependencies that should be watched by webpack for changes.

Dependencies can also be added using loaderContext.addDependency(file: string).

contextDependencies

Type:

typecontextDependencies=Array<string>;

Default: []

An array of absolute, native paths to directory dependencies that should be watched by webpack for changes.

Context dependencies can also be added using loaderContext.addContextDependency(directory: string).

buildDependencies

Type:

typebuildDependencies=Array<string>;

Default: []

An array of absolute, native paths to directory dependencies that should be watched by webpack for changes.

Build dependencies can also be added using loaderContext.addBuildDependency(file: string).

cacheable

Type:

typecacheable=boolean;

Default: false

If true, specifies that the code can be reused in watch mode if none of the dependencies have changed.

Examples

Simple

In this example the loader is configured to operate on a file name of years-in-ms.js, execute the code, and store the result in the bundle as the result of the execution. This example passes years as an option, which corresponds to the years parameter in the target module's exported function:

years-in-ms.js

module.exports=functionyearsInMs({ years }){constvalue=years*365*24*60*60*1000;// NOTE: this return value will replace the module in the bundlereturn{cacheable: true,code: "module.exports = "+value,};};

webpack.config.js

module.exports={module: {rules: [{test: require.resolve("src/years-in-ms.js"),use: [{loader: "val-loader",options: {years: 10,},},],},],},};

In the bundle, requiring the module then returns:

importtenYearsMsfrom"years-in-ms";console.log(tenYearsMs);// 315360000000

Modernizr

Example shows how to build modernizr.

entry.js

importmodenizrfrom"./modernizr.js";

modernizr.js

constmodernizr=require("modernizr");module.exports=function(options){returnnewPromise(function(resolve){// It is impossible to throw an error because modernizr causes the process.exit(1)modernizr.build(options,function(output){resolve({cacheable: true,code: `var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; ${output} modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;`,});});});};

webpack.config.js

constpath=require("path");module.exports={module: {rules: [{test: path.resolve(__dirname,"src","modernizr.js"),use: [{loader: "val-loader",options: {minify: false,options: ["setClasses"],"feature-detects": ["test/css/flexbox","test/es6/promises","test/serviceworker",],},},],},],},};

Figlet

Example shows how to build figlet.

entry.js

import{defaultasfiglet}from"./figlet.js";console.log(figlet);

figlet.js

constfiglet=require("figlet");functionwrapOutput(output,config){letfigletOutput="";if(config.textBefore){figletOutput+=encodeURI(`${config.textBefore}\n`);}output.split("\n").forEach((line)=>{figletOutput+=encodeURI(`${line}\n`);});if(config.textAfter){figletOutput+=encodeURI(`${config.textAfter}\n`);}return`module.exports = decodeURI("${figletOutput}");`;}module.exports=function(options){constdefaultConfig={fontOptions: {font: "ANSI Shadow",horizontalLayout: "default",kerning: "default",verticalLayout: "default",},text: "FIGLET-LOADER",textAfter: null,textBefore: null,};constconfig=Object.assign({},defaultConfig,options);returnnewPromise(function(resolve,reject){figlet.text(config.text,config.fontOptions,(error,output)=>{if(error){returnreject(error);}resolve({cacheable: true,code: "module.exports = "+wrapOutput(output,config),});});});};

webpack.config.js

constpath=require("path");module.exports={module: {rules: [{test: path.resolve(__dirname,"src","figlet.js"),use: [{loader: "val-loader",options: {text: "FIGLET",},},],},],},};

Contributing

We welcome all contributions! If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.

CONTRIBUTING

License

MIT

About

val loader module for webpack

Topics

Resources

Contributing

Stars

185 stars

Watchers

9 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages