Npm webpack ss-utils, accessing from $.ss on razor page

Moving over to npm and webpack…

Probably an issue with npm, jQuery modules like ss-utils, but how do we access $.ss from a razor .cshtml page or external .js not in the webpack build? From within the webpack build we can access $.ss, but not outside of webpack.

  1. We can access jQuery from either $ or jQuery from any .js file in the webpack build.
  2. We can access $ and jQuery from a razor .cshtml page.
  3. We can also access jQuery.ss from razor .cshtml page, e.g. jQuery.ss.humanize('EmailAlreadyExists').

But we cannot access $.ss from razor .cshtml file or external .js file.
Example: $.ss.humanize('EmailAlreadyExists');

Already have code that utilizes the $.ss syntax and rather not add extra characters for every $ usage.

ss-utils.js is a jquery plugin that can be included with a script include:

<script type="text/javascript" src="/js/ss-utils.js"></script>

For webpack modules it’s preferred to use the newer jquery-free @servicestack/client library which is included in all .NET Core Single Page App templates.

Hmmm… Don’t think that would work b/c we have code in the webpack modules that access $.ss and also in the razor .cshtml files. If it worked it would be duplicated b/c webpack would include it and it would also be included in the <script .../>

We already have lots of code that is based on Bootstrap 3 and jQuery… a migration to @servicestack/client looks like it may be more work than is available.

Also, we’re needing to access ss-utils from the razor .cshtml files. Not sure if we’d run into the same problems.

You need to include jQuery as well, they’re simple script includes which is how they everyone referenced jQuery + plugins long before webpack existed.

Yeah that is what we had before. We have some external npm webpack projects that we now need to include, so we’re fighting with two ecosystems (before and after webpack) and can’t go back to <script ../> includes without a lot more work and those require jQuery as well. Everything works except for $.ss and thought it would be something simple to fix. Might have to change the razor .cshtml pages to use jQuery.ss instead then.

Here is what we found to work as a work around. Not tested at all, so use at your own risk.

It should be noted that if your project lets you use plain old jQuery and ss-utils in <head><script> like @mythz said then do that. If for whatever reason you need to webpack in jQuery you can try the following if $ or $.ss isn’t working when accessing from .cshtml files.

Note: Not sure if webpack still needs to use expose-loader, but it is set in ours for other reasons. e.g.

// in webpack.common.js or whatever you've named it
use: [
      {
        loader: "expose-loader",
        options: "jQuery"
      },
      {
        loader: "expose-loader",
        options: "$"
      }]

It seems webpack causes jQuery to not be available right away even tho it’s in the <head> tag. To get around this we:

  1. In _Layout.cshtml add to the window.onload event using old code from Simon Willison
  2. call into the old code function addLoadEvent(func) and set $ to jQuery.
  3. In any View Page that uses the layout you can call into that same addLoadEvent(func) with your jQuery $ code.
  4. Note: now ss-utils is available in the .cshtml view pages via the $.ss syntax

Example:

// _Layout.cshtml
// Source: https://simonwillison.net/2004/May/26/addLoadEvent/
function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
        }
    }
}

// set jQuery to window.$
addLoadEvent(function () {
    if (typeof window.$ === "undefined") {
        // note: probably should check that jQuery is defined, tho we aren't here
        window.$ = jQuery;
    }
});

Now in any View Page that uses the _Layout.cshtml can use $ and $.ss so long as it’s called via the addLoadEvent(func).

Example:

// any View Page .cshtml that inherits from _Layout.cshtml
addLoadEvent(function () {
   // below from https://github.com/NetCoreApps/SimpleAuth.Mvc/blob/1809333c068ecce64e917fb6606a40bfa3d25910/src/Mvc/Views/Home/Index.cshtml#L13
    var hashVars = $.ss.queryString(location.hash.replace('#','?'));
    if (hashVars['f']) {
        $("#autherror").html($.ss.humanize(hashVars['f']));
    }
});
1 Like