An open API service indexing awesome lists of open source software.

https://github.com/jirutka/ts-transformer-inline-file

A TypeScript custom transformer for inlining files
https://github.com/jirutka/ts-transformer-inline-file

inline typescript typescript-transformer

Last synced: 8 months ago
JSON representation

A TypeScript custom transformer for inlining files

Awesome Lists containing this project

README

          

= TypeScript transformer for inlining files
:npm-name: ts-transformer-inline-file
:gh-name: jirutka/{npm-name}
:gh-branch: master
:vs-marketplace-uri: https://marketplace.visualstudio.com/items?itemName=

ifdef::env-github[]
image:https://github.com/{gh-name}/workflows/CI/badge.svg[Build Status, link=https://github.com/{gh-name}/actions?query=workflow%3A%22CI%22]
image:https://img.shields.io/npm/v/{npm-name}.svg[npm Version, link="https://www.npmjs.org/package/{npm-name}"]
endif::env-github[]

This is a TypeScript AST transformer footnote:[If you’ve never heard about TypeScript transformers, I can recommend https://blog.logrocket.com/using-typescript-transforms-to-enrich-runtime-code-3fd2863221ed/[this blog post] to dive into the topic.] that allows you to include content of a file into the transpiled code, i.e. _inline it_ in build-time.

You can think about it as a C preprocessor’s directive `#include` but more powerful… way more powerful.
If the referenced file is a JSON file, it doesn’t include it as a string but converts the JSON to an object literal.
Thus it can be further optimized by a minifier.
Moreover, if you use an object destructing assignment, this transformer will optimize it itself -- include only the assigned properties!

== Usage

Add {npm-name} package to your project as a **dev**elopment dependency and <>.

=== Inline Any Textual File

[source, js, subs="+attributes"]
----
import { $INLINE_FILE } from '{npm-name}'

const words = $INLINE_FILE('../data/words.txt').trim().split(' ')
----

This will be transformed into:

[source, js]
const words = "lorem ipsum dolor\n".trim().split(' ');

…where `"lorem ipsum dolor\n"` is full content of the file `../data/words.txt`.

=== Inline JSON Data

[source, js, subs="+attributes"]
----
import { $INLINE_JSON } from '{npm-name}'

const pkg = $INLINE_JSON('../package.json')
----

This will be transformed into:

[source, js]
const pkg = { "name": "my-package", "version": "0.1.0", "license": "MIT", ... }

However, if you need only few properties from the referenced JSON file, use object destructuring assignment:

[source, js]
const { name, version } = $INLINE_JSON('../package.json')

…and the transformer will include only the assigned properties:

[source, js]
const { name, version } = { "name": "my-package", "version": "0.1.0" }

NOTE: This works only for the top level; filtering of nested properties is currently not supported.

== How to Configure the Transformer

Unfortunately, TypeScript itself does not currently provide any easy way to use custom transformers (see https://github.com/Microsoft/TypeScript/issues/14419[Microsoft/TypeScript#14419]).
Fortunately, there are few solutions.

=== TTypescript

If you don’t use any bundler such as Rollup or webpack, https://github.com/cevek/ttypescript[TTypescript] is the way to go.
It provides wrappers `ttsc` and `ttserver` for the `tsc` and `tsserver` commands that add support for custom transformers.
All you have to do is to use these wrappers instead of the original commands and define the transformer in your `tsconfig.json`:

.tsconfig.json:
[source, jsonc, subs="+attributes"]
----
{
"compilerOptions": {
// ...
"plugins": [
{ "transform": "{npm-name}/transformer" }
]
},
// ...
}
----

=== Rollup (with rollup-plugin-typescript2)

.rollup.config.js:
[source, js, subs="+attributes"]
----
import typescript from 'rollup-plugin-typescript2'
import inlineFileTransformer from '{npm-name}/transformer'

export default {
// ...
plugins: [
typescript({
transformers: [
(service) => ({
before: [ inlineFileTransformer(service.getProgram()) ],
after: [],
}),
],
}),
],
}
----

=== Webpack (with ts-loader or awesome-typescript-loader)

.webpack.config.js:
[source, js, subs="+attributes"]
----
const inlineFileTransformer = require('{npm-name}/transformer').default

module.exports = {
// ...
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader', // or 'awesome-typescript-loader',
options: {
getCustomTransformers: (program) => ({
before: [
inlineFileTransformer(program),
],
}),
},
},
],
},
}
----

ifndef::npm-readme[]

== Development

=== System Requirements

* https://nodejs.org[NodeJS] 14+
* https://pandoc.org[Pandoc] and https://asciidoctor.org[Asciidoctor] (used only for converting README.adoc to Markdown for npmjs)

=== Used Tools

* https://www.typescriptlang.org[TypeScript] the language
* https://yarnpkg.com[yarn] for dependencies management and building
* https://eslint.org[ESLint] for linting JS/TypeScript code
* https://github.com/substack/tape[tape] for testing

=== How to Start

. Clone this repository:
[source, subs="+attributes"]
git clone https://github.com/{gh-name}.git
cd {npm-name}

. Install Yarn (if you don’t have it already):
[source]
npm install -g yarn

. Install all JS dependencies:
[source]
yarn install

. Build the project:
[source]
yarn build

. Run tests:
[source]
yarn test

. Run linter:
[source]
yarn lint

=== Visual Studio Code

If you use Visual Studio Code, you may find the following extensions useful:

* link:{vs-marketplace-uri}EditorConfig.EditorConfig[EditorConfig for VS Code]
* link:{vs-marketplace-uri}dbaeumer.vscode-eslint[ESLint]
* link:{vs-marketplace-uri}gamunu.vscode-yarn[yarn]

endif::[]

== License

This project is licensed under http://opensource.org/licenses/MIT/[MIT License].
For the full text of the license, see the link:LICENSE[LICENSE] file.