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

gatsby-ts

v1.0.0-rc.1

Published

Configure Gatsby to use Typescript configuration files

Downloads

1

Readme

Configure Gatsby to use Typescript for configuration files

paypal

This plugin will allow you to write your gatsby-* configuration files in Typescript.


Installation

  • Install using your package manager

    npm install gatsby-ts
  • Use gatsby-ts in place of gatsby

    package.json

    {
      "scripts": {
        "build": "gatsby-ts build",
        "develop": "gatsby-ts develop"
      }
    }

    All of the flags & options provided to gatsby-ts will be passed through to gatsby.

  • Write your gatsby-config and gatsby-node in Typescript

Usage

You may write your gatsby-config and gatsby-node files how you would normally, except you will be writing them in Typescript.

Some examples:

// .gatsby-ts.js
const { createOptions } = require("gatsby-ts");

module.exports = createOptions({
  type: "babel",
  props: {
    test: "Hello",
  },
});
// gatsby-config.ts
import { loadPluginsDeferred, withMetaConfig, GatsbyPlugin } from "gatsby-ts";
import type { PluginOptions as ITypegenPluginOptions } from 'gatsby-plugin-typegen/types';
import type { IPluginOptions as IPnpmPluginOptions } from 'gatsby-plugin-pnpm';
import type { FileSystemConfig } from 'gatsby-source-filesystem';

type PluginDefs = (
  | GatsbyPlugin<'gatsby-plugin-typegen', ITypegenPluginOptions>
  | GatsbyPlugin<'gatsby-plugin-pnpm', IPnpmPluginOptions>
  | FileSystemConfig
)

type PropertyBag = {
  test: string;
}

loadPluginsDeferred<
  PluginDefs,
  PropertyBag
>(() => ([
  {
    resolve: `gatsby-plugin-typegen`,
    options: {
      // These options will be typed
    },
  },
]));

export default withMetaConfig(({ loadPlugins }, props) => {
  console.log(props.test) // Hello
  props.test += " world"


  const plugins = loadPlugins<PluginDefs, PropertyBag>([
    // All of these will be typed
    {
      resolve: `gatsby-plugin-pnpm`,
      options: {
        strict: true,
        projectPath: __dirname,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
  ]);

  return {
    siteMetadata: {
      title: "Foo site",
    },
    plugins: [
      ...plugins,

      // These are not typed
      {
        resolve: "foo-plugin"
      }
    ]
  }
})
// gatsby-node.ts
import { withMetaNode } from "gatsby-ts";

/**
 * Can easily do this the normal way
 *
 * import { GatsbyNode } from "gatsby";
 *
 * export const sourceNodes: GatsbyNode["sourceNodes"] = ({ actions }) => {
 *   // do something
 * }
 */

export default withMetaNode((args, props) => {
  console.log(props.test) // Hello world

  return {
    sourceNodes: async ({
      actions,
    }): Promise<void> => {
      /**
       * Create your nodes here
       */

      console.log("Hello from sourceNodes!!\n\n\n");
      return;
    },

    onCreateWebpackConfig: ({
      actions,
      getConfig,
    }) => {
      const config = getConfig();
      // Do something with the config
    },
  };
});

Configuration

Each project that employs this utility may define their own configurations. This primarily serves the purpose of configuring what transpiler to use and its options, but also allows you to define a "property bag" that will be passed around to the meta functions described later.

  • Create the file .gatsby-ts.js in the root of the project using this utiltiy.

    // This function will give you intellisense for the object structure
    const { createOptions } = require("gatsby-ts");
    
    module.exports = createOptions({
      type: "babel", // | "ts-node"
      transpilerOptions: {
        // ... any transpiler options applicable to the chosen transpiler
      },
      props: {
        // ... Put any object you wish here.  It will be passed around to gatsby-ts meta functions
      }
    })

Option Descriptions

  1. type: "babel" | "ts-node"

    • Tells gatsby-ts what transpiler to use. For ts-node, typescript must be installed.
  2. transpilerOptions: Object

    • If you chose babel as your type, see the babel docs for configuration details
    • if you chose ts-node as your type, see the ts-node docs for configuration details
  3. props: Object

    • This can be any object you choose. It will be passed around as-is to each "meta" function that you define. Any of those functions may mutate the props, and the affect will be passed along.
  4. hooks: HooksObject

    • See Hooks for more details

Property Bag

This object may take any shape you want, and serve any purpose you want. It is completely free-form. gatsby-ts itself doesn't care about it at all, and its sole purpose is to pass around values that you wish between gatsby-config, and gatsby-node.

A couple of notes regarding the property bag:

  • One will be passed to the meta functions whether or not you define it in .gatsby-ts.js

  • The property bag is mutable, so you may make changes to it in one function, and those changes will be passed over to the other.

  • When calling local plugins (ones you have designed yourself inside of the /plugins folder), the property bag for the current project will be copied and passed to them.

Hooks

You may hook into some of the internal processes of gatsby-ts by defining the hooks property on your configuration object.

Hooks that are available:

  1. ignore: Array<(filename: string, original: boolean) => boolean | void>
    • This hook allows you to define an array of functions that will be treated as ignore rules for the transpiler. The file currently being processed will be passed in the first parameter, and whatever ignore value gatsby-ts would have used originally will be the second parameter.

    • The first function to return true (or a truthy value) will cause the file to be ignored.

"Meta" Functions

These are functions that receive certain meta values / utilities from gatsby-ts. Their use is completely optional, but may be useful in certain situations. They receive in their parameters certain details about the project that's currently being transpiled, certain utility functions, as well as the "Property Bag" that gets passed around to all of the "Meta" functions for the current project.

The function you'll use depends on the file you are setting up:

|API Type|Meta Function Factory| |--------|---------------------| |gatsby-config|withMetaConfig()| |gatsby-node|withMetaNode()|

Each meta function factory takes a single callback:

type MetaCb = (args: MetaCbArgs, props: PropertyBag) => GatsbyConfig | GatsbyNode

MetaCbArgs: Object

Common Properties
  • projectRoot: The absolute path to the current project.
  • imports: All of the imports used by your gatsby-* modules.
    • This is structured by API Type, and then by plugin + API Type
      • config: string[]
      • node: string[]
      • plugins: Object
        • [pluginName: string]: Object
          • config: string[]
          • node: string[]

withMetaConfig() Properties

  • loadPlugins: (input: GatsbyPlugin[] | MetaCb) => GatsbyPlugin[]
    • Use this function to generate a strongly typed array of gatsby plugin definitions.

      It has a generic type parameter that you can use to define a union of accepted gatsby plugins & options. This allows you to restrict the plugin definitions the types that are (hopefully) published by each plugin.

    • See more details in Generating plugin arrays (For details about this function specifically, see this section)

Generating plugin arrays

It may be desirable to apply types to the plugin array that you define for Gatsby's consumption. Some plugins already publish types for their configurations, so gatsby-ts provides a method to make appyling those types easier.

There are two APIs to facilitate this:

  • loadPluginsDeferred
  • loadPlugins

These functions accept callbacks that behave exactly the same as the ProjectMetaCb described earlier

Generic Type Parameters

Each of these APIs can be used with two generic type parameters,

  • PluginDefinitions - Should be a union of various plugin declaration types, in the format:

    type PluginDef = string | {
      resolve: string;
      options: Record<string, any> | PluginOptions
    }

    To make this easy, gatsby-ts provides a type utility called GatsbyPlugin.

    import { GatsbyPlugin } from "gatsby-ts";
    
    type PluginDefs = (
      | GatsbyPlugin<"gatsby-source-filesystem", {
        // Options
      }>
      | GatsbyPlugins<"foo-plugin", {
        // Options
      }>
    );
  • PropertyBag - Defines the structure of the property bag passed to the callback.

loadPluginsDeferred

Plugins defined with this API will not be included until all of the current project's modules are completed processing. The reason for this is that the various properties passed to the callback are updated as the project is processed, so deferring the loading of the plugins until the end ensures that they get the most up to date information.

Loading plugins this way causes them to be appended to the end of the plugin array that is passed to Gatsby.

import { loadPluginsDeferred, GatsbyPlugin } from "gatsby-ts";

type PluginDefinitions = (
  | GatsbyPlugin<'foo', IFooPluginOptions>
  | 'bar'
  | { resolve: 'bar'; options: { qux: number }; }
)

type PropertyBag = {
  random: string;
  properties: number[];
}

loadPluginsDeferred<PluginDefinitions, PropertyBag>(
  ({ projectRoot, imports }, {random, properties}) => {
    // Build plugin array
  })
);

loadPlugins

This function is passed to ProjectMetaCb functions withMetaConfig. It accepts either an array of plugins, or its own ProjectMetaCb. This array/cb will be processed immediately.

You may use the same generic type parameters for this function as well:

import { withMetaConfig, GatsbyPlugin } from "gatsby-ts";

type PluginDefinitions = (
  | GatsbyPlugin<'foo', IFooPluginOptions>
  | GatsbyPlugin<"bar", { qux: number }>
  | "baz"
)

type PropertyBag = {
  random: string;
  properties: number[];
}

export default withMetaConfig(({ loadPlugins }, { random, properties }) => {

  const plugins = loadPlugins<PluginDefinitions, PropertyBag>([
    {
      resolve: "foo",
      options: { ...opts }
    },
    {
      resolve: "bar",
      options: { qux: 1234 }
    },
    "baz" // Or `{ resolve: "baz" }` but there's no options
  ])

  return {
    plugins,
  }

})

Contributing / Issues

If you feel a feature is missing, or you find a bug, please feel free to file an issue at https://github.com/Js-Brecht/gatsby-plugin-ts-config/issues.

I would also welcome any additions anybody would like to make.

Donations

If you enjoyed using this plugin, and you'd like to help support its development, you're welcome to donate!

paypal