title: Using webpack with an existing requirejs application
body: <p>I am working with an existing application (<a href="https://github.com/instructure/canvas-lms" rel="noreferrer">canvas-lms</a>) that uses RequireJS in its build system. I'm working on a pseudo-standalone application that plugs into Canvas (a "client_app" in Canvas parlance). This is a fontend-only app that makes API calls back to the host Canvas app. The details aren't terribly important for my question - all a client_app needs to do is have a build script that spits out a JS file in a defined place within the Canvas app tree.</p>
  
  <p>I'm trying to use Webpack to build my app instead of RequireJS. Everything works great if I keep all my dependencies self-contained (e.g. npm-install everything I need); however, Canvas already provides many of these dependencies (e.g. React, jQuery), and in jQuery's case, it provides a patched version that I'd like to use instead. This is where I start to have problems.</p>
  
  <p>Getting React to work was easy; Canvas installs it with bower, so I was able to add an <code>alias</code> in my <a href="https://github.com/sfu/canvas_spaces_client_app/blob/a8c879646d81bf04951233781ef8ebcc1fbfa78b/webpack.production.js#L37" rel="noreferrer">webpack config to point at it</a>:</p>
  
  <pre><code>alias: {
    'react': __dirname + '/vendor/canvas/public/javascripts/bower/react/react-with-addons',
  }
  </code></pre>
  
  <p>(<code>__dirname + /vendor/canvas</code> is a symlink in my application tree to the host Canvas application's tree)</p>
  
  <p>Where I'm having trouble is trying to load the provided copy of jQuery.</p>
  
  <p>Canvas has the following jQuery structure:</p>
  
  <p><a href="https://github.com/instructure/canvas-lms/blob/d7581b8395fc8b372023b83ce6c3f4f98b5dac72/public/javascripts/jquery.js" rel="noreferrer">/public/javascripts/jquery.js</a>:</p>
  
  <pre><code>define(['jquery.instructure_jquery_patches'], function($) {
    return $;
  });
  </code></pre>
  
  <p><a href="https://github.com/instructure/canvas-lms/blob/d7581b8395fc8b372023b83ce6c3f4f98b5dac72/public/javascripts/jquery.instructure_jquery_patches.js" rel="noreferrer">/public/javascripts/jquery.instructure_jquery_patches.js</a>:</p>
  
  <pre><code>define(['vendor/jquery-1.7.2', 'vendor/jquery.cookie'], function($) {
    // does a few things to patch jquery ...
    // ...
    return $;
  });
  </code></pre>
  
  <p><a href="https://github.com/instructure/canvas-lms/blob/d7581b8395fc8b372023b83ce6c3f4f98b5dac72/public/javascripts/vendor/jquery.cookie.js" rel="noreferrer">/public/javascripts/vendor/jquery.cookie.js</a> -- looks like the standard jquery.cookie plugin, wrapped in an AMD define:</p>
  
  <pre><code>define(['vendor/jquery-1.7.2'], function(jQuery) {
  
  jQuery.cookie = function(name, value, options) {
      //......
  };
  
  });
  </code></pre>
  
  <p>and finally, <a href="https://github.com/instructure/canvas-lms/blob/d7581b8395fc8b372023b83ce6c3f4f98b5dac72/public/javascripts/vendor/jquery-1.7.2.js" rel="noreferrer">/public/javascripts/vendor/jquery-1.7.2.js</a>. Not going to paste it in, since it's bog-standard jQuery1.7.2, except that the <a href="https://github.com/instructure/canvas-lms/blob/d7581b8395fc8b372023b83ce6c3f4f98b5dac72/public/javascripts/vendor/jquery-1.7.2.js#L9399" rel="noreferrer">AMD define has been made anonymous</a> -- reverting it to the stock behaviour doesn't make a difference.</p>
  
  <p>I want to be able to do something like <code>var $ = require('jquery')</code> or <code>import $ from 'jquery'</code> and have webpack do whatever magic, poorly-documented voodoo it needs to do to use <code>jquery.instructure-jquery-patches</code>.</p>
  
  <p>I've tried adding the path to <code>resolve.root</code> in my <code>webpack.config.js</code> file:</p>
  
  <pre><code>resolve: {
    extensions: ['', '.js', '.jsx'],
    root: [
      __dirname + '/src/js',
      __dirname + '/vendor/canvas/public/javascripts'
    ],
    alias: {
      'react': 'react/addons',
      'react/addons/lib': 'react/../lib'
    }
  },
  </code></pre>
  
  <p>This should mean that when I do a <code>require('jquery')</code>, it first finds <code>/public/javascripts/jquery.js</code>, which defines a module with <code>instructure_jquery_patches</code> as a dependency. That falls into <code>instructure_jquery_patches</code>, which defines a module with two dependencies (<code>'vendor/jquery-1.7.2', 'vendor/jquery.cookie'</code>).</p>
  
  <p>In my main entry point (<a href="https://github.com/sfu/canvas_spaces_client_app/blob/a8c879646d81bf04951233781ef8ebcc1fbfa78b/src/js/index.js" rel="noreferrer">index.js</a>), I am importing jQuery (also tried a commonjs require, no difference), and trying to use it:</p>
  
  <pre><code>import React from 'react';    
  
  
  import $ from 'jquery';
  $('h1').addClass('foo');    
  
  if (__DEV__) {
    require('../scss/main.scss');
    window.React = window.React || React;
    console.log('React: ', React.version);
    console.log('jQuery:', $.fn.jquery);
  }
  </code></pre>
  
  <p>Building the bundle with webpack seems to work; there are no errors. When I try to load the page in the browser, though, I'm getting an error from within <code>jquery.instructure-jquery-patches.js</code>:</p>
  
  <p><img src="https://i.stack.imgur.com/chN8H.png" alt="enter image description here"></p>
  
  <p>It would seem that jQuery is not availble within <code>jquery.instructure-jquery-patches.</code></p>
  
  <p>It <strong>is</strong>, however, available in the global scope after the page loads, so jQuery is being evaluated and executed.</p>
  
  <p><img src="https://i.stack.imgur.com/VFfI2.png" alt="enter image description here"></p>
  
  <p>My guess is that I'm running into some sort of requirejs/amd asynchronicity problem, but that's a shot in the dark. I don't know enough about requirejs or amd to know for sure.</p>