मैगेंटो 2 कॉल "मिक्सिन्स" को कैसे लागू किया जाता है?


16

मैगेंटो 2 के रिक्जेस्ट आधारित ऑब्जेक्ट सिस्टम में "मिक्सिन्स" नामक एक सुविधा होती है। एक Magento 2 मिक्सिन नहीं है जो एक सॉफ्टवेयर इंजीनियर आमतौर पर मिक्सिन / विशेषता के रूप में सोचता है । इसके बजाय, एक Magento 2 मिक्सिन आपको एक वस्तु / मूल्य जो मुख्य प्रोग्राम द्वारा उपयोग किया जाता है, उससे पहले एक आवश्यकता मॉड्यूल द्वारा लौटाए गए ऑब्जेक्ट / मूल्य को संशोधित करने की अनुमति देता है। आप एक Magento 2 मिक्सिन को इस तरह कॉन्फ़िगर करते हैं (एक आवश्यकता-config -js फ़ाइल के माध्यम से)

var config = {
    'config':{
        'mixins': {
            //the module to modify
            'Magento_Checkout/js/view/form/element/email': {
                //your module that will do the modification
                'Pulsestorm_RequireJsRewrite/hook':true
            }
        }
    }
};

उसके बाद, आपके पास hook.js(या आपके द्वारा कॉन्फ़िगर किया गया कोई भी आवश्यकता मॉड्यूल),

define([], function(){
    console.log("Hello");
    return function(theObjectReturnedByTheModuleWeAreHookingInto){
        console.log(theObjectReturnedByTheModuleWeAreHookingInto);
        console.log("Called");
        return theObjectReturnedByTheModuleWeAreHookingInto;
    };
});

एक समारोह लौटें। Magento इस फ़ंक्शन को "मॉड्यूल" के संदर्भ में पास करते हुए कॉल करेगा, जिसे आप संशोधित करना चाहते हैं। हमारे उदाहरण में यह आवश्यकता के मॉड्यूल द्वारा लौटा दी गई वस्तु होगी Magento_Checkout/js/view/form/element/email। यह एक फ़ंक्शन या स्केलर मान भी हो सकता है (यह इस पर निर्भर करता है कि आवश्यकताएँ मॉड्यूल रिटर्न क्या है)।

यह सिस्टम mixinsइसलिए कहा जाता है क्योंकि यह आपको मूल व्यवहार की extendविधि का समर्थन करता है अगर ऑब्जेक्ट द्वारा लौटाया जाता है तो आप मिक्सिन को व्यवहार की तरह बना सकते हैं ।

define([], function(){
    'use strict';
    console.log("Hello");

    var mixin = {
        ourExtraMethod = function(){
            //...
        }
    };

    return function(theObjectReturnedByTheModuleWeAreHookingInto){
        console.log(theObjectReturnedByTheModuleWeAreHookingInto);
        console.log("Called");


        return theObjectReturnedByTheModuleWeAreHookingInto.extend(mixin);
    };
});

हालाँकि, सिस्टम ही मॉड्यूल ऑब्जेक्ट निर्माण में हुक करने का एक तरीका है।

प्रस्तावना समाप्त - क्या किसी को पता है कि मैगनेटो ने इस कार्यक्षमता को कैसे लागू किया है? रिक्वायरज वेबसाइट मिक्सिंस का उल्लेख नहीं करती है (हालाँकि Google को लगता है कि आप रिक्जेस्ट के प्लगइन पेज चाहते हैं )।

requirejs-config.jsफ़ाइलों के बाहर , Magento 2 के मुख्य जावास्क्रिप्ट में केवल mixinsतीन फ़ाइलों का उल्लेख है

$ find vendor/magento/ -name '*.js' | xargs ack mixins
vendor/magento/magento2-base/lib/web/mage/apply/main.js
73:                            if (obj.mixins) {
74:                                require(obj.mixins, function () {
79:                                    delete obj.mixins;

vendor/magento/magento2-base/lib/web/mage/apply/scripts.js
39:            if (_.has(obj, 'mixins')) {
41:                data[key].mixins = data[key].mixins || [];
42:                data[key].mixins = data[key].mixins.concat(obj.mixins);
43:                delete obj.mixins;

vendor/magento/magento2-base/lib/web/mage/requirejs/mixins.js
5:define('mixins', [
24:     * Adds 'mixins!' prefix to the specified string.
30:        return 'mixins!' + name;
76:     * Iterativly calls mixins passing to them
80:     * @param {...Function} mixins
84:        var mixins = Array.prototype.slice.call(arguments, 1);
86:        mixins.forEach(function (mixin) {
96:         * Loads specified module along with its' mixins.
102:                mixins   = this.getMixins(path),
103:                deps     = [name].concat(mixins);
111:         * Retrieves list of mixins associated with a specified module.
114:         * @returns {Array} An array of paths to mixins.
118:                mixins = config[path] || {};
120:            return Object.keys(mixins).filter(function (mixin) {
121:                return mixins[mixin] !== false;
126:         * Checks if specified module has associated with it mixins.
137:         * the 'mixins!' plugin prefix if it's necessary.
172:    'mixins'
173:], function (mixins) {
237:        deps = mixins.processNames(deps, context);
252:            queueItem[1] = mixins.processNames(lastDeps, context);

mixins.jsफ़ाइल एक RequireJS प्लगइन प्रतीत होता है (के आधार पर !...टिप्पणी में उल्लेख है - यह सही है), लेकिन यह नहीं 100% स्पष्ट है जब main.jsया scripts.jsMagento द्वारा लाया जाता है, या कैसे कस्टम mixinsविन्यास से यह बनाता है requirejs-config.jsश्रोता / हुक प्रणाली में ऊपर वर्णित।

क्या किसी के पास इस बात की व्याख्या है कि इस प्रणाली को कैसे लागू किया गया / लागू किया गया, एक आँख के साथ डीबग करने में सक्षम होने के कारण "मिक्सिन" क्यों लागू किया जा सकता है या नहीं?

जवाबों:


18

मैं सीधे आपके प्रश्नों पर जाना चाहता हूं और फिर मैं इसे स्पष्ट करने की कोशिश करूंगा कि आप वास्तव में मिक्सचर प्लगइन के साथ क्या कर सकते हैं । तो, पहले चीजें पहले।

कार्यान्वयन

यहां मुख्य बात यह है कि कुछ फ़ाइलों की लोडिंग प्रक्रिया को पूरी तरह से संभालने के लिए किसी भी आवश्यकता प्लग इन की क्षमता है। यह एक मॉड्यूल के निर्यात मूल्य को संशोधित करने की अनुमति देता है इससे पहले कि यह एक संकल्पित निर्भरता के रूप में पारित हो जाएगा।

इस स्केच के कार्यान्वयन पर एक नज़र डालें कि मैगेंटो कस्टम मिक्सइन प्लगइन वास्तव में क्या है:

// RequireJS config object.
// Like this one: app/code/Magento/Theme/view/base/requirejs-config.js
{
    //...

    // Every RequireJS plugin is a module and every module can
    // have it's configuration.
    config: {
        sampleMixinPlugin: {
            'path/to/the/sampleModule': ['path/to/extension']
        }
    }
}

define('sampleMixinPlugin', [
    'module'
] function (module) {
    'use strict';

    // Data that was defined in the previous step.
    var mixinsMap = module.config();

    return {
        /**
         * This method will be invoked to load a module in case it was requested
         * with a 'sampleMixinPlugin!' substring in it's path,
         * e.g 'sampleMixinPlugin!path/to/the/module'.
         */
        load: function (name, req, onLoad) {
            var mixinsForModule = [],
                moduleUrl = req.toUrl(name),
                toLoad;

            // Get a list of mixins that need to be applied to the module.
            if (name in mixinsMap) {
                mixinsForModule = mixinsMap[name];
            }

            toLoad = [moduleUrl].concat(mixinsForModule);

            // Load the original module along with mixins for it.
            req(toLoad, function (moduleExport, ...mixinFunctions) {
                // Apply mixins to the original value exported by the sampleModule.
                var modifiedExport = mixinFunctions.reduce(function (result, mixinFn) {
                        return mixinFn(result);
                }, moduleExport);

                // Tell RequireJS that this is what was actually loaded.
                onLoad(modifiedExport);
            });
        }
    }
});

अंतिम और सबसे चुनौतीपूर्ण हिस्सा गतिशील रूप से 'नमूनामिक्सिनप्लगिन' को प्रस्तुत करना है! अनुरोधित मॉड्यूल के विकल्प। ऐसा करने के लिए हम इंटरसेप्ट defineऔर requireइनवोकेशन को रोकते हैं और निर्भरता की सूची को संशोधित करते हैं इससे पहले कि वे मूल आवश्यकताएँ जेआरएस लोड विधि द्वारा संसाधित हो जाएंगे। यह थोड़ा मुश्किल है और lib/web/mage/requirejs/mixins.jsअगर आप इसे कैसे काम करना चाहते हैं, तो मैं इसे लागू करने की सलाह दूंगा।

डिबगिंग

मैं इस कदम की सिफारिश करेंगे:

  • सुनिश्चित करें कि 'मिश्रण' के लिए विन्यास! प्लगइन वास्तव में वहाँ है
  • जांचें कि एक मॉड्यूल के लिए पथ को संशोधित किया जा रहा है । यानी यह से बदल जाता path/to/moduleहै mixins!path/to/module

और अंतिम लेकिन कम से कम, requiresjs/mixins.jsइसका main.jsया script.jsमॉड्यूल से कोई लेना-देना नहीं है क्योंकि वे केवल data-mage-initविशेषता से पास किए जा रहे कॉन्फ़िगरेशन का विस्तार कर सकते हैं :

<div data-mage-init='{
    "path/to/module": {
        "foo": "bar",
        "mixins": ["path/to/configuration-modifier"]
    }
}'></div>

मेरा मतलब है कि पूर्व की दो फाइलें एक मॉड्यूल द्वारा लौटाए गए मूल्य के साथ गड़बड़ी नहीं करती हैं, इसके बजाय वे एक उदाहरण के कॉन्फ़िगरेशन को पूर्व-प्रक्रिया करते हैं।

उपयोग के उदाहरण

इसके साथ शुरू करने के लिए मैं रिकॉर्ड को सीधे सेट करना चाहूंगा जिसे तथाकथित "मिक्सिंस" (आप गलत तरीके से सही कह रहे हैं) वास्तव में किसी भी तरह से आप चाहते हैं कि किसी भी तरह से मॉड्यूल के निर्यात मूल्य को संशोधित करने की अनुमति दें। मैं कहूंगा कि यह एक अधिक सामान्य तंत्र है।

मॉड्यूल द्वारा निर्यात किए जा रहे फ़ंक्शन में अतिरिक्त कार्यक्षमता जोड़ने का एक त्वरित नमूना यहां दिया गया है:

// multiply.js
define(function () {
    'use strict';

    /**
     * Multiplies two numeric values.
     */
    function multiply(a, b) {
        return a * b;
    }

    return multiply;
});

// extension.js
define(function () {
    'use strict';

    return function (multiply) {
        // Function that allows to multiply an arbitrary number of values.
        return function () {
            var args = Array.from(arguments);

            return args.reduce(function (result, value) {
                return multiply(result, value);
            }, 1);
        };
    };
});

// dependant.js
define(['multiply'], function (multiply) {
    'use strict';

    console.log(multiply(2, 3, 4)); // 24
});

आप किसी मॉड्यूल द्वारा लौटाए गए किसी भी ऑब्जेक्ट / फ़ंक्शन के लिए एक वास्तविक मिक्सिन लागू कर सकते हैं और आपको extendविधि पर निर्भर होने की आवश्यकता नहीं है ।

एक निर्माण कार्य का विस्तार:

// construnctor.js
define(function () {
    'use strict';

    function ClassA() {
        this.property = 'foo';
    }

    ClassA.prototype.method = function () {
        return this.property + 'bar';
    }

    return ClassA;
});

// mixin.js
define(function () {
    'use strict';

    return function (ClassA) {
        var originalMethod = ClassA.prototype.method;

        ClassA.prototype.method = function () {
            return originalMethod.apply(this, arguments) + 'baz';
        };

        return ClassA;
    }
});

मुझे उम्मीद है कि यह आपके सवालों का जवाब देता है।

सादर।


धन्यवाद! बस क्या मैं खोज रहा था - केवल अन्य प्रश्न मैं होगा है - क्या करता है mixinsविन्यास में क्या x-magento-initऔर data-mage-initविन्यास? उदाहरण के लिए - आप ऊपर के उदाहरण में, path/to/configuration-modifierएक कॉलबैक भी लौटाएंगे जो कॉन्फ़िगरेशन डेटा को संशोधित कर सकता है? या कुछ और?
एलन स्टॉर्म

हाँ, ठीक है! यह एक कॉलबैक वापस करने वाला है जिसमें से आप कॉन्फ़िगरेशन डेटा को संशोधित कर सकते हैं।
डेनिस रुल

आपको लगता है कि इन दोनों सवालों पर किसी भी अंतर्दृष्टि - सामने अंत सामान के आसपास अपना रास्ता पता लगता है? magento.stackexchange.com/questions/147899/… magento.stackexchange.com/questions/147880/…
एलन स्टॉर्म

4

डेनिस रुल के जवाब को गोल करने के लिए ।

इसलिए, यदि आप एक Magento पृष्ठ को देखते हैं, तो यहां तीन <script/>टैग हैं जो Magento लोड करते हैं।

<script  type="text/javascript"  src="http://magento.example.com/pub/static/frontend/Magento/luma/en_US/requirejs/require.js"></script>
<script  type="text/javascript"  src="http://magento.example.com/pub/static/frontend/Magento/luma/en_US/mage/requirejs/mixins.js"></script>
<script  type="text/javascript"  src="http://magento.example.com/pub/static/_requirejs/frontend/Magento/luma/en_US/requirejs-config.js"></script>

यह खुद हीJJS ( require.js), mixins.jsप्लगइन और मर्ज किए गए आवश्यकताएँ JJS विन्यास ( requirejs-config.js) है।

mixins.jsफ़ाइल एक RequireJS प्लगइन परिभाषित करता है। यह प्लगइन्स, आवश्यकता के मॉड्यूल को लोड करने और कॉल करने के लिए ज़िम्मेदार है, जो अन्य आवश्यकताएँ मॉड्यूल के इंस्टेंटेशन को सुनता है।

मिक्सिन प्लगइन को परिभाषित करने के बाद इस प्लगइन में एक आवश्यकता कार्यक्रम भी शामिल है।

require([
    'mixins'
], function (mixins) {
    'use strict';
    //...

    /**
     * Overrides global 'require' method adding to it dependencies modfication.
     */
    window.require = function (deps, callback, errback, optional) {
        //...
    };

    //...

    window.define = function (name, deps, callback) {
        //...
    };

    window.requirejs = window.require;
});

यह दूसरा कार्यक्रम भार सिर्फ परिभाषित mixinsएक निर्भरता के रूप में प्लगइन, और फिर पुनर्परिभाषित वैश्विक require, defineऔर requirejsकार्य करता है। यह पुनर्वितरण वह है जो नियमित कार्यों के लिए चीजों को वापस करने से पहले रिक्जेस्ट मॉड्यूल की प्रारंभिक तात्कालिकता में हुक करने के लिए "वास्तव में एक मिश्रण नहीं" प्रणाली की अनुमति देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.