require.js to load javascript

whilst wp_enqueue_script seems to work it’s not really elegant. I’m currently making a WP front end which uses MVC (backbone.js) and has literally 30+ seperate Model/View/Collection/Controller scripts and I keep adding to the number. I’ve used require.js a lot before and really like it, however it seems to completely break wordpresses logic.

Can anyone point me to a clean method of using a js scriptloader with wordpress? or is this a hopeless task?

Read More

Thanks

Related posts

Leave a Reply

2 comments

  1. Though WordPress already has a basic .js API (with register and enqueue script), I don’t see why you cannot use it in conjunction with require.js, at least at the modular level.

    From what I can tell (never used it) it only needs to be loaded, so you can,

    wp_enqueue_script( 
         $handle, 
         '...folder../require.js',
          $deps,
          $ver,
          $in_footer 
    );
    

    Then use the recommended require folder structure and js code to take advantage of it. I believe that require.js is framework agnostic, even so it has it’s own namespace function to avoid conflicts.

    With that being said your still going to be limited to using it for your own code as opposed to plugins and themes you might be using.

    Meaning, if a plugin or theme author does it the right way you can wp_dequeue_script the script and manage it with require.js, but what if they don’t? There is not much you can do outside writing some sort of hacky plugin or manually changing the code.

    For this reason using a js framework with wordpress is probably not worth the effect, unless your doing it from scratch and have control over the plugins and themes.

  2. For using require JS you need add in head

    <!-- Delayed execution of inline jQuery scripts with ready waiting event -->
    <script type="text/javascript">(function(w, d, u){w.readyQ = []; w.bindReadyQ = []; function p(x, y){if (x == "ready"){w.bindReadyQ.push(y); } else{w.readyQ.push(x); }}; var a = {ready:p, bind:p}; w.$ = w.jQuery = function(f){if (f === d || f === u){return a} else{p(f)}}})(window, document)</script>
    
    <!-- Loading require.js -->
    <script async data-main="/wp-content/theme/default/js/requirejs.config" src="/wp-content/theme/default/js/requirejs.min.js"></script>
    

    Next, create Require.JS config file and update functions.php

    /* Delayed loading of all JS files */
    add_filter('script_loader_tag', function($tag, $handle, $src) {
        if (isAdmin()) return $tag;
    
        if (stripos($src, 'jquery.min') !== FALSE) return '';
    
        global $wp_scripts;
        $dependencies = $wp_scripts->query($handle, 'registered')->deps;
        $dependenciesList = empty($dependencies) ? "'jquery'" : "'" . implode("','", $wp_scripts->query($handle, 'registered')->deps) . "'";
    
        return "<script>$(document).ready(function(){ define('{$handle}', [{$dependenciesList}], function(){require(['{$src}']);}); require(['{$handle}']); });</script>n";
    }, 10, 3);
    

    And in finish, you need in your config file, add initialization of delayed jquery events, like this:

    requirejs.config({
        paths: {
            jquery: 'jquery.min'
        }
    });
    
    //loading jquery as dependency
    require(["jquery"], function ($) {
        (function($,d){$.each(readyQ,function(i,f){$(f)});$.each(bindReadyQ,function(i,f){$(d).bind("ready",f)})})(jQuery,document);
    });