Roots Discourse

Sage 9 + Vue.JS (no jQuery)

sage9

#1

Hello!

I was wondering: is there any specific up-to-date tutorial on how to properly set-up Vue.JS + Sage 9 (either on install or on existing project). I’m thinking that I should probably dispose of jQuery and learn something new with this new upcoming project.
I found Adding Vue.js to Sage 9: Dependencies and Approach but it’s a little outdated and people had some issues as well.

Also, is it viable to use it at all since Blade template managing is quite good, and would it be a problem using both simultaneously?

Anyone uses Vue.js regularly with Sage? If so, how?

Thanks and best regards,
j


#2

https://github.com/pixelcollective/SageJS from @kellymears might be a good starting point although it still includes jQuery.

You will be somewhat hardpressed ridding yourself of jQuery in entirety on the frontend unless you plan on not using any plugins that handle anything on the frontend (e.g. contact forms, etc.)

But if you insist, it will come down to dequeueing jQuery and jQuery Migrate as well as cleaning out the existing JS boilerplate that ships with Sage.

If you handle jQuery with a CDN such as Soil’s jQuery CDN module does, it shouldn’t be too big of a deal to just use both instead going through the headache of trying to dodge it at every corner within the WordPress ecosystem.


#3

I’m using this as a base for a production site right now and it’s working out well. I made zero attempt to patch out jQuery.

One issue people will likely run into is that Sage’s live reload dev feature relies on a node_module called dom-compare-temp which doesn’t play nicely with Vue templating.

In my experience Browsersync worked for a while but eventually things fell apart. In order to fix it I needed to modify dom-compare-temp/lib/compare.js. Around line 100 you’ll find this switch statement:

        switch (left.nodeType) {
            case type.DOCUMENT_NODE:
               return this.compareNode(left.documentElement, right.documentElement);
            case type.ELEMENT_NODE:
               return this._compareAttributes(left.attributes, right.attributes) &&
                     this._compareNodeList(left.childNodes, right.childNodes);
            case type.TEXT_NODE:
               // fallthrough
            case type.CDATA_SECTION_NODE:
               // fallthrough
            case type.COMMENT_NODE:
               if (left.nodeType == type.COMMENT_NODE && !this._options.compareComments)
                  return true;
               vLeft = "" + left.nodeValue;
               vRight = "" + right.nodeValue;
               if (this._options.stripSpaces && left.nodeType !== type.CDATA_SECTION_NODE) {
                  vLeft = vLeft.trim();
                  vRight = vRight.trim();
               }
               r = vLeft === vRight;
               return !r ? this._collector.collectFailure(left, right) : r;
            default:
               throw Error("Node type " + left.nodeType + " comparison is not implemented");
         }

You want to make a new case for type.DOCUMENT_FRAGMENT_NODE to give a little leniency to the Vue templates:

case type.DOCUMENT_FRAGMENT_NODE:
  // fallthrough

I inserted it below the type.CDATA_SECTION_NODE case. The resulting switch in full:

         switch (left.nodeType) {
            case type.DOCUMENT_NODE:
               return this.compareNode(left.documentElement, right.documentElement);
            case type.ELEMENT_NODE:
               return this._compareAttributes(left.attributes, right.attributes) &&
                     this._compareNodeList(left.childNodes, right.childNodes);
            case type.TEXT_NODE:
               // fallthrough
            case type.CDATA_SECTION_NODE:
               // fallthrough
            case type.DOCUMENT_FRAGMENT_NODE:
                // fallthrough
            case type.COMMENT_NODE:
               if (left.nodeType == type.COMMENT_NODE && !this._options.compareComments)
                  return true;
               vLeft = "" + left.nodeValue;
               vRight = "" + right.nodeValue;
               if (this._options.stripSpaces && left.nodeType !== type.CDATA_SECTION_NODE) {
                  vLeft = vLeft.trim();
                  vRight = vRight.trim();
               }
               r = vLeft === vRight;
               return !r ? this._collector.collectFailure(left, right) : r;
            default:
               throw Error("Node type " + left.nodeType + " comparison is not implemented");

I implemented this workaround by cloning the module and linking it with yarn link. The dom-compare-temp package hasn’t been updated in years, so this might be the only option until the dependency is revisited by the fine folks on the Sage team.

Everything has been pretty smooth sailing since then. Godspeed!


#4

I’ve updated the instructions from Adding Vue.js to Sage 9: Dependencies and Approach with the fix for vue-style-loader not working, which https://github.com/pixelcollective/SageJS from @kellymears had working.

Hope that helps.


#5

Thanks mate, that’s great yeah.