Skip to content

Commit

Permalink
Compile TypeScript (#17)
Browse files Browse the repository at this point in the history
* Add build process

* 0.1.5-0

* Update tsup config

* 0.1.6-0

* Fix issues with template resolution

* 0.1.7-0
  • Loading branch information
Stephen Hanson authored Nov 4, 2023
1 parent 6f539ce commit 0af3974
Show file tree
Hide file tree
Showing 21 changed files with 350 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ npm-debug.log
.idea/*
.vscode/*
.DS_Store
/build
/dist
1 change: 1 addition & 0 deletions .yarnrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry "https://registry.npmjs.org/"
26 changes: 26 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,32 @@ Install dependencies:
yarn install
```

Run the dev server during development:

```bash
yarn dev
```

## Test changes locally

In thoughtbelt directory:

```bash
yarn link
```

In some other directory:

```bash
yarn add thoughtbelt
yarn link thoughtbelt

# or whatever command
yarn thoughtbelt NewApp
```

## Creating a pull request

Make sure the tests pass:

```bash
Expand Down
39 changes: 27 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
{
"name": "thoughtbelt",
"version": "0.1.4",
"description": "Monorepo for project bootstrapping CLIs",
"main": "bin/belt.js",
"author": "thoughtbot, Inc.",
"license": "MIT",
"version": "0.1.7-0",
"description": "React Native project starter and generator CLI",
"type": "module",
"exports": "./dist/index.js",
"bin": {
"thoughtbelt": "./dist/index.js",
"belt": "./dist/index.js"
},
"files": [
"dist",
"templates",
"README.md",
"LICENSE",
"CONTRIBUTING.md",
"package.json"
],
"scripts": {
"belt": "bin/belt.js",
"build": "tsup",
"dev": "tsup --watch",
"clean": "rm -rf dist node_modules",
"start": "node dist/index.js",
"lint": "run-p lint:eslint lint:types lint:prettier",
"lint:eslint": "eslint --max-warnings=0 --ext js,jsx,ts,tsx .",
"lint:prettier": "prettier --check '**/*' --ignore-unknown",
"lint:types": "tsc",
"fix:prettier": "prettier --write '**/*' --ignore-unknown",
"test": "vitest",
"test:run": "vitest run",
"test:all": "yarn lint && yarn test:run"
"test:all": "yarn lint && yarn test:run",
"pub:beta": "yarn build && npm publish --tag beta",
"pub:release": "yarn build && npm publish"
},
"bin": {
"thoughtbelt": "./bin/belt.js"
},
"author": "thoughtbot, Inc.",
"license": "MIT",
"dependencies": {
"@inquirer/prompts": "^3.2.0",
"@thoughtbot/eslint-config": "^1.0.2",
Expand All @@ -38,6 +52,7 @@
"@types/react": "^18.2.6",
"memfs": "^4.2.0",
"npm-run-all": "^4.1.5",
"tsup": "^7.2.0",
"typescript": "^5.0.4",
"vitest": "^0.34.1"
},
Expand All @@ -48,10 +63,10 @@
"@thoughtbot/eslint-config/typescript"
],
"ignorePatterns": [
"src/commands/templates",
"templates",
"__mocks__/**/*.js",
"bin/belt.js",
"/build",
"/dist",
"vitest.setup.js"
],
"rules": {
Expand Down
2 changes: 0 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,3 @@ export default function runCli() {
printWelcome();
program.parse();
}

runCli();
6 changes: 2 additions & 4 deletions src/commands/eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import chalk from 'chalk';
import * as eta from 'eta';
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath, URL } from 'url';
import { PACKAGE_ROOT } from '../constants';
import addDependency from '../util/addDependency';
import getProjectDir from '../util/getProjectDir';
import isEslintConfigured from '../util/isEslintConfigured';
import isPackageInstalled from '../util/isPackageInstalled';
import print from '../util/print';
import writeFile from '../util/writeFile';

const dirname = fileURLToPath(new URL('.', import.meta.url));

export default async function addEslint() {
const projectDir = await getProjectDir();

Expand All @@ -21,7 +19,7 @@ export default async function addEslint() {
const hasTypeScript = await isPackageInstalled('typescript');

const eslintConfigTemplate = await fs.readFile(
path.join(dirname, 'templates', 'eslintrc.js.eta'),
path.join(PACKAGE_ROOT, 'templates/eslintrc.js.eta'),
);

const fileContents = eta.render(eslintConfigTemplate.toString(), {
Expand Down
14 changes: 6 additions & 8 deletions src/commands/prettier.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { log } from 'console';
import path from 'path';
import { fileURLToPath, URL } from 'url';
import fs from 'fs-extra';
import chalk from 'chalk';
import { log } from 'console';
import * as eta from 'eta';
import isPrettierConfigured from '../util/isPrettierConfigured';
import fs from 'fs-extra';
import path from 'path';
import { PACKAGE_ROOT } from '../constants';
import addDependency from '../util/addDependency';
import getProjectDir from '../util/getProjectDir';
import isPrettierConfigured from '../util/isPrettierConfigured';
import writeFile from '../util/writeFile';

const dirname = fileURLToPath(new URL('.', import.meta.url));

export default async function runPrettier() {
const projectDir = await getProjectDir();
const eslintJsFile = path.join(projectDir, '.eslintrc.js');
Expand All @@ -30,7 +28,7 @@ export default async function runPrettier() {
log('.prettierignore config file already exists');
} else {
const prettierIgnoreTemplate = await fs.readFile(
path.join(dirname, 'templates', 'prettierignore.eta'),
path.join(PACKAGE_ROOT, 'templates/prettierignore.eta'),
);
const fileContents = eta.render(prettierIgnoreTemplate.toString(), {});

Expand Down
6 changes: 2 additions & 4 deletions src/commands/scaffold.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import { URL, fileURLToPath } from 'url';
import { PACKAGE_ROOT } from '../constants';
import print from '../util/print';

const dirname = fileURLToPath(new URL('.', import.meta.url));

export default async function createScaffold() {
print(chalk.bold('👖 Creating directory structure'));
print(`
Expand All @@ -15,6 +13,6 @@ export default async function createScaffold() {
hooks/
test/
`);
fs.copySync(path.join(dirname, 'templates', 'scaffold', 'src'), './src');
fs.copySync(path.join(PACKAGE_ROOT, 'templates/scaffold/src'), './src');
print('✅ Created directories');
}
13 changes: 4 additions & 9 deletions src/commands/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@ import chalk from 'chalk';
import * as eta from 'eta';
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath, URL } from 'url';
import { PACKAGE_ROOT } from '../constants';
import addDependency from '../util/addDependency';
import getProjectDir from '../util/getProjectDir';
import getProjectType from '../util/getProjectType';
import print from '../util/print';
import writeFile from '../util/writeFile';

// for manual testing, change this to another name so doesn't conflict
// with project's tsconfig.json
const tsConfig = 'tsconfig.json';
const dirname = fileURLToPath(new URL('.', import.meta.url));

export default async function addTypescript() {
const projectDir = await getProjectDir();

if (await fs.exists(path.join(projectDir, tsConfig))) {
if (await fs.exists(path.join(projectDir, 'tsconfig.json'))) {
print(
chalk.yellow(
'tsconfig.json already exists, exiting.\nIf you would like to perform a fresh TypeScript install, delete this file and rerun the script.\n',
Expand All @@ -30,13 +25,13 @@ export default async function addTypescript() {

const projectType = await getProjectType();
const template = await fs.readFile(
path.join(dirname, 'templates', 'tsconfig.json.eta'),
path.join(PACKAGE_ROOT, 'templates/tsconfig.json.eta'),
);
const fileContents = eta.render(template.toString(), {
expo: projectType === 'expo-bare' || projectType === 'expo-managed',
});

await writeFile(path.join(projectDir, tsConfig), fileContents, {
await writeFile(path.join(projectDir, 'tsconfig.json'), fileContents, {
format: true,
});

Expand Down
14 changes: 14 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import path from 'path';
import { fileURLToPath } from 'url';

// TSUP builds files without hierarchy to dist/, so the path is ultimately
// in relation to the dist/ directory. NPM package structure is:
// <root>
// dist/
// index.js // file executed here
// templates/
const filename = fileURLToPath(import.meta.url);
const distPath = path.dirname(filename);
// eslint-disable-next-line import/prefer-default-export
export const PACKAGE_ROOT = path.join(distPath, '../');
console.log('PACKAGE_ROOT', filename, distPath, PACKAGE_ROOT);
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
import runCli from './cli';

runCli();
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
"experimentalSpecifierResolution": "node"
},
"include": ["./**/*.ts"],
"exclude": ["./src/commands/templates/**/*"]
"exclude": ["templates/**/*"]
}
10 changes: 10 additions & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';

export default defineConfig({
clean: true,
entry: ['src/index.ts'],
format: ['esm'],
minify: false,
target: 'esnext',
outDir: 'dist',
});
Loading

0 comments on commit 0af3974

Please sign in to comment.