Rails 6 + webpacker + jquery + sprockets + jquery plugin (fancetree)

So you might be in the process of migrating to webpacker. This means your sprockets should continue working. This is difficult. Sprockets wants jquery available in the view and you don’t have jquery available in the views. You have it in the webpacker packs.

These things won’t work

  <script> 
    $("element_id")
  </script>

jQuery is only available to the PACKS it is not available to the VIEWS.

But there is a solution – expose-loader

Here is how to setup jquery to be available to the views in sprockets app that you are migrating to rails 6. I am starting from the previous article were we set up the project from 0. – https://kmitov.com/posts/rails-6-webpacker-yarn-fancytree-less/

$ yarn add expose-loader

Add configuration for exposing of jquery

// config/webpack/environments.js
const { environment } = require('@rails/webpacker')
 
const less_loader= {
 test: /\.less$/,
 use: ['css-loader', 'less-loader']
};
environment.loaders.append('less', less_loader)

+
+const webpack = require('webpack')
+// this makes jquery available in all pack and you don't
+// have to import or require it each time 
+environment.plugins.prepend(
+  'Provide',
+  new webpack.ProvidePlugin({
+    $: 'jquery',
+    jQuery: 'jquery'
+  })
+)
+
+// this exposes jquery to be available in the views
+// <script>
+//   console.log($('#tree'))
+// </script>
+environment.loaders.append('expose', {
+  test: require.resolve('jquery'),
+  use: [{
+    loader: 'expose-loader',
+    options: '$'
+  }, {
+    loader: 'expose-loader',
+    options: 'jQuery',
+  }]
+})

Also expose fancytree

// config/webpack/environments.js
...
+// this exposes fancytree to be available in the views
+// <script>
+//   console.log($('#tree').fancytree())
+// </script>
+environment.loaders.append('fancytree', {
+  test: require.resolve('jquery.fancytree'),
+  use: [{
+    loader: 'expose-loader',
+    options: 'fancytree'
+  }]
+})

And you are done.

How in your views you could do:

<script>
  console.log($('#tree'))
  $(function(){
    $('#tree').fancytree({
      extensions: ['edit', 'filter'],
      source: [
        {title: "Node 1", key: "1"},
        {title: "Folder 2", key: "2", folder: true, children: [
          {title: "Node 2.1", key: "3"},
          {title: "Node 2.2", key: "4"}
        ]}
      ],
    });
    const tree = fancytree.getTree('#tree');
    // Note: Loading and initialization may be asynchronous, so the nodes may not be accessible yet.
  })
</script>

Fancytree as a jquery plugin is working in rails 6 views and is available also to sprockets compiled files.