From 3796b08d212179a1ebb341a27a6e42adbce25cba Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 19 Sep 2024 21:31:57 +0200 Subject: [PATCH 1/4] feat: added linter and proper docs --- .github/workflows/pull-request.yml | 27 ++++ .husky/pre-commit | 2 + README.md | 134 +++++++++++++------- docs/esbuild-favicon.svg | 7 ++ docs/guides/HOW_TO_CONTRIBUTE.md | 150 +++++++++++++++++++++++ eslint.config.mjs | 25 ++++ package.json | 17 ++- src/core/constants/messages.constant.ts | 6 +- src/core/plugin.ts | 25 ++-- src/core/procedures/handler.procedure.ts | 66 +++++----- src/core/types/options.type.ts | 18 +-- src/core/utils/error.util.ts | 18 +-- 12 files changed, 379 insertions(+), 116 deletions(-) create mode 100644 .github/workflows/pull-request.yml create mode 100644 .husky/pre-commit create mode 100644 docs/esbuild-favicon.svg create mode 100644 docs/guides/HOW_TO_CONTRIBUTE.md create mode 100644 eslint.config.mjs diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..190a4cd --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,27 @@ +name: Pull request checks +on: + pull_request: + types: + - opened + - reopened + branches: + - main + +jobs: + pull_request: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install + uses: pnpm/action-setup@v4 + with: + version: latest + run_install: true + + - name: TypeScript Compiler + run: tsc --noEmit + + - name: Lint + run: pnpx eslint . diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..8ccff6f --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +pnpx eslint . +tsc --noEmit diff --git a/README.md b/README.md index eaded57..9c11422 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,128 @@ -# esbuild plugin typescript +
-![NPM Downloads](https://img.shields.io/npm/dw/esbuild-plugin-typescript) ![NPM License](https://img.shields.io/npm/l/esbuild-plugin-typescript) + -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. +

TypeScript Plugin

-* Supports newest esbuild and typescript version -* Uses esbuild config to determine the out folder -* Can do everything that TypeScript offers -* Type declarations (d.ts) included +

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.

-## How It Works +![NPM Downloads](https://img.shields.io/npm/dw/esbuild-plugin-typescript) +![NPM License](https://img.shields.io/npm/l/esbuild-plugin-typescript) +![GitHub package.json version](https://img.shields.io/npm/v/esbuild-plugin-typescript) +![TypeScript types](https://img.shields.io/badge/TypeScript_types-included-blue) -1. esbuild calls this package in the onStart lifecycle. -2. Gets the configuration from esbuild or user-defined configuration. -3. Evaluate the out folder, that should be deleted, based on the given input. -4. Runs the official TypeScript-Compiler by its API and\ -generates output based on the given tsconfig. +
-## Options +Add a โญ to this repository โ€” *it motivates me a lot!* -### Overriding the out-folder +
-This package will search for a tsconfig by TypeScript itself. -It can be helpful sometimes to override the path to the tsconfig: -```typescript -typescriptPlugin( - overrideConfigPath?: string | undefined -); -``` +## โšก๏ธ Getting started -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. +Simply install this package with your package manager. + +````shell +npm install -D esbuild-plugin-typescript +```` -## Usage +
+๐Ÿ“ฆ other package manager -### Installation +Here are examples for installing the package with other package manager. -The plugin can be installed by any package manager. +> ๐Ÿ’พ **yarn** +> ````shell +> yarn add -D esbuild-plugin-typescript +> ```` -
Show instructions +> ๐Ÿ’พ **pnpm** +> ````shell +> pnpm install -D esbuild-plugin-typescript +> ```` -> npm \ -> ``npm install esbuild-plugin-typescript`` +
-> yarn \ -> ``yarn install esbuild-plugin-typescript`` +Looks good so far ๐Ÿ”ฅ โ€” now you have installed the latest version! -> pnpm \ -> ``pnpm install esbuild-plugin-typescript`` +## ๐Ÿ’ก Introduction -
+This esbuild plugin integrates TypeScript, generating .d.ts files and performing type checks based on the user's tsconfig.json. It uses the TypeScript compiler API to ensure strict type checks that +esbuild alone can't provide. -### Integration +During the build, TypeScript is compiled to JavaScript while .d.ts files are created simultaneously. The plugin runs tsc in a subprocess to handle type checking +independently from esbuildโ€™s fast bundling. This ensures type safety without sacrificing performance. It respects the user's configuration, ensuring compatibility with various project setups. -The easy way to integrate this plugin in esbuild. +## ๐Ÿ”ง Usage -
Show instructions +```typescript +typescriptPlugin(options); +``` + +This function needs to be called inside the esbuild configuration in order to use this plugin. It will provide the plugin inside the build process of esbuild. + +
+Show an example of the integration ````typescript -await esbuild.build({ +esbuild.build({ + // some configuration... plugins: [ - typescriptPlugin(...) + typescriptPlugin(); + // more plugins here... ] }) ```` -[See here for more about the esbuild plugin integration.](https://esbuild.github.io/plugins/#using-plugins) +
+ +
+Show an example of the configuration + +````typescript +typescriptPlugin({ + // configure here +}); +````
+### Properties + +#### ``overridePathToTsconfig`` + +> Default: ``undefined`` (esbuild's tsconfig file) + +A ``string`` that determines the path to the tsconfig. + +
+Show an example + +````typescript +typescriptPlugin({ + overridePathToTsconfig: "libs/my-lib/tsconfig.json" // any path allowed +}); +```` + +
+ +### Returns + +Type: ``Plugin`` + +An instance of this plugin, that will be used by esbuild automatically. + ## License -The MIT License (MIT) - Please have a look at the LICENSE file for more details. +The MIT License (MIT) - Please have a look at the [License](https://github.com/simonkovtyk/esbuild-plugin-typescript/blob/main/LICENSE) file for more details. ## Contributing -Feel free to contribute to this project.\ -You can fork this project and create a new pull request for contributing. +Want to contribute to an open-source project on GitHub but unsure where to start? Check out this comprehensive step-by-step guide on how to contribute effectively! + +From forking the repository to creating pull requests, this guide walks you through every stage of the process, helping you make a successful contribution to this GitHub project. Start collaborating, +learn new skills, and make an impact on this project! -[Get to the repository at GitHub.](https://github.com/simonkovtyk/esbuild-plugin-typescript) +[See here](https://github.com/simonkovtyk/esbuild-plugin-typescript/blob/main/docs/guides/HOW_TO_CONTRIBUTE.md) for the contribute guide at GitHub.
diff --git a/docs/esbuild-favicon.svg b/docs/esbuild-favicon.svg new file mode 100644 index 0000000..234900f --- /dev/null +++ b/docs/esbuild-favicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/guides/HOW_TO_CONTRIBUTE.md b/docs/guides/HOW_TO_CONTRIBUTE.md new file mode 100644 index 0000000..455324c --- /dev/null +++ b/docs/guides/HOW_TO_CONTRIBUTE.md @@ -0,0 +1,150 @@ +# โš™๏ธ How to contribute + +How to Contribute to a GitHub Repository: A Step-by-Step Guide +Contributing to open-source projects on GitHub is a great way to collaborate with others, learn new skills, and improve software. Here's a step-by-step guide on how to contribute to this GitHub +repository. + +## 1. Fork the Repository + +Before making any changes, you'll need to fork the repository to your own GitHub account. + +1. Go to the [repository page](https://github.com/simonkovtyk/esbuild-plugin-typescript/). +2. Click on the "Fork" button in the top-right corner. +3. GitHub will create a copy of the repository in your account. + +## 2. Clone Your Fork Locally + +Next, you need to clone your forked repository to your local machine. + +Open a terminal on your computer. + +Use the following command to clone the repository: + +````shell +git clone https://github.com/YOUR-USERNAME/esbuild-plugin-typescript.git +```` + +Replace YOUR-USERNAME with your GitHub username. + +Navigate into the project directory: + +````shell +cd esbuild-plugin-typescript +```` + +## 3. Set Up the Upstream Remote + +To ensure you can pull in updates from the original repository, add an "upstream" remote. + +In the terminal, run: + +````shell +git remote add upstream https://github.com/simonkovtyk/esbuild-plugin-typescript.git +```` + +Confirm the upstream remote has been added: + +````shell +git remote -v +```` + +## 4. Create a New Branch + +To keep your changes organized and separate from the main codebase, create a new branch. + +Make sure you're in the main branch: + +````shell +git checkout main +```` + +Create and switch to a new branch: + +````shell +git checkout -b branch-name +```` + +Replace branch-name with a descriptive name for your branch (e.g., fix-bug, add-feature). + +## 5. Make Your Changes + +Now you're ready to make changes to the codebase. Open the project in your favorite code editor, modify the code, and save your changes. + +## 6. Commit Your Changes + +After making your changes, commit them to your branch. + +Check which files have changed: + +````shell +git status +```` + +Stage your changes: + +````shell +git add . +```` + +Commit your changes with a descriptive message: + +````shell +git commit -m "Brief description of the changes" +```` + +## 7. Push Your Branch to GitHub + +Push your changes to your fork on GitHub. + +````shell +git push origin branch-name +```` + +## 8. Open a Pull Request + +Now that your changes are pushed to your fork, it's time to open a pull request (PR) to the original repository. + +1. Go to the [original repository](https://github.com/simonkovtyk/esbuild-plugin-typescript/) on GitHub. +2. Click the "Compare & pull request" button. +3. Review your changes and ensure they are correct. +4. Add a descriptive title and description for your PR. +5. Click "Create pull request." + +## 9. Respond to Review Feedback + +After opening your pull request, a code style check will run automatically and the maintainers of the repository might review your code and suggest changes. + +If changes are requested, update your branch locally, commit the new changes, and push them to your fork. +The PR will automatically update with your latest changes. + +## 10. Keep Your Fork Up-to-Date + +To ensure your fork remains up-to-date with the original repository, regularly sync it with the upstream repository. + +Fetch the latest updates from upstream: + +````shell +git fetch upstream +```` + +Merge the upstream changes into your local main branch: + +````shell +git checkout main +```` + +````shell +git merge upstream/main +```` + +Push the updated main branch to your fork: + +````shell +git push origin main +```` + +## 11. Celebrate Your Contribution! + +Once your pull request is merged, you've officially contributed to an open-source project! + +**๐Ÿš€ Congratulations!** diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..0458e13 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,25 @@ +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; +import stylistic from "@stylistic/eslint-plugin"; + +export default tseslint.config( + { + ignores: [ + ".github", + ".idea", + "dist", + "docs", + "node_modules" + ] + }, + eslint.configs.recommended, + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + stylistic.configs.customize({ + indent: 2, + quotes: "double", + semi: true, + commaDangle: "never", + jsx: false + }) +); diff --git a/package.json b/package.json index 265e138..7dd7cc2 100644 --- a/package.json +++ b/package.json @@ -33,11 +33,9 @@ "type": "git", "url": "git+https://github.com/simonkovtyk/esbuild-plugin-typescript.git" }, + "types": "./public-api.d.ts", "exports": { - ".": { - "default": "./public-api.js", - "types": "./public-api.d.ts" - } + "default": "./public-api.js" }, "author": { "name": "Simon Kovtyk", @@ -56,6 +54,15 @@ }, "devDependencies": { "@types/node": "^22.5.4", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "eslint": "^9.10.0", + "typescript-eslint": "^8.6.0", + "@stylistic/eslint-plugin": "^2.8.0", + "@eslint/js": "^9.10.0", + "@types/eslint__js": "^8.42.3", + "husky": "^9.1.6" + }, + "scripts": { + "lint:husky": "husky" } } diff --git a/src/core/constants/messages.constant.ts b/src/core/constants/messages.constant.ts index 92d205f..0a5f153 100644 --- a/src/core/constants/messages.constant.ts +++ b/src/core/constants/messages.constant.ts @@ -1,7 +1,7 @@ enum ErrorMessages { - TSCONFIG_NOT_FOUND = "The tsconfig file was not found. Please make sure it is inside your project root." + TSCONFIG_NOT_FOUND = "The tsconfig file was not found. Please make sure it is inside your project root." } export { - ErrorMessages -} + ErrorMessages +}; diff --git a/src/core/plugin.ts b/src/core/plugin.ts index 127e37b..396e462 100644 --- a/src/core/plugin.ts +++ b/src/core/plugin.ts @@ -1,19 +1,20 @@ import { Plugin, PluginBuild } from "esbuild"; import { handlerProcedure } from "./procedures/handler.procedure"; -import { Options } from "./types/options.type"; +import { HandlerOptions, Options } from "./types/options.type"; -const typescriptPlugin = (options: Options): Plugin => ({ - name: "esbuild-plugin-typescript", - setup: (build: PluginBuild) => { - const handlerUnwrapped = handlerProcedure({ - ...options, - tsconfigPath: build.initialOptions.tsconfig - }); +const typescriptPlugin = (options?: Options | undefined): Plugin => ({ + name: "esbuild-plugin-typescript", + setup: (build: PluginBuild) => { + const handlerOptions: HandlerOptions = { + tsconfigPath: options?.overridePathToTsconfig ?? build.initialOptions.tsconfig + }; - build.onStart(handlerUnwrapped); - } + const handlerUnwrapped = handlerProcedure(handlerOptions); + + build.onStart(handlerUnwrapped); + } }); export { - typescriptPlugin -} + typescriptPlugin +}; diff --git a/src/core/procedures/handler.procedure.ts b/src/core/procedures/handler.procedure.ts index d0904b0..ef152c0 100644 --- a/src/core/procedures/handler.procedure.ts +++ b/src/core/procedures/handler.procedure.ts @@ -6,47 +6,47 @@ import { HandlerOptions } from "../types/options.type"; import { mapDiagnosticsToPartialMessages } from "../utils/error.util"; const handlerProcedure = (options: HandlerOptions) => { - return async (): Promise => { - const parsedTsconfigPath = options.tsconfigPath === undefined ? undefined : path.parse(options.tsconfigPath); + return async (): Promise => { + const parsedTsconfigPath = options.tsconfigPath === undefined ? undefined : path.parse(options.tsconfigPath); - const configFile = ts.findConfigFile( - parsedTsconfigPath?.dir ?? ".", - ts.sys.fileExists, - parsedTsconfigPath?.base - ); + const configFile = ts.findConfigFile( + parsedTsconfigPath?.dir ?? ".", + ts.sys.fileExists, + parsedTsconfigPath?.base + ); - if (configFile === undefined) - return { - errors: [ { - text: ErrorMessages.TSCONFIG_NOT_FOUND - } ] - }; + if (configFile === undefined) + return { + errors: [{ + text: ErrorMessages.TSCONFIG_NOT_FOUND + }] + }; - const config = ts.readConfigFile(configFile, ts.sys.readFile); - const parsedConfig = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configFile)); + const config = ts.readConfigFile(configFile, ts.sys.readFile); + const parsedConfig = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configFile)); - const host = ts.createCompilerHost(parsedConfig.options, true); - const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options, host); + const host = ts.createCompilerHost(parsedConfig.options, true); + const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options, host); - program.emit(); + program.emit(); - const redundantDiagnostics = ts.getPreEmitDiagnostics(program); - const sourceDiagnostics = ts.sortAndDeduplicateDiagnostics(redundantDiagnostics); - const configDiagnostics = parsedConfig.errors; + const redundantDiagnostics = ts.getPreEmitDiagnostics(program); + const sourceDiagnostics = ts.sortAndDeduplicateDiagnostics(redundantDiagnostics); + const configDiagnostics = parsedConfig.errors; - if (sourceDiagnostics.length === 0 && configDiagnostics.length === 0) - return null; + if (sourceDiagnostics.length === 0 && configDiagnostics.length === 0) + return null; - const partialSourceMessages = mapDiagnosticsToPartialMessages(host, Array.from(sourceDiagnostics)); - const partialConfigMessages = mapDiagnosticsToPartialMessages(host, configDiagnostics); + const partialSourceMessages = mapDiagnosticsToPartialMessages(host, Array.from(sourceDiagnostics)); + const partialConfigMessages = mapDiagnosticsToPartialMessages(host, configDiagnostics); - return { - errors: partialSourceMessages, - warnings: partialConfigMessages - }; - } -} + return { + errors: partialSourceMessages, + warnings: partialConfigMessages + }; + }; +}; export { - handlerProcedure -} + handlerProcedure +}; diff --git a/src/core/types/options.type.ts b/src/core/types/options.type.ts index aab2035..8bcc3cf 100644 --- a/src/core/types/options.type.ts +++ b/src/core/types/options.type.ts @@ -1,15 +1,15 @@ -type PathOverrides = { - overrideConfigPath: string | undefined +interface PathOverrides { + overridePathToTsconfig?: string | undefined; } -type HandlerOptions = { - tsconfigPath?: string | undefined -} & PathOverrides +interface HandlerOptions extends PathOverrides { + tsconfigPath?: string | undefined; +} type Options = PathOverrides; export type { - PathOverrides, - HandlerOptions, - Options -} + PathOverrides, + HandlerOptions, + Options +}; diff --git a/src/core/utils/error.util.ts b/src/core/utils/error.util.ts index bfd6fa1..b213972 100644 --- a/src/core/utils/error.util.ts +++ b/src/core/utils/error.util.ts @@ -3,16 +3,16 @@ import os from "node:os"; import ts from "typescript"; const mapDiagnosticsToPartialMessages = (host: ts.CompilerHost, diagnostics: ts.Diagnostic[]) => diagnostics.map((diagnostic: ts.Diagnostic): PartialMessage => { - if (diagnostic.file === undefined || diagnostic.start === undefined) - return { - text: ts.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL, 2) - }; + if (diagnostic.file === undefined || diagnostic.start === undefined) + return { + text: ts.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL, 2) + }; - return { - text: ts.formatDiagnostic(diagnostic, host) - } + return { + text: ts.formatDiagnostic(diagnostic, host) + }; }); export { - mapDiagnosticsToPartialMessages -} + mapDiagnosticsToPartialMessages +}; From 611c5c4942c8460ec6247ab833418908e9213a9b Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 19 Sep 2024 21:33:16 +0200 Subject: [PATCH 2/4] chore: upgraded version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7dd7cc2..c89c209 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "esbuild tsc" ], "license": "MIT", - "version": "1.0.0", + "version": "2.0.0-next.0", "bugs": "https://github.com/simonkovtyk/esbuild-plugin-typescript/issues", "homepage": "https://github.com/simonkovtyk/esbuild-plugin-typescript", "repository": { From 531f79c233ee5ccf561b7bee004e32472b783b03 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 19 Sep 2024 21:35:37 +0200 Subject: [PATCH 3/4] docs: added image path --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c11422..6c7b3ec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +

TypeScript Plugin

From 8d549fc2620eea3c335da1ab7019a0029cee407b Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 19 Sep 2024 21:37:48 +0200 Subject: [PATCH 4/4] ci: changed deploy pipeline branch --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e417e24..7feaadc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,7 +2,7 @@ name: Deploy on: push: branches: - - release + - main jobs: deploy: