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

ts-transform-auto-require

v1.3.0

Published

Typescript transformer used to require all files matching a pattern

Downloads

15

Readme

npm package License Build Status Coverage Status Issues

ts-transform-auto-require - Typescript transformer used to require all files matching a pattern

This transformer fills in a variable initializer in a file with the content of files matching a glob. For example, with this file structure:

.
└── themes/
    ├── index.ts
    ├── dark.ts
    ├── magic.ts
    └── partial/
        ├── light.ts
        └── stars.ts

and this file content:

// locales/index.ts
import { Theme, createTheme } from '../Theme'

const allThemes: { [name: string]: Theme } = {}

Object.entries(allThemes).forEach(([name, theme]) => createTheme(name, theme))

the transformer will fill in the allThemes variable so the file will be:

// locales/index.ts
import { Theme, createTheme } from '../Theme'

const allThemes: { [name: string]: Theme } = {
  dark: require('./dark').default,
  magic: require('./magic').default,
  'partial/light': require('./partial/light').default,
  'partial/stars': require('./partial/stars').default,
}

Object.entries(allThemes).forEach(([name, theme]) => createTheme(name, theme))

Language/langue

Documents, messages, code (including variable names and comments), are in English.

Anyway, because Slune is French firm, all documents and important messages must also be provided in French. Other translations are welcome.

:fr: Une version française de ce document se trouve ici.

Installation

Installation is done using npm install command:

$ npm install --save-dev ts-transform-auto-require

Why would I need that?

You have an extensible application in which you can drop some locales, plugins, loaders, themes or whatever you want, and you need a place to require them all (probably an index file) for they are available in the application. How can you deal with that?

  • You can manually update the aggregation file each time you create a new extension file… provided that you don't forget! In big organizations, it is rather easy to forget and even don't notice it, so that the added file will never be used.
  • You can read and require the files at runtime. This will need to code the file search process, which will consume time. There even may be some situations where it would not work (e.g. if the module is executed in a web browser).
  • You may write a tool which creates the index file at build time. In order not to forget it, you should add it to your build process. But you will also need to provide at least a fake aggregation file in order for TypeScript to be able to check types, or for the unit tests.

Using the transformer, you will not need to do any of that. Simply write your aggregation file, which contains an initialized variable. You can even put fake initialization in there, if you need it for tests, it will be replaced by the transformer. Once this is done, you can add your extension files, and they will be automatically added to the variable.

Usage

The transformer holds its configuration under the autoRequires parameters, which is an array of objects containing:

  • source: the definition of the source, the files to be required — this is a mandatory object containing:
    • glob: the glob format used to select files, relative to project root — this parameter is mandatory;
    • ignore: either a string or an array of strings for the files to ignore — the value is directly given to the ignore option of glob — this parameter is optional.
  • target: the definition of the target, where variable to be initialized will be found — this is a mandatory object containing:
    • file: the name of the file containing the variable (mandatory);
    • variable: the name of the variable to initialize with the requires (mandatory);
    • codeExtensions: a list of extensions used to identify source code files — default is ['js', 'jsx', 'ts', 'tsx'].

There is currently no way of declaring a transformer in the vanilla TypeScript compiler. If you do not want to write your own compiler using the typescript API, you can use the ttypescript wrapper.

Automatic fill-in

The code part to fill in by the transformer has to follow those rules:

  • it must be a variable declaration, using const, let, or var;
  • the variable name may be followed by a type definition;
  • the variable must be followed by an immediate initialization;
  • the initialization value must be an object literal;
  • the initialization object can be empty or not;
  • the initialization may be followed by a type cast.

All the below variable declarations are suitable for automatic filling:

const allThemes: { [name: string]: Theme } = {}
let loaders = {} as { [name: string]: Loader; default: Loader }
var myVar = { fake: 'Fake testing value' }

Required file names

Files are treated differently whether they are considered source code files or not (see configuration entry target.codeExtensions). JSON files, for example, can be required this way, but for other extensions, it is the responsibility of the developper to do what is needed in order for NodeJS to be able to load the files.

Source code files

Source code file paths are treated like that:

  • the file name (with path) is taken relatively to the target file;
  • the extension is removed (needed for, for example, TypeScript .ts files which are transpiled into .js at runtime).

In the variable, the key is associated to the default export of the file.

For example, in an index file collecting files in the same directory, the entry key is then simply the base name of the file without extension. If the file is in a subfolder, the subfolder name will also be present (e.g. subfolder/file). If we must climb up a folder (or more) to reach the file, the entry key will start with ...

Ordinary files

Treatments of ordinary files have the following differences:

  • the extension is kept, both in the variable key and in the require statement;
  • in the variable, the key is associated to the full require result.

Configuration with ttypescript

For ttypescript, configure your tsconfig.json. Example:

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "ts-transform-auto-require",
        "autoRequires": [
          {
            "source": {
              "glob": "themes/**/*.ts",
              "ignore": ["**/index.ts", "**/*.spec.ts"]
            },
            "target": {
              "file": "themes/index.ts",
              "variable": "allThemes"
            }
          },
          {
            "source": { "glob": "**/loader-*.cts" },
            "target": {
              "file": "loader.ts",
              "variable": "loaders",
              "codeExtensions": ["cts"]
            }
          }
        ]
      }
    ]
  }
}

The transformer is of type program (which is the default for ttypescript).

Notices

  • The same file name, and even the same full target can appear multiple times in the configuration. All matching requires will be merged.
  • All matching variables will be filled in, so ensure not to have multiple variables with the configured name (the transformer does not care of the scopes).
  • Files to require must be under the project root. Files outside of the root directory will be ignored, even if they match the provided glob.

Contributing

Even though we cannot guarantee a response time, please feel free to file an issue if you have any question or problem using the package.

Pull Requests are welcome. You can, of course, submit corrections or improvements for code, but do not hesitate to also improve documentation, even for small spell or grammar errors.