Skip to content

Commit

Permalink
chore: template setup
Browse files Browse the repository at this point in the history
configured with:
 - solid-js
 - tsup
 - bun
 - nvm
 - typescript
 - vitest
 - eslint
 - prettier
  • Loading branch information
thedanchez committed Oct 12, 2024
0 parents commit 091625c
Show file tree
Hide file tree
Showing 20 changed files with 383 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"parser": "@typescript-eslint/parser",
"plugins": ["simple-import-sort", "solid"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:solid/typescript"
],
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true
},
"parserOptions": {
"sourceType": "module"
},
"rules": {
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_" }],
"no-unused-vars": "off",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error"
},
"ignorePatterns": ["dist", "node_modules"]
}
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
thedanchez
29 changes: 29 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
quality-checks:
name: Quality Checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install Dependencies
run: bun install --frozen-lockfile
- name: Lint Check
run: bun run lint
- name: Format Check
run: bun run format
- name: Test Coverage Check
run: bun run test
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage
dist
node_modules

.DS_Store
/*.tgz
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.17.0
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
coverage
dist
node_modules
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"printWidth": 120
}
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": "always"
},
"editor.formatOnSave": true,
"editor.rulers": [120],
"files.autoSave": "onFocusChange",
"files.insertFinalNewline": true
}
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Template: SolidJS Library

Template for [SolidJS](https://www.solidjs.com/) library package. Bundling of the library is managed by [tsup](https://tsup.egoist.dev/).

Other things configured include:

- Bun (for dependency management and running scripts)
- TypeScript
- ESLint / Prettier
- Solid Testing Library + Vitest (for testing)
- GitHub Actions (for all CI/CD)

## Getting Started

Some pre-requisites before install dependencies:

- Install Node Version Manager (NVM)
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
```
- Install Bun
```bash
curl -fsSL https://bun.sh/install | bash
```

### Installing Dependencies

```bash
nvm use
bun install
```

### Local Development Build

```bash
bun start
```

### Linting & Formatting

```bash
bun run lint # checks source for lint violations
bun run format # checks source for format violations
bun run lint:fix # fixes lint violations
bun run format:fix # fixes format violations
```

### Unit Testing

> We use [Solid Testing Library](https://github.com/solidjs/solid-testing-library) for integration style unit tests

```bash
bun run test
bun run test:cov # with test coverage
```

### Contributing

The only requirements when contributing are:

- You keep a clean git history in your branch
- rebasing `main` instead of making merge commits.
- Using proper commit message formats that adhere to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
- Additionally, squashing (via rebase) commits that are not [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
- CI checks pass before merging into `main`
Binary file added bun.lockb
Binary file not shown.
16 changes: 16 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/playground/assets/favicon.ico" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/playground/index.tsx" type="module"></script>
</body>
</html>
48 changes: 48 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "template-solidjs-library",
"version": "0.0.0",
"description": "Template for SolidJS library using tsup for bundling. Configured with Bun, NVM, TypeScript, ESLint, Prettier, Vitest, and GHA",
"type": "module",
"author": "Daniel Sanchez <[email protected]>",
"license": "MIT",
"homepage": "https://github.com/thedanchez/template-solidjs-library#readme",
"bugs": {
"url": "https://github.com/thedanchez/template-solidjs-library/issues"
},
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"dev": "vite",
"format": "prettier . --check",
"format:fix": "prettier . --write",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"serve": "vite preview",
"start": "vite",
"test": "vitest run",
"test:cov": "vitest run --coverage",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@solidjs/testing-library": "^0.8.10",
"@testing-library/jest-dom": "^6.5.0",
"@types/bun": "^1.1.10",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"@vitest/coverage-istanbul": "^2.1.1",
"eslint": "^8.57.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-solid": "^0.14.3",
"jsdom": "^25.0.1",
"prettier": "^3.3.3",
"tsup": "^8.3.0",
"tsup-preset-solid": "^2.2.0",
"typescript": "^5.6.2",
"vite": "^5.4.8",
"vite-plugin-solid": "^2.10.2",
"vitest": "^2.1.1"
},
"peerDependencies": {
"solid-js": ">=1.8.0"
}
}
19 changes: 19 additions & 0 deletions playground/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createSignal } from "solid-js";

export const App = () => {
const [count, setCount] = createSignal(0);

return (
<div>
<div>Playground App</div>
<div>Count: {count()}</div>
<button
onClick={() => {
setCount((prev) => prev + 1);
}}
>
Increment Count
</button>
</div>
);
};
36 changes: 36 additions & 0 deletions playground/__tests__/todo-list.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { fireEvent, render } from "@solidjs/testing-library";
import { describe, expect, test } from "vitest";

import { TodoList } from "../App";

describe("<TodoList />", () => {
test("it will render an text input and a button", () => {
const { getByPlaceholderText, getByText } = render(() => <TodoList />);
expect(getByPlaceholderText("new todo here")).toBeInTheDocument();
expect(getByText("Add Todo")).toBeInTheDocument();
});

test("it will add a new todo", async () => {
const { getByPlaceholderText, getByText } = render(() => <TodoList />);
const input = getByPlaceholderText("new todo here") as HTMLInputElement;
const button = getByText("Add Todo");
input.value = "test new todo";
fireEvent.click(button as HTMLInputElement);
expect(input.value).toBe("");
expect(getByText(/test new todo/)).toBeInTheDocument();
});

test("it will mark a todo as completed", async () => {
const { getByPlaceholderText, findByRole, getByText } = render(() => <TodoList />);
const input = getByPlaceholderText("new todo here") as HTMLInputElement;
const button = getByText("Add Todo") as HTMLButtonElement;
input.value = "mark new todo as completed";
fireEvent.click(button);
const completed = (await findByRole("checkbox")) as HTMLInputElement;
expect(completed?.checked).toBe(false);
fireEvent.click(completed);
expect(completed?.checked).toBe(true);
const text = getByText("mark new todo as completed") as HTMLSpanElement;
expect(text).toHaveStyle({ "text-decoration": "line-through" });
});
});
13 changes: 13 additions & 0 deletions playground/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { render } from "solid-js/web";

import { App } from "./App";

const root = document.getElementById("root");

if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
throw new Error(
"Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?",
);
}

render(() => <App />, root!);
1 change: 1 addition & 0 deletions setupTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "@testing-library/jest-dom/vitest";
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Main library export site
// Use playground app (via Vite) to test and document the library
34 changes: 34 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"compilerOptions": {
/* Base Options: */
"outDir": "dist",
"esModuleInterop": true,
"skipLibCheck": true,
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"allowJs": true,
"resolveJsonModule": true,
"moduleResolution": "Bundler",
"moduleDetection": "force",
"isolatedModules": true,
"verbatimModuleSyntax": true,

/* Strictness */
"strict": true,
"allowUnreachableCode": false,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,

/* JSX */
"jsx": "preserve",
"jsxImportSource": "solid-js",

/* Types */
"types": ["vite/client", "bun-types", "@testing-library/jest-dom"]
},
"exclude": ["node_modules", "coverage", "dist"]
}
34 changes: 34 additions & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig } from "tsup";
import * as preset from "tsup-preset-solid";

const generateSolidPresetOptions = (watching: boolean): preset.PresetOptions => ({
entries: [
{
// entries with '.tsx' extension will have `solid` export condition generated
entry: "src/index.tsx",
dev_entry: false,
server_entry: true,
},
],
drop_console: !watching, // remove all `console.*` calls and `debugger` statements in prod builds
cjs: false,
});

export default defineConfig((config) => {
const watching = !!config.watch;
const solidPresetOptions = generateSolidPresetOptions(watching);
const parsedOptions = preset.parsePresetOptions(solidPresetOptions, watching);

if (!watching) {
const packageFields = preset.generatePackageExports(parsedOptions);
// console.log(`\npackage.json: \n${JSON.stringify(packageFields, null, 2)}\n\n`);
/* will update ./package.json with the correct export fields */
preset.writePackageJson(packageFields);
}

const tsupOptions = preset
.generateTsupOptions(parsedOptions)
.map((tsupOption) => ({ name: "solid-js", ...tsupOption }));

return tsupOptions;
});
Loading

0 comments on commit 091625c

Please sign in to comment.