ESLintNow is an unofficial ES5 port and distribution of ESLint, suitable for prehistoric and quirky JavaScript engines (like the one that the ServiceNow platform uses for its ES5 Standards Mode).
- Build dependencies
- Build
- Usage
- Installation to ServiceNow
- Usage example in ServiceNow
- Custom rules
- Test coverage
- License
To be able to build the distribution, you should only need git, Node.js and npm preinstalled.
-
Download the latest version of this distribution:
git clone https://github.com/trosos/eslintnow.git
-
Set the working directory:
cd eslintnow
-
Figure out the dependencies as they were at the time of timestamp.txt:
npm run wrap
-
Download the dependencies:
npm ci
-
Build the bundle, extract the automatic tests and pack everything into an Update Set:
npm run build
The bundle exposes only a subset of classes exported by the eslint
npm package, namely Linter
and SourceCode
, plus some helpers.
They are accessible as properties of the bundle
variable,
declared in the namespace in which the bundle was included
(this will typically be x_eslintnow
).
If you choose to install ESLintNow
via the Update Set,
then you can also enjoy the convenience shortcuts x_eslint.Linter
,
x_eslint.SourceCode
, and so on.
You can use these classes in accordance with the official ESLint documentation.
For a complete list of exported classes in the bundle, look into src/bundle.js. Alternatively, you can explore the proxy Script Includes in the generated Update Set.
This is the recommended way to use ESLintNow with ServiceNow.
TL;DR:
Commit the Update Set in dist/eslintnow.xml
and you are good to go.
-
In ServiceNow, navigate to System Update Sets > Retrieved Update Sets.
-
Follow the Related link Import Update Set from XML.
-
Select the file
dist/eslintnow.xml
generated in the Build step above, and press the Upload button. -
Locate the imported Update Set (its name starts with ESLintNow) and open it by clicking the corresponding Preview icon in the left column, and pressing Open Record afterwards.
-
On the form of the ESLintNow Retrieved Update Set, press the Preview Update Set button.
-
After the preview completes, close the dialog.
-
If the preview failed, resolve all preview problems.
-
Press the Commit Update Set button.
-
After the commit completes, close the dialog.
Alternatively, you can install the ESLintNow core manually.
Using this method is discouraged and there is no point in doing so, other than trying to understand how things work. This info is provided mainly for users of other JavaScript engines, to help them understand how to use ESLintNow outside of the ServiceNow environment.
-
In ServiceNow, create a new application with JavaScript Mode set to ES5 Standards Mode.
Example application name:x_eslintnow
. -
Inside your new application, create a new Script Include, named
bundle
. -
Configure your Script Include to be accessible from all application scopes.
-
Copy-paste the content of the generated
dist/bundle.js
into theScript
field of your Script Include.
To quickly test your installation, use the ServiceNow module
Scripts - Background
. Select global scope
and run:
var linter = new x_eslintnow.bundle.Linter();
var result = linter.verify("var foo", {
rules: {
semi: 2
}
});
gs.print(JSON.stringify(result, null, 2));
You should see something along the following lines:
*** Script: [
{
"ruleId": "semi",
"severity": 2,
"message": "Missing semicolon.",
"line": 1,
"column": 8,
"nodeType": "VariableDeclaration",
"messageId": "missingSemi",
"fix": {
"range": [
7,
7
],
"text": ";"
}
}
]
In addition to the ESLint core rules, you can define custom rules
using the Linter#defineRule
API, as defined in the ESLint
documentation.
For example, in ServiceNow, you can do the following:
var linter = new x_eslintnow.bundle.Linter();
linter.defineRule("my-rule", {
meta: {
messages: {
call_prohibited: "You call {{fun_name}} in your code, but you should only call be_nice."
}
},
create: function (context) {
return {
CallExpression: function (node) {
if (node.callee.type === "Identifier") {
context.report({
node: node,
messageId: "call_prohibited",
data: {
fun_name: JSON.stringify(node.callee.name)
}
});
}
}
};
}
});
var result = linter.verify("({ something: be_bad(naughty) });", {
rules: {"my-rule": [1]}
});
gs.print(JSON.stringify(result, null, 2));
When run as a ServiceNow Background Script, the above code should print something like this:
*** Script: [
{
"ruleId": "my-rule",
"severity": 1,
"message": "You call \"be_bad\" in your code, but you should only call be_nice.",
"line": 1,
"column": 15,
"nodeType": "CallExpression",
"messageId": "call_prohibited",
"endLine": 1,
"endColumn": 30
}
]
ESLint provides an exhausting set of automated tests for each of the core rules. Most of these tests are extracted as part of the build process of ESLintNow; the tests that ESLintNow fails to provide pertain to the following core ESLint rules:
- comma-dangle
- func-name-matching
- no-misleading-character-class
- no-unused-vars
- prefer-const
- prefer-regex-literals
- strict
While it would be theoretically possible to extract these tests as well, it would require more work on the extraction engine and/or on the ESLintNow's custom rule tester.
On ServiceNow, all of the remaining ESLint core rules should pass every of their automatic tests. You can execute the tests by running the following as a ServiceNow Background Script:
var outcomes = [];
gs.print(JSON.stringify(x_eslintnow.ruleTester.runAllTests(outcomes), null, 2));
gs.print("----------");
gs.print(JSON.stringify(outcomes, null, 2));
Be patient and give the process some time: the custom tester is not heavily optimized and the package contains plenty of tests. It can easily happen that they will take around 30 minutes to complete.
This software is distributed under the BSD Zero Clause License.