Recognizing Legacy JavaScript
How to spot outdated form code in practice. A search list of the patterns that keep showing up in old Dynamics scripts.
Before you can talk about the risks of old form code, there is a craft question. How do you recognize legacy code at all when a folder full of web resources lies in front of you? The good thing about legacy patterns is that you can search for them literally. Here is an annotated search list.
The clear hits
These strings are a finding by themselves. You do not need to understand the surrounding code.
- "Xrm.Page": the old form access, replaced since version 9 by the formContext from the execution context. By far the most common find.
- "/XRMServices/2011/": the old SOAP or OData v2 endpoint. Data access belongs on the Web API today.
- "Xrm.Page.context", "Xrm.Utility.openEntityForm" and "Xrm.Utility.openQuickCreate": deprecated predecessors of "Xrm.Utility.getGlobalContext()" and of today's navigation API "Xrm.Navigation" (list of deprecated client APIs at Microsoft).
- "window.parent.Xrm": reaching from an HTML web resource into the parent window. Depending on the embedding, it works sometimes and sometimes not. It was never the intended way.
- "crmForm": if you find this, you are looking at code from the 4.0 era. It is rare, but it happens.
The behavior patterns
Other traits are not recognized by a keyword but by how the code is built.
You recognize synchronous server calls by the third parameter "false" in "xhr.open(...)". They freeze the form during the call and are deprecated in the browser. Some scripts keep hand-built field name lists in the code instead of fetching them from the form. Such lists break at the next rename. And embedded third-party libraries with a version number in the file name (a jQuery 1.x, for example) date a script more reliably than any comment.
One more word on HTML web resources: they are a gold mine of their own. They hold complete pages from earlier project phases, with embedded script and the oldest access patterns in the whole inventory. Anyone who only searches the js files misses them.
Another hint of age: references to "ClientGlobalContext.js.aspx" in HTML resources. That route still works, but it dates from the time before "Xrm.Utility.getGlobalContext()". Usually it sits deep in old helper pages that like to survive modernization rounds unnoticed. It is not a finding by itself, but a good reason to look at the page more closely.
From finding to assessment
Not every hit is equally urgent. A simple split has proven useful for prioritizing. Anything based on deprecated endpoints or synchronous calls can actually stop working with a platform update. That belongs on the active list. The plain "Xrm.Page" inventory works for now and can be migrated on a schedule, ideally when the form in question is being touched anyway.
The opposite direction matters too. A script can be free of all these patterns and still be dead, because no form and no button calls it anymore. The modernity of the code and its usage are two separate questions, and both belong in the inventory.
The whole search list runs in a few minutes with any editor over the unzipped WebResources folder. Few checks offer a better ratio of effort to insight.
For context, since I build an audit tool with D365 Audit myself: it detects "Xrm.Page", embedded jQuery versions, "eval" and synchronous calls from this list automatically. "/XRMServices/2011/", "crmForm", "openEntityForm" and "window.parent.Xrm" are not part of it. For those, text search remains the right way.
Upload your solution export and get an assessment within minutes: security risks, technical debt, documentation coverage, and migration risk. No access to your environment required, first metrics free of charge.
Analyze your solution View sample report