function main( context ) {
	var options;
	var opts;

	opts = copy( DEFAULTS );
	options = context.options[ 0 ];
	if ( hasOwnProp( options, 'globals' ) ) {
		opts.globals = options.globals;
	}
	/**
	* Reports the error message.
	*
	* @private
	* @param {ASTNode} node - node to report
	* @param {string} name - name of global variable
	*/
	function report( node, name ) {
		context.report({
			'node': node,
			'message': name+' is used without loading it beforehand via require()'
		});
	}

	/**
	* Checks whether a global is loaded via `require()` before invocation.
	*
	* @private
	* @param {ASTNode} node - node to examine
	* @returns {void}
	*/
	function validate( node ) {
		var scope;
		var name;
		var i;

		// Skip when the identifier refers to the key of an object:
		if ( node.parent.type === 'MemberExpression' ) {
			return void 0;
		}

		scope = context.getScope( node );
		for ( i = 0; i < opts.globals.length; i++ ) {
			name = opts.globals[ i ];
			if ( node.name === name ) {
				if ( !searchScopes( scope, name ) ) {
					report( node, name );
				}
				break;
			}
		}
	}

	/**
	* Traverses the parent scopes searching for a variable declaration of the given global variable.
	*
	* @private
	* @param {Object} scope - scope to examine
	* @param {string} name - name of the global variable
	* @returns {boolean} boolean indicating whether a variable declaration for the given global was found
	*/
	function searchScopes( scope, name ) {
		if ( !scope ) {
			return false;
		}
		if ( scope.set.has( name ) ) {
			// Check whether the definition is due to an implicit global or not:
			return scope.set.get( name ).defs.length > 0;
		}
		return searchScopes( scope.upper, name );
	}

	return {
		'Identifier': validate
	};
}
Rule to enforce that specified global variables are explicitly required before invocation.

@param {Object} context - ESLint context
@returns {Object} validators