A JS Foundation Project



sonarwhal was designed with extensibility in mind. At a high level, this is the project’s architecture:

sonarwhal's architecture

The main piece is sonarwhal. It’s an object that extends from EventEmitter. This means that the communication between all the different parts is going to be done mostly via events. The other pieces are:

  • rule: Is a group of related tests that are run on a resource (HTML, document, image, request, etc.). E.g.: Verify that the HTML document has a valid language declared. Learn how to develop a rule.
  • connector: Is the way in which sonarwhal obtains information about the DOM, network information, resources, etc. The underlying technique (debugging protocol, web driver, etc.) to access this data does not matter to the rest of the system. Learn how to develop a connector.
  • formatter: Transforms the results into something useful to the user. It could be as simple as printing out the results to the command line, or something more complex like creating an HTML report. Learn how to developer a formatter.
  • parser: Understands a particular resource type (e.g.: JavaScript, stylesheet, webmanifest, etc.), parses it, and emits related event(s) so rules can take action on them. Learn how to develop a parser.

When a user invokes sonarwhal https://example.com basically what happens is this:

  1. The CLI creates a new SonarwhalConfig object based on the user’s .sonarwharc file. This process validates that the rules are configured correctly, etc.
  2. The CLI then passes this SonarwhalConfig to the resource-loader that will return a SonarwhalResources object that contains the Constructors of the configured resources. resource-loader checks at the same time if the resources actually exist, are compatible with the current sonarwhal version, etc. If there are missing dependencies, the names will be in the missing property of the result. For incompatibilities, it will be the incompatible.
  3. If everything goes well, a new Sonarwhal object is created using the previous SonarwhalConfig and SonarwhalResources, then CLI calls its analyze method.
  4. sonarwhal then calls the collect method of the configured connector.
  5. The connector will navigate to the URL traverse the HTML, and send events related to this and the resource loading process.
  6. If a parser has subscribed to one of the emitted events, it will parse that resource and emit new events.
  7. rules can subscribe to any event no matter where it’s comming from (connector or parser). If they find an issue, it will be reported via the report method.
  8. Once sonarwhal has finished analyzing the website, the results are returned to CLI that will print them using the configured formatter(s).

Any developer can create their own rules, connectors, parsers and/or formatters, and use them without having to do a pull request to the main project and distribute them as npm packages.