instrument-context-module
v0.1.0
Published
A utility for adding instrumentation to [Webpack] dynamic [context modules](https://webpack.js.org/guides/dependency-management/#require-context).
Downloads
3
Readme
#Instrument Context Module
A utility for adding instrumentation to Webpack dynamic context modules.
Usage
Certain Webpack plugins use a set of regular expressions to filter modules, a context expression to match a directory and a module expression to filter files within the directory.
instrumentContextModule
is used to wrap a set of regular expressions used by webpack plugins to enable monitoring the matches found by the plugins.
const handleContext = (context, contextRegEx, moduleRegEx) =>
console.log('in context ' + context);
const handleModule = (module, context, contextRegEx, moduleRegEx) =>
console.log('include module ' + module);
const wrap = instrumentContextModule(handleContext, handleModule);
const moduleRegExp = wrap.module(/(foo|bar)\.js$/);
const contextRegExp = wrap.module(/some_module/);
const plugin = new webpack.ContextReplacementPlugin(
contextRegExp,
moduleRegExp,
);
The handleContext
function is called for the first module match within a context. It receives as arguments in order:
- The path of the context.
- The regular expression that matched the context.
- The regular expression that matched the module.
The handleModule
function is called for every module match. It receives as arguments in order:
- The require path of the module, this may be relative to the context.
- The path of the context.
- The regular expression that matched the context.
- The regular expression that matched the module.
Since the result of instrumentContextModule
is stateful, a new instance must be created for each plugin to be instrumented.
Examples
Logging dynamically included modules.
With a non-restrictive module regular expression, an instrumented ContextReplacementPlugin
can be used to simply observe and log what is included in a certain context.
Webpack config
// webpack.config.babel.js
//
import {join, relative, dirname} from 'path';
import webpack from 'webpack';
import instrumentContextModule from 'instrument-context-module';
import escapeRegExp from 'escape-string-regexp';
import nearest from 'find-nearest-file';
const ROOT = dirname(nearest('package.json'));
const logInclude = instrumentContextModule(
(context, contextRegEx, moduleRegEx) =>
console.log(`🗃 Including ${moduleRegEx} in ${relative(ROOT, context)}`),
(module, context) => console.log(` ${module.slice(2)}`),
);
const iconPath = join(ROOT, 'src', 'asset', 'icon');
export default {
// Existing webpack config.
context: ROOT,
plugins: [
new webpack.definePlugin({
process.env.ICON_PATH: JSON.stringify(iconPath),
}),
new webpack.ContextReplacementPlugin(
logInclude.context(new RegExp(`^${escapeRegExp(iconPath)}$`, 'i')),
logInclude.module(/\.icon\.svg$/),
)
],
};
Component file
const icons = require.context(process.env.ICON_PATH, false, /\.icon\.svg$/);
Console output
🗃 Including /\.icon\.svg$/ in src/asset/icon
arrow-down.icon.svg
arrow-left.icon.svg
arrow-right.icon.svg
arrow-up.icon.svg
chevron-left.icon.svg
...
--
Logging dynamically ignored modules.
(Waiting on https://github.com/webpack/webpack/pull/4418)
IgnorePlugin
can be instrumented to log which modules are excluded.
Note that the arguments to
IgnorePlugin
reversed compared toContextReplacementPlugin
.
Webpack config
// webpack.config.babel.js
//
import {join, relative, dirname} from 'path';
import webpack from 'webpack';
import instrumentContextModule from 'instrument-context-module';
import nearest from 'find-nearest-file';
const ROOT = dirname(nearest('package.json'));
const LOCALES = ['en', 'fr'];
const logIngore = instrumentContextModule(
(context, contextRegEx, moduleRegEx) =>
console.log(`🚫 Ignoring ${moduleRegEx} in ${relative(ROOT, context)}`),
(module) => console.log(` ${module.slice(2)}`),
);
export default {
// Existing webpack config.
context: ROOT,
plugins: [
new new webpack.IgnorePlugin(
logIngore.module(new RegExp(`^\\.\\/(?!${LOCALES.join('|')}).*\\.js$`)),
logIngore.context(/moment[\/\\]locale$/),
)
],
};
Console output
🚫 Ignoring /^\.\/(?!en|fr).*\.js$/ in node_modules/moment/locale
af.js
ar-dz.js
ar-ly.js
ar-ma.js
ar-sa.js
ar-tn.js
ar.js
az.js
be.js
bg.js
bn.js
bo.js
br.js
...