This library allows consumers to decorate the behavior of JavaScript modules via module proxies that are aliased through Webpack configuration.
This library has behavior similar to native JavaScript decorator support, except that instead of requiring decorator annotations to be used within user-code, this library can inject your decorators dynamically into a proxied ES module.
This provides a level of metaprogramming support for scenarios where you may need to inject cross-cutting functionality into your codebase without requiring you to sprinkle annotations throughout the codebase (or even for situations where you may not own the code in question to begin with).
This repo currently supports two module proxies:
react
(in packagewebpack-decorators-react
)react-dom
(in packagewebpack-decorators-react-dom
)
- Install the package
npm install webpack-decorators-react
ornpm install webpack-decorators-react-dom
- Add the desired
react
orreact-dom
configs (examples inreactDecoratorConfig
) to your webpack.config.js
For react:
resolve: {
alias: {
react$: require.resolve(`webpack-decorators-react`),
"___react-original___$": require.resolve(`react`),
},
}
For react-dom:
resolve: {
alias: {
"react-dom$": require.resolve(`webpack-decorators-react-dom`),
"___react-dom-original___$": require.resolve(`react-dom`),
},
}
For react-dom/server:
resolve: {
alias: {
"react-dom/server$": require.resolve(`webpack-decorators-react-dom-server`),
"___react-dom-server-original___$": require.resolve(`react-dom/server`),
},
}
- Register your custom decorators
const { registerDecorator } = require('webpack-decorators');
const decorator = {
createElement: function(originalFunc, ...args) {
console.log('[decorator]: Decorated React.createElement...');
return originalFunc(...args);
}
}
const decorator2 = {
createElement: function(originalFunc, ...args) {
console.log('[decorator2]: Decorated React.createElement...');
return originalFunc(...args);
},
Component: function(originalFunc, ...args) {
console.log('[decorator2]: Decorated React.Component...');
return originalFunc(...args);
}
}
registerDecorator('react', decorator, 'createElement');
registerDecorator('react', decorator2, 'createElement', 'Component');
NOTE: decorators are pipelined and executed in the order in which they are defined.
Given the above order of registrations, when calling something like
React.createElement
in your code, the following call chain will result:
decorator2.createElement
decorator.createElement
React.createElement
(original module)