Magento 2: requirejs-config.js in themes?

OK, I think I may have solved it and I believe that the documentation is ambiguous and needs updating to clarify the process.

I moved my requirejs-config.jsfrom within the web/js and web directories respectively for both Magento_Theme and the root of my theme at <Vendor>/<theme> and now my RequireJS config is merged into the main requirejs-config.js with all other includes.

So, it appears that you have to include the requirejs-config.js file in the following locations based on the theme/module requirements.

Theme Level

app/design/frontend/<Vendor>/<theme>/requirejs-config.js

Module Level

app/design/frontend/<Vendor>/<theme>/<Module_Name>/requirejs-config.js

So, in your requirejs-config.js for your theme you should map your component to a path and then use shim to declare any dependencies:

var config = {
    map: {
        'component': 'js/component'
    },
    shim: {
        'component': {
            deps: ['jquery']
        }
    }
};

Then you'll need to create a template to hold the initialisation of the components via a <script> tag (unless you attach it directly to an element within a .phtml file) if this is the route you want to go down, include the following content:

<script type="text/x-magento-init">
    {
        "*": {
            "js/component": {} // Not entirely sure what {} is and what I'm passing here
        }
    }
</script>

Alternatively, bind it to an element:

<script type="text/x-magento-init">
    {
        "#element": {
            "js/component": {} // Not entirely sure what {} is and what I'm passing here
        }
    }
</script>

Then simply include the .phtml template in your layout instructions, for example, I placed mine within the default.xml located at app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout under the body node and referenced:

<block class="Magento\Framework\View\Element\Template" name="theme.js" template="Magento_Theme::html/js.phtml" />


you can actually include a require-config.js in your themes Module dirs.

The problem is (actually for our frontend team) that there seems to be no possibility, to override the config, but to extend the config.

So, to take the Magento_Theme module for an example here, if you add a require-config.js under <theme_base_dir>/Magento_Theme dir, the config will be added to the generated require-config.js file and also the config from the Magento_Theme module will be added.

To answer your question I also tried to add a require-config.js under the themes <theme_base_dir>/web dir and also under the themes root dir. Both did not work. update: actually according to the answer below, it is possible by placing it into the theme base dir

So the answer would be basically yes, since you could add any js requirement under any module (theme related js files may be best placed under the <theme_base_dir>/Magento_Theme dir)

Although I would say, there should be the possibility to add a theme related require-config.js outside of any Module (maybe you deactivate the given module) and also it should be possible to override a modules require-config.js.

Both seem not possible atm.

===UPDATE===

actually it seems possible to have a theme specific require-config.js. See @Gareth Daine's Answer below


Didn't have sufficient rep to make this a comment, but just to note that Gareth's answer didn't quite work for me.

var config = {
    map: {
        '*': {
            'component': 'js/component'
        }
    },
    shim: {
        'component': {
            deps: ['jquery']
        }
    }
};

Wrapping the 'component': 'js/component' with '*':{} did the trick.

Also rather than create a template file I added the code below at the top of app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout/default.xml

    <referenceContainer name="after.body.start">
        <block class="Magento\Framework\View\Element\Text" name="jquery.bootstrap">
            <arguments>
                <argument translate="true" name="text" xsi:type="string"><![CDATA[<script type="text/x-magento-init">{"*":{"jquery.bootstrap":{}}}</script>]]></argument>
            </arguments>
        </block>
    </referenceContainer>