title: DataTables API undefined with Symfony Webpack Encore
body: <p>I'm using Webpack Encore with Symfony 3.4 <em>(part of migration to Symfony 4)</em>.</p>
  
  <p>I have Datatables (installed via NPM to node_modules) working with jQuery but the <code>api</code> functions such as <code>.columns</code> are returning: <code>.column is not a function at</code></p>
  
  <p><strong><em>Package Versions</em></strong>:</p>
  
  <ul>
  <li>jQuery <code>2.14.4</code></li>
  <li>Datatables <code>1.10.19</code></li>
  <li>Webpack Encore <code>0.27.0</code></li>
  </ul>
  
  <p><strong><em>Webpack app.js</em></strong>:</p>
  
  <pre><code>global.$ = global.jQuery = require('jquery');
  require('bootstrap');
  global.moment = require('moment');
  require('datatables.net-dt');
  $.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables.net');
  </code></pre>
  
  <p><strong><em>webpack.config.js</em></strong>:</p>
  
  <pre><code>var Encore = require('@symfony/webpack-encore');
  
  Encore
  // directory where compiled assets will be stored
      .setOutputPath('code/web/build/')
      // public path used by the web server to access the output path
      .setPublicPath('/build')
      // only needed for CDN's or sub-directory deploy
      //.setManifestKeyPrefix('build/')
  
      .addEntry('site', './assets/js/site/app.js')
  
      // will require an extra script tag for runtime.js
      // but, you probably want this, unless you're building a single-page app
      .enableSingleRuntimeChunk()
  
      .cleanupOutputBeforeBuild()
      .enableSourceMaps(!Encore.isProduction())
      // enables hashed filenames (e.g. app.abc123.css)
      .enableVersioning(Encore.isProduction())
  
  // uncomment if you use TypeScript
  //.enableTypeScriptLoader()
  
  // uncomment if you use Sass/SCSS files
  //.enableSassLoader()
  
  // uncomment if you're having problems with a jQuery plugin
  //.autoProvidejQuery()
  ;
  
  module.exports = Encore.getWebpackConfig();
  </code></pre>
  
  <p>Javascript example in <strong><em>template.html.twig</em></strong> <em>(extends base html file)</em>:</p>
  
  <pre><code>{{ encore_entry_script_tags('site') }}
  
  &lt;script type="text/javascript"&gt;
  $(document).ready(function() {
      var $dtable;
  
      $dtable = $('#simpleTable')
                          .DataTable({
                              data: data,
                              deferRender: true,
                              scrollX: false,
                              searching: true,
                              paging: true,
                              pageLength: 25});
  
      console.log($dtable);
  
      // Error occurs here
      var column = $dtable.column(index);
  });
  &lt;/script&gt;
  </code></pre>
  
  <p>A console log of <code>$dtable</code> immediately after instantiation outputs the following which seems to confirm an Api instance isn't created?</p>
  
  <p><a href="https://i.stack.imgur.com/4VAmY.png" rel="noreferrer"><img src="https://i.stack.imgur.com/4VAmY.png" alt="dtable instance"></a></p>
  
  <p>Is it possible this is related to the DataTable loader that uses the <code>AMD</code> method due to Webpack?</p>
  
  <p><strong><em>jquery.dataTables.js</em></strong>:</p>
  
  <pre><code>(function( factory ) {
      "use strict";
      if ( typeof define === 'function' &amp;&amp; define.amd ) {
          define( ['jquery'], function ( $ ) {
              return factory( $, window, document );
          } );
      }
      else if ( typeof exports === 'object' ) {
          module.exports = function (root, $) {
              if ( ! root ) {
                  // CommonJS environments without a window global must pass a
                  // root. This will give an error otherwise
                  root = window;
              }
              if ( ! $ ) {
                  $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
                      require('jquery') :
                      require('jquery')( root );
              }
              return factory( $, root, root.document );
          };
      }
      else {
          factory( jQuery, window, document );
      }
  }
  </code></pre>