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

webpack-typings-for-json

v0.12.0

Published

Webpack loader that generates TypeScript typings for JSON files

Downloads

112

Readme

Webpack typings for JSON loader

NPM License Coverage Downloads Build

Webpack loader that generates TypeScript typings for JSON files

Installation

npm install webpack-typings-for-json --save-dev

webpack.config.js

module.exports = {
    module: {
        rules: [{
            test: /\.json$/,
            type: 'javascript/auto',
            use: [{
                loader: 'webpack-typings-for-json'
            }]
        }]
    }
};

Example (i18n)

Let's say our project uses a JSON based localization setup, like i18next and we have the following file: ./src/locale/en.js in your project, containing the following (simple) resource strings:

{
    "align-left": "Align left",
    "align-center": "Align centre",
    "align-right": "Align right",
    "justify": "Justify",
    "bullet-list": "Bullet list",
    "numbered-list": "Numbered list",
    "decrease-indent": "Decrease indent",
    "increase-indent": "Increase indent"
}

When we add the webpack-typings-for-json loader, this will generate a TypeScript definition file ./src/locale/en.d.ts with the following content:

declare const locale = {
    alignLeft: 'align-left',
    alignCenter: 'align-center',
    alignRight: 'align-right',
    justify: 'justify',
    bulletList: 'bullet-list',
    numberedList: 'numbered-list',
    decreaseIndent: 'decrease-indent',
    increaseIndent: 'increase-indent'
} as const;

export type LocaleKey = string;

export default locale;

In your Typescript file you will now be able to import this localization file and get type hints with the available properties. The values for these properties are the keys of the original json:

import locale from './en.json';

console.log(locale.alignLeft); // "align-left"
console.log(locale.alignRight); // "align-right"
console.log(locale.alignCenter); // "align-center"
console.log(locale.justify); // "justify"

In your (React) component you can import this localization file and use the properties as input for the translation function / library to fetch the right string. This means: No more hard coded keys. And if someone changes the JSON, you will get compile time warnings!

import React from 'react';
import { useTranslation } from 'react-i18next';
import locale from './en.json';

export const MyComponent = () => {
    const { t } = useTranslation();
    return (
        <div>
           <span>{t(locale.alignLeft)}</span>
           <span>{t(locale.alignRight)}</span>
           <span>{t(locale.alignCenter)}</span>
           <span>{t(locale.justify)}</span>
        </div>
    );
};

Example (properties)

Some projects use a JSON file as a 'configuration' or 'settings' file that specifies build properties. For instance: A location to a server, some theme settings, etc. We normally embed these properties during build time (using Webpack), but they are never typed... You can use this same loader to generate typings for this JSON file and use the values, as if you are using a normal Typescript object.

Let's say you have the following settings file ./src/settings.json:

{
    "server": "https://github.com",
    "username": "John Doe",
    "theme": {
        "color": "#FF0000",
        "fonts": {
            "header": "{ font-family: monospace; font-size: 20px; }",
            "body": "{ font-family: monospace; font-size: 12px; }"
        }
    }
}

When we add the webpack-typings-for-json loader, then we can specify the option to include the values, rather then the keys in the output object:

webpack.config.js

module.exports = {
    module: {
        rules: [{
            test: /\.json$/,
            type: 'javascript/auto',
            use: [{
                loader: 'webpack-typings-for-json',
                options: {
                    exportValues: true
                }
            }]
        }]
    }
};

this will generate a TypeScript definition file ./src/settings.json.d.ts with the following content, as you can see this is just a normal Typescript interface that matches the JSON we are importing:

const locale = {
    server: 'https://github.com',
    username: 'John Doe',
    theme: {
        color: '#FF0000',
        fonts: {
            header: '{ font-family: monospace; font-size: 20px; }',
            body: '{ font-family: monospace; font-size: 12px; }'
        }
    }
} as const;

export type LocaleKey = string;

export default locale;

In your Typescript file you will now be able to import this settings file and get type hints with the available properties. The values for these properties are directly coming from the imported json

import settings from './settings.json';

console.log(settings.server); // https://github.com
console.log(settings.username); // John Doe
console.log(settings.theme.color); // #FF0000
console.log(settings.theme.fonts.header); // { font-family: monospace; font-size: 20px; }
console.log(settings.theme.fonts.body); // { font-family: monospace; font-size: 12px; }

Known issues

As the loader generates typing files, it is wise to tell webpack to ignore them. The fix is luckily very simple. Webpack ships with a "WatchIgnorePlugin" out of the box. Simply add this to your webpack plugins:

plugins: [
    new webpack.WatchIgnorePlugin([
        /json\.d\.ts$/
    ]),
    ...
]

You might see project warnings when you have not yet build the project. This happens because Typescript cannot import JSON files (since they are not official modules). In order to fix this you can add a type definition to your project:

./typings/json.d.ts

declare module '*.json' {

    declare const keys: {
        readonly [key: string]: string;
    };

    export type LocaleKey = string;

    export default keys;
}

tsconfig.json

{
    ...
    "files": [
        "./typings/json.d.ts"
    ],
    ...
}