Skip to content

Commit 56c5678

Browse files
committed
feat: init
1 parent f179c02 commit 56c5678

File tree

11 files changed

+321
-0
lines changed

11 files changed

+321
-0
lines changed

.github/workflows/deploy.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Deploy
2+
on:
3+
push:
4+
branches:
5+
- release
6+
7+
jobs:
8+
deploy:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v4
13+
14+
- name: Install
15+
uses: pnpm/action-setup@v4
16+
with:
17+
version: latest
18+
run_install: true
19+
20+
- name: Build
21+
run: tsc
22+
23+
- name: Assets
24+
run: |
25+
cp package.json dist/package.json
26+
cp README.md dist/README.md
27+
28+
- name: Config
29+
env:
30+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
31+
run: |
32+
cd dist
33+
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
34+
echo "registry=https://registry.npmjs.org/" >> ~/.npmrc
35+
36+
- name: Publish
37+
run: |
38+
cd dist
39+
pnpm publish --access public --no-git-checks

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.idea
3+
package-lock.json
4+
pnpm-lock.yaml
5+
dist

README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# esbuild plugin typescript
2+
3+
![NPM Downloads](https://img.shields.io/npm/dw/esbuild-plugin-typescript) ![NPM License](https://img.shields.io/npm/l/esbuild-plugin-typescript)
4+
5+
The plugin enhances the build process by seamlessly integrating TypeScript, offering powerful features like type checking, automatic generation of .d.ts files, and ensuring robust type safety
6+
throughout.
7+
8+
* Supports newest esbuild and typescript version
9+
* Uses esbuild config to determine the out folder
10+
* Can do everything that TypeScript offers
11+
* Type declarations (d.ts) included
12+
13+
## How It Works
14+
15+
1. esbuild calls this package in the onStart lifecycle.
16+
2. Gets the configuration from esbuild or user-defined configuration.
17+
3. Evaluate the out folder, that should be deleted, based on the given input.
18+
4. Runs the official TypeScript-Compiler by its API and\
19+
generates output based on the given tsconfig.
20+
21+
## Options
22+
23+
### Overriding the out-folder
24+
25+
This package will search for a tsconfig by TypeScript itself.
26+
It can be helpful sometimes to override the path to the tsconfig:
27+
```typescript
28+
typescriptPlugin(
29+
overrideConfigPath?: string | undefined
30+
);
31+
```
32+
33+
After using this override, this package will start to resolve your tsconfig. If your override is not valid, because the tsconfig does not exists, this package will discover the nearest tsconfing.
34+
35+
## Usage
36+
37+
### Installation
38+
39+
The plugin can be installed by any package manager.
40+
41+
<details><summary><b>Show instructions</b></summary>
42+
43+
> npm \
44+
> ``npm install esbuild-plugin-typescript``
45+
46+
> yarn \
47+
> ``yarn install esbuild-plugin-typescript``
48+
49+
> pnpm \
50+
> ``pnpm install esbuild-plugin-typescript``
51+
52+
</details>
53+
54+
### Integration
55+
56+
The easy way to integrate this plugin in esbuild.
57+
58+
<details><summary><b>Show instructions</b></summary>
59+
60+
````typescript
61+
await esbuild.build({
62+
plugins: [
63+
typescriptPlugin(...)
64+
]
65+
})
66+
````
67+
68+
[See here for more about the esbuild plugin integration.](https://esbuild.github.io/plugins/#using-plugins)
69+
70+
</details>
71+
72+
## License
73+
74+
The MIT License (MIT) - Please have a look at the LICENSE file for more details.
75+
76+
## Contributing
77+
78+
Feel free to contribute to this project.\
79+
You can fork this project and create a new pull request for contributing.
80+
81+
[Get to the repository at GitHub.](https://github.com/simonkovtyk/esbuild-plugin-typescript)
82+
83+
<hr>
84+
85+
GitHub [@simonkovtyk](https://github.com/simonkovtyk)

package.json

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "esbuild-plugin-typescript",
3+
"description": "The plugin enhances the build process by seamlessly integrating TypeScript, offering powerful features like type checking, automatic generation of .d.ts files, and ensuring robust type safety throughout.",
4+
"keywords": [
5+
"frontend",
6+
"backend",
7+
"packages",
8+
"esbuild",
9+
"build",
10+
"esbuild plugin",
11+
"esbuild tool",
12+
"build plugin",
13+
"build tool",
14+
"typescript",
15+
"developer tools",
16+
"build process",
17+
"plugin",
18+
"d.ts",
19+
"tsc",
20+
"type checking",
21+
"type check",
22+
"esbuild d.ts",
23+
"esbuild typescript",
24+
"esbuild type check",
25+
"esubild type checking",
26+
"esbuild tsc"
27+
],
28+
"license": "MIT",
29+
"version": "1.0.0",
30+
"bugs": "https://github.com/simonkovtyk/esbuild-plugin-typescript/issues",
31+
"homepage": "https://github.com/simonkovtyk/esbuild-plugin-typescript",
32+
"repository": {
33+
"type": "git",
34+
"url": "git+https://github.com/simonkovtyk/esbuild-plugin-typescript.git"
35+
},
36+
"exports": {
37+
".": {
38+
"default": "./public-api.js",
39+
"types": "./public-api.d.ts"
40+
}
41+
},
42+
"author": {
43+
"name": "Simon Kovtyk",
44+
"url": "https://github.com/simonkovtyk",
45+
"email": "[email protected]"
46+
},
47+
"maintainers": [
48+
{
49+
"name": "Simon Kovtyk",
50+
"url": "https://github.com/simonkovtyk",
51+
"email": "[email protected]"
52+
}
53+
],
54+
"dependencies": {
55+
"esbuild": ">=0.20.0"
56+
},
57+
"devDependencies": {
58+
"@types/node": "^22.5.4",
59+
"typescript": "^5.5.4"
60+
}
61+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
enum ErrorMessages {
2+
TSCONFIG_NOT_FOUND = "The tsconfig file was not found. Please make sure it is inside your project root."
3+
}
4+
5+
export {
6+
ErrorMessages
7+
}

src/core/plugin.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Plugin, PluginBuild } from "esbuild";
2+
import { handlerProcedure } from "./procedures/handler.procedure";
3+
import { Options } from "./types/options.type";
4+
5+
const typescriptPlugin = (options: Options): Plugin => ({
6+
name: "esbuild-plugin-typescript",
7+
setup: (build: PluginBuild) => {
8+
const handlerUnwrapped = handlerProcedure({
9+
...options,
10+
tsconfigPath: build.initialOptions.tsconfig
11+
});
12+
13+
build.onStart(handlerUnwrapped);
14+
}
15+
});
16+
17+
export {
18+
typescriptPlugin
19+
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { OnStartResult } from "esbuild";
2+
import path from "node:path";
3+
import ts from "typescript";
4+
import { ErrorMessages } from "../constants/messages.constant";
5+
import { HandlerOptions } from "../types/options.type";
6+
import { mapDiagnosticsToPartialMessages } from "../utils/error.util";
7+
8+
const handlerProcedure = (options: HandlerOptions) => {
9+
return async (): Promise<OnStartResult | null> => {
10+
const parsedTsconfigPath = options.tsconfigPath === undefined ? undefined : path.parse(options.tsconfigPath);
11+
12+
const configFile = ts.findConfigFile(
13+
parsedTsconfigPath?.dir ?? ".",
14+
ts.sys.fileExists,
15+
parsedTsconfigPath?.base
16+
);
17+
18+
if (configFile === undefined)
19+
return {
20+
errors: [ {
21+
text: ErrorMessages.TSCONFIG_NOT_FOUND
22+
} ]
23+
};
24+
25+
const config = ts.readConfigFile(configFile, ts.sys.readFile);
26+
const parsedConfig = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configFile));
27+
28+
const host = ts.createCompilerHost(parsedConfig.options, true);
29+
const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options, host);
30+
31+
program.emit();
32+
33+
const redundantDiagnostics = ts.getPreEmitDiagnostics(program);
34+
const sourceDiagnostics = ts.sortAndDeduplicateDiagnostics(redundantDiagnostics);
35+
const configDiagnostics = parsedConfig.errors;
36+
37+
if (sourceDiagnostics.length === 0 && configDiagnostics.length === 0)
38+
return null;
39+
40+
const partialSourceMessages = mapDiagnosticsToPartialMessages(host, Array.from(sourceDiagnostics));
41+
const partialConfigMessages = mapDiagnosticsToPartialMessages(host, configDiagnostics);
42+
43+
return {
44+
errors: partialSourceMessages,
45+
warnings: partialConfigMessages
46+
};
47+
}
48+
}
49+
50+
export {
51+
handlerProcedure
52+
}

src/core/types/options.type.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type PathOverrides = {
2+
overrideConfigPath: string | undefined
3+
}
4+
5+
type HandlerOptions = {
6+
tsconfigPath?: string | undefined
7+
} & PathOverrides
8+
9+
type Options = PathOverrides;
10+
11+
export type {
12+
PathOverrides,
13+
HandlerOptions,
14+
Options
15+
}

src/core/utils/error.util.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { PartialMessage } from "esbuild";
2+
import os from "node:os";
3+
import ts from "typescript";
4+
5+
const mapDiagnosticsToPartialMessages = (host: ts.CompilerHost, diagnostics: ts.Diagnostic[]) => diagnostics.map((diagnostic: ts.Diagnostic): PartialMessage => {
6+
if (diagnostic.file === undefined || diagnostic.start === undefined)
7+
return {
8+
text: ts.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL, 2)
9+
};
10+
11+
return {
12+
text: ts.formatDiagnostic(diagnostic, host)
13+
}
14+
});
15+
16+
export {
17+
mapDiagnosticsToPartialMessages
18+
}

src/public-api.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./core/plugin";
2+
export * from "./core/types/options.type";

tsconfig.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"outDir": "dist",
4+
"module": "NodeNext",
5+
"target": "ESNext",
6+
"moduleResolution": "NodeNext",
7+
"allowSyntheticDefaultImports": true,
8+
"strict": true,
9+
"noImplicitAny": true,
10+
"noImplicitThis": true,
11+
"noImplicitReturns": true,
12+
"noImplicitOverride": true,
13+
"noUncheckedIndexedAccess": true,
14+
"declaration": true,
15+
"alwaysStrict": true,
16+
"isolatedModules": true
17+
}
18+
}

0 commit comments

Comments
 (0)