From dd83f7d1bb0b4f735e704b0b041477c21b25b111 Mon Sep 17 00:00:00 2001 From: Yu Lia <1938793150@qq.com> Date: Sun, 1 Mar 2026 11:17:08 +0800 Subject: [PATCH 1/2] feat: add create-lib package --- packages/create-lib/README.md | 9 ++ packages/create-lib/bin/index.js | 2 + packages/create-lib/package.json | 43 +++++++++ packages/create-lib/src/constants.ts | 16 ++++ packages/create-lib/src/helper.ts | 41 ++++++++ packages/create-lib/src/index.ts | 93 +++++++++++++++++++ .../template/base/.vscode/extensions.json | 3 + .../template/base/.vscode/settings.json | 50 ++++++++++ .../create-lib/template/base/_editorconfig | 6 ++ .../create-lib/template/base/_gitattributes | 1 + packages/create-lib/template/base/_gitignore | 5 + .../create-lib/template/base/package.json | 27 ++++++ .../template/eslint/eslint.config.mjs | 8 ++ .../create-lib/template/eslint/package.json | 11 +++ .../template/git-hooks/package.json | 17 ++++ .../git-hooks/scripts/verify-commit.js | 41 ++++++++ .../.github/workflows/release.yml | 36 +++++++ .../.github/workflows/unit-test.yml | 63 +++++++++++++ .../template/monorepo/eslint.config.mjs | 9 ++ .../template/monorepo/packages/foo/README.md | 3 + .../monorepo/packages/foo/package.json | 21 +++++ .../monorepo/packages/foo/src/index.ts | 1 + .../monorepo/packages/foo/tests/index.test.ts | 6 ++ .../template/monorepo/pnpm-workspace.yaml | 5 + .../template/monorepo/tsconfig.json | 21 +++++ .../template/monorepo/tsdown.config.ts | 9 ++ .../template/single-repo/package.json | 13 +++ .../template/single-repo/src/index.ts | 1 + .../template/single-repo/tests/index.test.ts | 6 ++ .../template/single-repo/tsconfig.json | 20 ++++ .../template/single-repo/tsdown.config.ts | 8 ++ packages/create-lib/tsdown.config.ts | 5 + 32 files changed, 600 insertions(+) create mode 100644 packages/create-lib/README.md create mode 100644 packages/create-lib/bin/index.js create mode 100644 packages/create-lib/package.json create mode 100644 packages/create-lib/src/constants.ts create mode 100644 packages/create-lib/src/helper.ts create mode 100644 packages/create-lib/src/index.ts create mode 100644 packages/create-lib/template/base/.vscode/extensions.json create mode 100644 packages/create-lib/template/base/.vscode/settings.json create mode 100644 packages/create-lib/template/base/_editorconfig create mode 100644 packages/create-lib/template/base/_gitattributes create mode 100644 packages/create-lib/template/base/_gitignore create mode 100644 packages/create-lib/template/base/package.json create mode 100644 packages/create-lib/template/eslint/eslint.config.mjs create mode 100644 packages/create-lib/template/eslint/package.json create mode 100644 packages/create-lib/template/git-hooks/package.json create mode 100644 packages/create-lib/template/git-hooks/scripts/verify-commit.js create mode 100644 packages/create-lib/template/github-workflows/.github/workflows/release.yml create mode 100644 packages/create-lib/template/github-workflows/.github/workflows/unit-test.yml create mode 100644 packages/create-lib/template/monorepo/eslint.config.mjs create mode 100644 packages/create-lib/template/monorepo/packages/foo/README.md create mode 100644 packages/create-lib/template/monorepo/packages/foo/package.json create mode 100644 packages/create-lib/template/monorepo/packages/foo/src/index.ts create mode 100644 packages/create-lib/template/monorepo/packages/foo/tests/index.test.ts create mode 100644 packages/create-lib/template/monorepo/pnpm-workspace.yaml create mode 100644 packages/create-lib/template/monorepo/tsconfig.json create mode 100644 packages/create-lib/template/monorepo/tsdown.config.ts create mode 100644 packages/create-lib/template/single-repo/package.json create mode 100644 packages/create-lib/template/single-repo/src/index.ts create mode 100644 packages/create-lib/template/single-repo/tests/index.test.ts create mode 100644 packages/create-lib/template/single-repo/tsconfig.json create mode 100644 packages/create-lib/template/single-repo/tsdown.config.ts create mode 100644 packages/create-lib/tsdown.config.ts diff --git a/packages/create-lib/README.md b/packages/create-lib/README.md new file mode 100644 index 0000000..9b28a5d --- /dev/null +++ b/packages/create-lib/README.md @@ -0,0 +1,9 @@ +### Usage + +```bash +npx @doyuli/create-lib + +# or + +npm create @doyuli/lib +``` diff --git a/packages/create-lib/bin/index.js b/packages/create-lib/bin/index.js new file mode 100644 index 0000000..201d2ce --- /dev/null +++ b/packages/create-lib/bin/index.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +import '../dist/index.mjs' diff --git a/packages/create-lib/package.json b/packages/create-lib/package.json new file mode 100644 index 0000000..7e4fa5c --- /dev/null +++ b/packages/create-lib/package.json @@ -0,0 +1,43 @@ +{ + "name": "@doyuli/create-lib", + "type": "module", + "version": "0.2.1", + "description": "@doyuli/create-lib", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/doyuli/template-kits.git", + "directory": "packages/create-lib" + }, + "keywords": [ + "templates", + "create-lib" + ], + "sideEffects": false, + "main": "dist/index.js", + "bin": { + "create-lib": "bin/index.js" + }, + "files": [ + "bin", + "dist", + "template", + "template/**/settings.json" + ], + "publishConfig": { + "access": "public" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "scripts": { + "dev": "tsdown --watch", + "build": "tsdown", + "prepack": "pnpm run build" + }, + "dependencies": { + "@clack/prompts": "catalog:", + "@doyuli/kits-core": "workspace:^", + "picocolors": "catalog:" + } +} diff --git a/packages/create-lib/src/constants.ts b/packages/create-lib/src/constants.ts new file mode 100644 index 0000000..4dfa741 --- /dev/null +++ b/packages/create-lib/src/constants.ts @@ -0,0 +1,16 @@ +export const DEFAULT_BANNER = 'Template-Kits - 快速生成你的模板代码' + +export const FEATURE_OPTIONS = [ + { + value: 'monorepo', + label: 'Monorepo(pnpm workspace 多包管理)', + }, + { + value: 'simple-git-hooks', + label: 'Simple Git Hooks(Git Commit 检查)', + }, + { + value: 'github-workflows', + label: 'GitHub Workflows(CI/CD 自动化)', + }, +] as const diff --git a/packages/create-lib/src/helper.ts b/packages/create-lib/src/helper.ts new file mode 100644 index 0000000..34e648e --- /dev/null +++ b/packages/create-lib/src/helper.ts @@ -0,0 +1,41 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' +import { renderFile } from '@doyuli/kits-core' + +/** + * Convert devDependencies to catalog: references and generate pnpm-workspace.yaml + */ +export function renderMonorepoDeps(root: string) { + const pkgPath = path.join(root, 'package.json') + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) + const devDeps: Record = pkg.devDependencies ?? {} + + // Extract real versions for catalog, then replace with catalog: references + const sortedEntries = Object.entries(devDeps).sort(([a], [b]) => a.localeCompare(b)) + const catalogDeps = Object.fromEntries(sortedEntries.map(([k]) => [k, 'catalog:'])) + + pkg.devDependencies = catalogDeps + renderFile(root, 'package.json', `${JSON.stringify(pkg, null, 2)}\n`) + + // Generate pnpm-workspace.yaml + const catalogLines = sortedEntries + .map(([name, version]) => { + const key = name.includes('/') ? `'${name}'` : name + return ` ${key}: ${version}` + }) + .join('\n') + + const workspace = [ + 'shellEmulator: true', + 'trustPolicy: no-downgrade', + '', + 'packages:', + ' - packages/*', + '', + 'catalog:', + catalogLines, + '', + ].join('\n') + + renderFile(root, 'pnpm-workspace.yaml', workspace) +} diff --git a/packages/create-lib/src/index.ts b/packages/create-lib/src/index.ts new file mode 100644 index 0000000..309459a --- /dev/null +++ b/packages/create-lib/src/index.ts @@ -0,0 +1,93 @@ +import type { + PromptResult, +} from '@doyuli/kits-core' +import * as path from 'node:path' +import process from 'node:process' +import { fileURLToPath } from 'node:url' +import { parseArgs } from 'node:util' +import { intro, outro } from '@clack/prompts' +import { + getCommand, + getPackageManager, + renderTemplate, + setupFeatures, + setupProject, + setupPrompts, +} from '@doyuli/kits-core' +import pico from 'picocolors' +import { + DEFAULT_BANNER, + FEATURE_OPTIONS, +} from './constants' +import { renderMonorepoDeps } from './helper'; + +(async function () { + const cwd = process.cwd() + const { positionals } = parseArgs({ + strict: true, + allowPositionals: true, + }) + + intro(pico.magenta(DEFAULT_BANNER)) + + const inputTargetDir = positionals[0] + + const { result, targetDir } = await setupPrompts(inputTargetDir, [ + setupFeatures('features', { + options: [...FEATURE_OPTIONS], + }), + ]) + + const root = await setupProject(cwd, result, targetDir) + + renderTemplates(root, result) + + outro(getOutroMessage(root, cwd)) +})() + +function getOutroMessage(root: string, cwd: string) { + const manager = getPackageManager() + + let message = `项目初始化完成,可执行以下命令:\n\n` + if (root !== cwd) { + const cdProjectName = path.relative(cwd, root) + message += ` ${pico.bold(pico.green(`cd ${cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName}`))}\n` + } + message += ` ${pico.bold(pico.green(getCommand(manager, 'install')))}\n` + message += ` ${pico.bold(pico.green(getCommand(manager, 'dev')))}\n` + + return message +} + +function renderTemplates(root: string, result: PromptResult & { features: string[] }) { + const { features } = result + + const needsMonorepo = features.includes('monorepo') + const needsGitHooks = features.includes('simple-git-hooks') + const needsWorkflows = features.includes('github-workflows') + + const templateRoot = fileURLToPath(new URL('../template', import.meta.url)) + const render = (templateName: string) => { + const templateDir = path.resolve(templateRoot, templateName) + renderTemplate(templateDir, root) + } + + render('base') + render('eslint') + + if (needsGitHooks) { + render('git-hooks') + } + + if (needsWorkflows) { + render('github-workflows') + } + + if (needsMonorepo) { + render('monorepo') + renderMonorepoDeps(root) + } + else { + render('single-repo') + } +} diff --git a/packages/create-lib/template/base/.vscode/extensions.json b/packages/create-lib/template/base/.vscode/extensions.json new file mode 100644 index 0000000..f38b52f --- /dev/null +++ b/packages/create-lib/template/base/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["vitest.explorer", "dbaeumer.vscode-eslint"] +} diff --git a/packages/create-lib/template/base/.vscode/settings.json b/packages/create-lib/template/base/.vscode/settings.json new file mode 100644 index 0000000..b0d616e --- /dev/null +++ b/packages/create-lib/template/base/.vscode/settings.json @@ -0,0 +1,50 @@ +{ + // Disable the default formatter, use eslint instead + "prettier.enable": false, + "editor.formatOnSave": false, + + // Auto fix + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + + // Silent the stylistic rules in you IDE, but still auto fix them + "eslint.rules.customizations": [ + { "rule": "style/*", "severity": "off", "fixable": true }, + { "rule": "format/*", "severity": "off", "fixable": true }, + { "rule": "*-indent", "severity": "off", "fixable": true }, + { "rule": "*-spacing", "severity": "off", "fixable": true }, + { "rule": "*-spaces", "severity": "off", "fixable": true }, + { "rule": "*-order", "severity": "off", "fixable": true }, + { "rule": "*-dangle", "severity": "off", "fixable": true }, + { "rule": "*-newline", "severity": "off", "fixable": true }, + { "rule": "*quotes", "severity": "off", "fixable": true }, + { "rule": "*semi", "severity": "off", "fixable": true } + ], + + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "xml", + "gql", + "graphql", + "astro", + "svelte", + "css", + "less", + "scss", + "pcss", + "postcss" + ] +} \ No newline at end of file diff --git a/packages/create-lib/template/base/_editorconfig b/packages/create-lib/template/base/_editorconfig new file mode 100644 index 0000000..7095e7f --- /dev/null +++ b/packages/create-lib/template/base/_editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +indent_size = 2 +end_of_line = lf +insert_final_newline = true diff --git a/packages/create-lib/template/base/_gitattributes b/packages/create-lib/template/base/_gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/packages/create-lib/template/base/_gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/packages/create-lib/template/base/_gitignore b/packages/create-lib/template/base/_gitignore new file mode 100644 index 0000000..26632ac --- /dev/null +++ b/packages/create-lib/template/base/_gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +dist +*.log +.eslintcache diff --git a/packages/create-lib/template/base/package.json b/packages/create-lib/template/base/package.json new file mode 100644 index 0000000..fd7de50 --- /dev/null +++ b/packages/create-lib/template/base/package.json @@ -0,0 +1,27 @@ +{ + "type": "module", + "private": true, + "license": "MIT", + "packageManager": "pnpm@10.25.0", + "engines": { + "node": ">=20.18.0" + }, + "scripts": { + "dev": "tsdown --watch", + "build": "tsdown", + "test": "vitest", + "release": "bumpp -r", + "lint": "eslint --cache", + "lint:fix": "eslint --cache --fix", + "typecheck": "tsc --noEmit", + "prepublishOnly": "pnpm run build" + }, + "devDependencies": { + "@types/node": "^25.3.2", + "bumpp": "^10.4.1", + "tsdown": "^0.20.3", + "tsx": "^4.21.0", + "typescript": "^5.9.3", + "vitest": "^4.0.18" + } +} diff --git a/packages/create-lib/template/eslint/eslint.config.mjs b/packages/create-lib/template/eslint/eslint.config.mjs new file mode 100644 index 0000000..17742c3 --- /dev/null +++ b/packages/create-lib/template/eslint/eslint.config.mjs @@ -0,0 +1,8 @@ +// @ts-check +import antfu from '@antfu/eslint-config' + +export default antfu( + { + formatters: true, + }, +) diff --git a/packages/create-lib/template/eslint/package.json b/packages/create-lib/template/eslint/package.json new file mode 100644 index 0000000..b5e3351 --- /dev/null +++ b/packages/create-lib/template/eslint/package.json @@ -0,0 +1,11 @@ +{ + "scripts": { + "lint": "eslint --cache", + "lint:fix": "eslint --cache --fix" + }, + "devDependencies": { + "@antfu/eslint-config": "catalog:", + "eslint": "catalog:", + "eslint-plugin-format": "catalog:" + } +} diff --git a/packages/create-lib/template/git-hooks/package.json b/packages/create-lib/template/git-hooks/package.json new file mode 100644 index 0000000..e32f68b --- /dev/null +++ b/packages/create-lib/template/git-hooks/package.json @@ -0,0 +1,17 @@ +{ + "scripts": { + "postinstall": "simple-git-hooks" + }, + "devDependencies": { + "picocolors": "^1.1.1", + "lint-staged": "^16.1.6", + "simple-git-hooks": "^2.13.1" + }, + "simple-git-hooks": { + "pre-commit": "pnpm lint-staged", + "commit-msg": "node scripts/verify-commit.js" + }, + "lint-staged": { + "*": "eslint --fix" + } +} diff --git a/packages/create-lib/template/git-hooks/scripts/verify-commit.js b/packages/create-lib/template/git-hooks/scripts/verify-commit.js new file mode 100644 index 0000000..8e31f37 --- /dev/null +++ b/packages/create-lib/template/git-hooks/scripts/verify-commit.js @@ -0,0 +1,41 @@ +// @ts-check + +import { readFileSync } from 'node:fs' +import path from 'node:path' +import process from 'node:process' +import pico from 'picocolors' + +const msgPath = path.resolve('.git/COMMIT_EDITMSG') +const msg = readFileSync(msgPath, 'utf-8').trim() + +// eslint-disable-next-line regexp/no-unused-capturing-group +const COMMIT_RE = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?: .{1,50}/ + +if (!COMMIT_RE.test(msg)) { + console.log() + console.error( + ` ${pico.bgRed(pico.white(' ERROR '))} ${pico.red(`Invalid commit message format.`)}\n\n` + + ` ${pico.dim('Help us keep a meaningful git history by following')}\n\n` + + + ` ${pico.yellow('Standard Format:')}\n` + + ` ${pico.green('[optional scope]: ')}\n\n` + + + ` ${pico.cyan('Common Types:')}\n` + + ` ${pico.green(' feat')} ${pico.dim('A new feature')}\n` + + ` ${pico.green(' fix')} ${pico.dim('A bug fix')}\n` + + ` ${pico.green(' docs')} ${pico.dim('Documentation only changes')}\n` + + ` ${pico.green(' style')} ${pico.dim('Changes that do not affect the meaning of the code')}\n` + + ` ${pico.green(' refactor')} ${pico.dim('Code change that neither fixes a bug nor adds a feature')}\n` + + ` ${pico.green(' perf')} ${pico.dim('A code change that improves performance')}\n` + + ` ${pico.green(' test')} ${pico.dim('Adding missing tests or correcting existing tests')}\n` + + ` ${pico.green(' build')} ${pico.dim('Changes that affect the build system or external dependencies')}\n` + + ` ${pico.green(' ci')} ${pico.dim('Changes to CI configuration files and scripts')}\n` + + ` ${pico.green(' chore')} ${pico.dim('Other changes that don\'t modify src or test files')}\n` + + ` ${pico.green(' revert')} ${pico.dim('Reverts a previous commit')}\n\n` + + + ` ${pico.cyan('Correct Examples:')}\n` + + ` ${pico.white(' feat(ui): add secondary button style')}\n` + + ` ${pico.white(' fix(auth): resolve token expiration issue')}\n\n`, + ) + process.exit(1) +} diff --git a/packages/create-lib/template/github-workflows/.github/workflows/release.yml b/packages/create-lib/template/github-workflows/.github/workflows/release.yml new file mode 100644 index 0000000..f290800 --- /dev/null +++ b/packages/create-lib/template/github-workflows/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Release + +permissions: + contents: write + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Install pnpm + uses: pnpm/action-setup@v4.2.0 + + - name: Set node + uses: actions/setup-node@v6 + with: + node-version: lts/* + + - name: Generate GitHub Changelog + run: pnpx changelogithub + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build + run: pnpm run build + + - name: Publish to NPM + run: pnpm -r publish --access public --no-git-checks diff --git a/packages/create-lib/template/github-workflows/.github/workflows/unit-test.yml b/packages/create-lib/template/github-workflows/.github/workflows/unit-test.yml new file mode 100644 index 0000000..e103048 --- /dev/null +++ b/packages/create-lib/template/github-workflows/.github/workflows/unit-test.yml @@ -0,0 +1,63 @@ +name: Unit Test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4.2.0 + + - name: Set node LTS + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: pnpm + + - name: Install + run: pnpm install + + - name: Lint + run: pnpm run lint + + - name: Typecheck + run: pnpm run typecheck + + test: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + node: [20, 22, 24] + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4.2.0 + + - name: Set node ${{ matrix.node }} + uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + cache: pnpm + + - name: Install + run: pnpm install + + - name: Build + run: pnpm run build + + - name: Test + run: pnpm run test diff --git a/packages/create-lib/template/monorepo/eslint.config.mjs b/packages/create-lib/template/monorepo/eslint.config.mjs new file mode 100644 index 0000000..5ae5e1d --- /dev/null +++ b/packages/create-lib/template/monorepo/eslint.config.mjs @@ -0,0 +1,9 @@ +// @ts-check +import antfu from '@antfu/eslint-config' + +export default antfu( + { + formatters: true, + pnpm: true, + }, +) diff --git a/packages/create-lib/template/monorepo/packages/foo/README.md b/packages/create-lib/template/monorepo/packages/foo/README.md new file mode 100644 index 0000000..611f8b1 --- /dev/null +++ b/packages/create-lib/template/monorepo/packages/foo/README.md @@ -0,0 +1,3 @@ +# @scope/foo + +@scope/foo diff --git a/packages/create-lib/template/monorepo/packages/foo/package.json b/packages/create-lib/template/monorepo/packages/foo/package.json new file mode 100644 index 0000000..df25a43 --- /dev/null +++ b/packages/create-lib/template/monorepo/packages/foo/package.json @@ -0,0 +1,21 @@ +{ + "name": "@scope/foo", + "type": "module", + "version": "0.0.0", + "packageManager": "pnpm@10.25.0", + "license": "MIT", + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + }, + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=20.18.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/create-lib/template/monorepo/packages/foo/src/index.ts b/packages/create-lib/template/monorepo/packages/foo/src/index.ts new file mode 100644 index 0000000..cb35646 --- /dev/null +++ b/packages/create-lib/template/monorepo/packages/foo/src/index.ts @@ -0,0 +1 @@ +export const foo = 'foo' diff --git a/packages/create-lib/template/monorepo/packages/foo/tests/index.test.ts b/packages/create-lib/template/monorepo/packages/foo/tests/index.test.ts new file mode 100644 index 0000000..d593a9b --- /dev/null +++ b/packages/create-lib/template/monorepo/packages/foo/tests/index.test.ts @@ -0,0 +1,6 @@ +import { expect, it } from 'vitest' +import { foo } from '../src' + +it('simple', () => { + expect(foo).toBe('foo') +}) diff --git a/packages/create-lib/template/monorepo/pnpm-workspace.yaml b/packages/create-lib/template/monorepo/pnpm-workspace.yaml new file mode 100644 index 0000000..319213a --- /dev/null +++ b/packages/create-lib/template/monorepo/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +shellEmulator: true +trustPolicy: no-downgrade + +packages: + - packages/* diff --git a/packages/create-lib/template/monorepo/tsconfig.json b/packages/create-lib/template/monorepo/tsconfig.json new file mode 100644 index 0000000..c8b0cdd --- /dev/null +++ b/packages/create-lib/template/monorepo/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es2023"], + "moduleDetection": "force", + "module": "preserve", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "noUnusedLocals": true, + "declaration": true, + "esModuleInterop": true, + "isolatedDeclarations": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": ["packages/*/src", "packages/*/tests"], + "exclude": ["packages/*/tests/fixtures"] +} diff --git a/packages/create-lib/template/monorepo/tsdown.config.ts b/packages/create-lib/template/monorepo/tsdown.config.ts new file mode 100644 index 0000000..c89a2f2 --- /dev/null +++ b/packages/create-lib/template/monorepo/tsdown.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsdown' + +export default defineConfig({ + workspace: true, + entry: ['src/index.ts'], + exports: true, + dts: true, + publint: true, +}) diff --git a/packages/create-lib/template/single-repo/package.json b/packages/create-lib/template/single-repo/package.json new file mode 100644 index 0000000..cc83220 --- /dev/null +++ b/packages/create-lib/template/single-repo/package.json @@ -0,0 +1,13 @@ +{ + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + }, + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/create-lib/template/single-repo/src/index.ts b/packages/create-lib/template/single-repo/src/index.ts new file mode 100644 index 0000000..cb35646 --- /dev/null +++ b/packages/create-lib/template/single-repo/src/index.ts @@ -0,0 +1 @@ +export const foo = 'foo' diff --git a/packages/create-lib/template/single-repo/tests/index.test.ts b/packages/create-lib/template/single-repo/tests/index.test.ts new file mode 100644 index 0000000..d593a9b --- /dev/null +++ b/packages/create-lib/template/single-repo/tests/index.test.ts @@ -0,0 +1,6 @@ +import { expect, it } from 'vitest' +import { foo } from '../src' + +it('simple', () => { + expect(foo).toBe('foo') +}) diff --git a/packages/create-lib/template/single-repo/tsconfig.json b/packages/create-lib/template/single-repo/tsconfig.json new file mode 100644 index 0000000..1b93450 --- /dev/null +++ b/packages/create-lib/template/single-repo/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es2023"], + "moduleDetection": "force", + "module": "preserve", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "noUnusedLocals": true, + "declaration": true, + "esModuleInterop": true, + "isolatedDeclarations": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": ["src", "tests"] +} diff --git a/packages/create-lib/template/single-repo/tsdown.config.ts b/packages/create-lib/template/single-repo/tsdown.config.ts new file mode 100644 index 0000000..96a2092 --- /dev/null +++ b/packages/create-lib/template/single-repo/tsdown.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: ['src/index.ts'], + exports: true, + dts: true, + publint: true, +}) diff --git a/packages/create-lib/tsdown.config.ts b/packages/create-lib/tsdown.config.ts new file mode 100644 index 0000000..d1ab7a4 --- /dev/null +++ b/packages/create-lib/tsdown.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from 'tsdown' + +export default defineConfig({ + entry: 'src/index.ts', +}) From 5a8d47c959bed67aa2895d7ae703abcce7b44574 Mon Sep 17 00:00:00 2001 From: Yu Lia <1938793150@qq.com> Date: Sun, 1 Mar 2026 11:36:12 +0800 Subject: [PATCH 2/2] docs: update README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 9cab9aa..a107ab1 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,13 @@ npx @doyuli/create-vue npm create @doyuli/vue ``` + +### 创建 TypeScript Library 项目 + +```bash +npx @doyuli/create-lib + +# or + +npm create @doyuli/lib +```