Comment on page
Application plugins
To create a plugin - means to create a programmable proxy between original function and the function caller. Plugin can modify original function arguments and return value.
Instruction
Example
- 1.Understand which class member you would like to proxy. Retrieve this class namespace by looking at it's leading comments.
- 2.
member-function
,member-properties
,static-member
it requires an additional configuration object with method or a property name mapped to the proxy implementation.class
it expects the proxy implementation without any configuration objects.
- 3.
- 4.
- 1.Use namespace you obtained at the step 1).
- 2.Use the plugin type you defined at the step 2).
- 3.Pay attention to configuration option of your desired plugin type.
- 5.Take a look at the reference and define a proxy implementation based on your proxy type. Make sure you are passing in the correct arguments.
- 6.Implement the proxy function according to your intention.
You can create class members that do not exist in the original classes. It is useful when you need some life-cycle member functions that are not present in the original class.
Remember to call the
callback
even if the original member is not present, that will make your plugin compatible with other plugins around the same member, by calling them after your plugin finishes its work.The main purpose of this plugin is to inject additional fields
base_grand_total
and base_currency_code
into the Cart.query.js
file's class method _getCartTotalsFields
return value.- 1.The class
CartQuery
declared inCart.query.js
is bind to a namespaceQuery/Cart
. - 2.We plan on modifying the class method, therefore we use
member-function
proxy type. It is special and requires a configuration object. It requires a method name as a key. - 3.Create a new file
CartQuery.plugin.js
insrc/plugin
, pay attention toplugin
post-fix. - 4.Define an
export default
object:- 1.Use our namespace key from the step 1) -
Query/Cart
. - 2.Use the plugin type from step 2) -
member-function
. - 3.As stated in 2) the method we intend to modify is
_getCartTotalsFields
therefore we declare it in themember-function
configuration object.
- 5.Proxy implementation function of
member-function
type takes following arguments:args
,callback
andinstance
. We do not need to call any other methods of theCartQuery
class instance, therefore, we can omit the last argument. - 6.Call the original method passing in the original arguments to get the original return value. This is done by calling
callback(...args)
. Then, we extend the original return value with two additional fields:base_grand_total
andbase_currency_code
.
const addBaseFields = (args, callback) => {
return [
...callback(...args),
'base_grand_total',
'base_currency_code'
];
};
export default {
'Query/Cart': {
'member-function': {
_getCartTotalsFields: addBaseFields
}
}
};
Instruction
Example
- 1.Understand which function you would like to proxy. Retrieve this function namespace by looking at it's leading comments.
- 2.
- 3.
- 4.
- 1.Use namespace you obtained at the step 1).
- 2.Use the plugin type you defined at the step 2).
- 5.Take a look at the reference and define a proxy implementation based on your proxy type. Make sure you are passing in the correct arguments.
- 6.Implement the proxy function according to your intention.
The main purpose of this plugin is to inject a new field
gtm
into the file's Config.reducer.js
reducer ConfigReducer
initial state. We know, that the function getInitialState
is responsible for that.- 1.The function
getInitialState
declared inConfig.reducer.js
is bind to a namespaceStore/Config/Reducer/getInitialState
. - 2.We plan on modifying the function assignment, therefore we use
function
proxy type. - 3.Create a new file
ConfigStore.plugin.js
insrc/plugin
, pay attention to plugin post-fix. - 4.Define an
export default
object:- 1.Use our namespace key from the step 1) -
Store/Config/Reducer/getInitialState
. - 2.Use the plugin type from step 2) -
function
.
- 5.Proxy implementation function of
function
type takes following arguments:args
,callback
andcontext
. We have no intention to interact with that function context, therefore, we can omit the last argument. - 6.Call the original method passing in the original arguments to get the original return value. This is done by calling
callback(...args)
. Then, we extend the original return value with one additional filedgtm
.
import BrowserDatabase from 'Util/BrowserDatabase';
const addGtmToConfigReducerInitialState = (args, callback, instance) => {
// We need to make sure the field "gtm" is an object
const { gtm } = BrowserDatabase.getItem('config') || { gtm: {} };
return {
...callback(...args),
gtm
};
};
export default {
'Store/Config/Reducer/getInitialState': {
'function': addGtmToConfigReducerInitialState
}
};
Plugins allow you to proxy any function or class of the application, which is bind to a namespace. To bind a an object to a namespace, it should have a leading comment starting with
@namespace
. Upon bind to a namespace one or multiple proxy types will become available.To bind a class to a namespace, add leading comment to a class. Like this:
/* @namespace Component/AddToCart/Container */
export class AddToCartContainer extends PureComponent {
// ...
}
- class methods -
member-function
- class properties -
member-properties
- static methods of a class -
static-member
- class instance itself -
class
To bind a function declaration to a namespace add leading comment to it. Like this:
/* @namespace Util/Validation/validateHandler */
function validateHandler(/** ... */) {
// ...
}
To bind functions assignment to a namespace:
/** @namespace Component/AddToCart/Container/mapStateToProps */
export const mapStateToProps = (state) => ({
// ...
});
You can also do it for arrow functions passed as an argument:
fetch(/** ... */).then(
/** @namespace Component/Braintree/Component/fetchThen */
() => { /** ... */ }
);
- function -
function
The application plugin declarations must be located inside of your extension's folder
src/plugin
. To declare a plugin inside of this folder, you must name it with a plugin
post-fix. For example: CartQuery.plugin.js
.For a plugin to work, it should export default an object of configuration. The configuration object is structured the following way:
- object keys are the namespaces you intend to apply proxy to
- object values are objects, which define the type of proxy to apply
For example:
export default {
'Framework/Component/App/Component': {
'class': proxyImplmentations,
'member-property': {
contextProviders: proxyImplmentations
}
}
};
In this case, the object has only one key -
Framework/Component/App/Component
which references an object bind to this namespace. We know this object is a class declaration, therefore we are now allowed to use the class-declaration proxy types. We utilize class
and member-property
types. The proxy types
member-function
, member-properties
, static-member
require additional configuration object. This object is structured as follows:- object keys are the method or property names you want to provide a proxy for
- object values are proxy function implementations
Other proxy types can be assigned to a proxy function implementation directly.
The
proxyImplmentations
used in the example can be:- A function implementing a proxy
- An object with
position
andimplementation
keys, where:position
is a numerical position of a plugin (default is100
)implementation
is a function implementing a proxy
You can also provide an array of above types.
Each proxy type expects a function with a different set of arguments. Here is an overview of function implementations for each proxy type:
member-function
member-properties
static-member
class
function
The class method proxy implementation function takes:
- An array of arguments from the caller
- Callback - an original method
- Instance - the original class instance
An example of such function is:
(args, callback, instance) => {
// TODO: implement
}
The class property proxy implementation function takes:
- Member - an original value of the class property
- Instance - the original class instance
An example of such function is:
(member, instance) => {
// TODO: implement
}
The static class method proxy implementation function takes:
- An array of arguments from the caller
- Callback - an original method
An example of such function is:
(args, callback) => {
// TODO: implement
}
The class proxy implementation function takes:
- Class - a class you intend to modify (not an instance!)
An example of such function is:
(Class) => {
// TODO: implement
}
The function proxy implementation function takes:
- An array of arguments from the caller
- Callback - an original method
- Context - the original context of a function
An example of such function is:
(args, callback, context) => {
// TODO: implement
}
Last modified 3yr ago