npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dojo-has

v2.0.0-alpha.6

Published

A feature detection library

Downloads

25

Readme

dojo-has

Build Status codecov npm version

A feature detection library.

This package provides an API for expressing feature detection to allow developers to branch code based upon the detected features. The features can also be asserted statically, thereby allowing integration into a build optimization tool that can be used to make certain branches of code "dead" which can be elided during a build step. The has module is also capable of allowing conditional loading of modules with certain loaders.

WARNING This is beta software. While we do not anticipate significant changes to the API at this stage, we may feel the need to do so. This is not yet production ready, so you should use at your own risk.

Features

Feature Branching

The most common feature is branching in code based upon a feature flag. has() essentially manages feature flags, returning either a truthy value if the feature is present or a falsey value if the feature isn't present. The has() module is the default export of the main module of the package:

For example:

import has from 'dojo-has';

if (has('host-browser')) {
	/* Browser Related Code */
}
else {
	/* Non-Browser Related Code */
}

has() can be used in any conditional expression, like a ternary operator:

function getArrayOrString(): number[] | string {
	return has('some-feature') ? [ 1, 2, 3 ] : '[ 1, 2, 3 ]';
}

Included Features

Other Dojo 2 packages leverage the has() package to express features that are then used within the package. Because of this, there are very few features expressed in this foundational package. The intention is that this package is used to enable a developer to express other features. The flags though that are included in this package are:

|Feature Flag|Description| |------------|-----------| |debug|Provides a way to code path for code that is only usable when debugging or providing enhanced diagnostics that are not desired in a production build. Defaults to true but should be configured statically as false in production builds.| |host-browser|Determines if the current environment contains a window and document object in the global context, therefore it being generally safe to assume the code is running in a browser environment.| |host-node|Attempts to detect if the environment appears to be a node environment.|

Adding a Feature Test/Feature Detection

The main module of the package exports a function named add() which allows the addition of features flags. The feature tests can be expressed as a static value, or as a function which will be lazily evaluated when the feature flag is first requested from has(). Once evaluated, the value is cached.

An example of adding a feature:

import { add } from 'dojo-has';

add('my-feature', true);
add('my-lazy-feature', () => {
	/* will not be called yet */
	return true;
});

if (has('my-lazy-feature')) { /* feature function called here */
	/* do something */
}

If a feature flag is already added, the value can be overridden by supplying true as the 3rd argument of the add() function:

add('my-feature', false, true);

The module also has an exits() function which returns true if the feature flag has been added to has():

import { exists, add } from 'dojo-has';

if (!exists('my-feature')) {
	add('my-feature', false);
}

Conditional Module Loading

When using an AMD loader that supports loader plugins (such as dojo-loader) then dojo-has can be used to conditionally load modules or substitute one module for another. The module ID is specified using the plugin syntax followed by the feature flag and a ternary operator of what to do if the feature is truthy or falsey:

import foo from 'dojo-has!host-browser?foo/browser:foo/node';

/* foo is now the default export from either `foo/browser` or `foo/node` */

The module IDs supplied in the ternary operator can be specified as absolute MIDs or relative MIDs based on the loading module, just as if you were just directly importing the module.

When using TypeScript, TypeScript will not be able to automatically resolve the module shape, therefore you will often have to make a global declaration of the module that is in the scope of the project where the module name matches the full MID you will be importing:

declare module 'dojo-has!host-browser?foo/browser:foo/node' {
	export * from 'foo/browser'; /* Assumes that foo/browser and foo/node have the same shape */
}

Static Features

Features can also be defined statically, before the module is loaded, in the global scope. The main use case is when it is not desirable to detect these features from the environment (because they may not be accurate, like when using a build tool). The features can only be specified before the module is loaded for the first time and cannot be changed once the module is loaded. The values specified in the static features will always be returned from has() irrespective of how those features a subsequently defined using add(), even if override is specified. In addition, if a value is being added via add() that is already defined as a static feature, it will still complete and not throw although if specified as function, the function will never be invoked.

To specify the features, the global variable DojoHasEnvironment needs to be specified with a property of staticFeatures which is a simple map of the features:

window.DojoHasEnvironment = {
	staticFeatures: {
		'host-node': true,
		'host-browser': false,
		'my-feature': 2
	}
};

staticFeatures can also be specified as a function, which returns an map of the features:

window.DojoHasEnvironment = {
	staticFeatures: function () {
		return { 'host-node': true, 'host-browser': false, 'my-feature': 2 };
	}
};

This function will be run once when the module is loaded and the values returned from the function will be used as the static features.

How do I use this package?

TODO: Add appropriate usage and instruction guidelines

How do I contribute?

We appreciate your interest! Please see the Dojo 2 Meta Repository for the Contributing Guidelines and Style Guide.

Testing

Test cases MUST be written using Intern using the Object test interface and Assert assertion interface.

90% branch coverage MUST be provided for all code submitted to this repository, as reported by istanbul’s combined coverage results for all supported platforms.

To test locally in node run:

grunt test

To test against browsers with a local selenium server run:

grunt test:local

To test against BrowserStack or Sauce Labs run:

grunt test:browserstack

or

grunt test:saucelabs

Licensing information

The original Dojo 1 has() API was based upon Peter Higgin's has.js.

© 2016 Dojo Foundation & contributors. New BSD license.