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

ghostly-loader

v0.0.13

Published

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Downloads

4

Readme

Ghostly Loader

License: MIT

A wepback loader which allows developers to write alternate versions of your code (AKA ghosts), which are inserted into your codebase during bundling.

Developers can then control which version of their code executes at run time.

Try using ghostly for:

  • A/B/C... testing
  • Running a different set of code given a certain context (e.g. locale, localStorage)

Installation and Use With Webpack

The loader is built to work in tandem with the ghostly-controller, which is a library for helping you orchestrate when your ghosts should appear:

npm i --save-dev ghostly-loader
npm i --save ghostly-controller
or 
yarn add -D ghostly-loader
yarn add ghostly-controller

ghostly-controller is not actually required to use ghostly, more on this below.

In webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      { test: /\.js$/, use: 'ghostly-loader' },
    ],
  }

}

Usage

As of writing, ghosts can be created only with function declarations.

If in your source code you have a function that returns a greeting:

src/index.js

require('ghostly-controller')();

function myGreeting() {
    return "Hello!"
}

Then, in a separate file, you can write a ghost which will return a different greeting. Just make sure that the substitute code is in a file named with the pattern [target_file_name].ghost.js:

src/index.ghost.js

function myGreeting$spanish() {
    return "Hola!"
}

ghostly-controller places a function called determineGhost on the global scope. This function will be called with the name of the ghost and any configuration that the ghost function was created with. By default, ghostly-controller uses localStorage to help manage your ghosts; run webpack, then open localStorage in your dev tools to see the result. Try overwriting the data to control which version is run.

You can choose not to use ghostly-controller and define your own implementation in its place.

determineGhost will return either 'main' or the tag of the ghost that should be run in its place.

When 'main' is returned, the original or primary function will be used.

When the function and tag name are returned, the corresponding ghost will be used.

Multiple Ghosts

A single function may have many ghosts, they simply have to start with the name of the original function:

src/index.ghost.js

function myGreeting$spanish() {
    return "Hola!"
}

function myGreeting$german() {
    return "Hallo"
}

root

global.determineGhost = (functionName, config) => {
  assert(functionName === 'myGreeting')
  const ghostNames = Object.keys(config) // ['myGreeting$spanish', 'myGreeting$german']

  const randomIndex = Math.floor(Math.random() * ghostNames.length)

  return ghostNames[randomIndex]
}

Inline Configuration

Ghosts can be configured to run probalistically using inline comments.

Any text placed in a comment directly above your ghost will be sent to determineGhost when the function is called:

some-file.ghost.js

// 0.5
function myFunction$example() {
    return "I should be used half (0.5x) the time!"
}

In determineGhost:

global.determineGhost = (functionName, config) => {
  assert(functionName === 'myFunction')
  assert(config.myFunction$example === 0.5)

  if (functionName === 'myFunction') {
    return (Math.random() > config.myFunction$example) ? 'myFunction$example' : 'main'
  }
  
  return 'main';
}

General Syntax

function myFunction$optionalTagName () {
    // this code will run in place of the primary code.
}