Skip to content

Commit

Permalink
feat: 🚀 Support profile
Browse files Browse the repository at this point in the history
  • Loading branch information
viarotel committed Oct 17, 2024
1 parent d5f82db commit aa3ce02
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 69 deletions.
10 changes: 4 additions & 6 deletions README-CN.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# Cleants

<!-- automd:badges -->

[![npm 版本](https://img.shields.io/npm/v/cleants)](https://npmjs.com/package/cleants)
[![npm 下载量](https://img.shields.io/npm/dm/cleants)](https://npm.chart.dev/cleants)

<!-- /automd -->

> 🧹 将 TypeScript 转换为更简洁的 JavaScript 项目
## 功能
Expand Down Expand Up @@ -34,13 +30,15 @@ pnpm add cleants

## 使用方法

### CLI 使用方法
> 你可以在执行命令目录下添加 `cleants.config.js` 文件来指定更多配置
CLI 使用方法

```shell
npx cleants
```

### 编程使用方法
编程使用方法

```javascript
import { Cleants } from 'cleants'
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# Cleants

<!-- automd:badges -->

[![npm version](https://img.shields.io/npm/v/cleants)](https://npmjs.com/package/cleants)
[![npm downloads](https://img.shields.io/npm/dm/cleants)](https://npm.chart.dev/cleants)

<!-- /automd -->

> 🧹 Convert TypeScript to a cleaner JavaScript project
## Features
Expand Down Expand Up @@ -34,6 +30,8 @@ pnpm add cleants

## Usage

> You can add a `cleants.config.js` file in the command execution directory to specify more configurations
CLI Usage

```shell
Expand Down
87 changes: 45 additions & 42 deletions src/bin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env node

import Cleants from './index.js'
import { capitalizeFirstLetter } from './helpers/index.js'
import yargs from 'yargs'
Expand All @@ -8,52 +7,56 @@ import * as p from '@clack/prompts'
import { description, name, version } from '../package.json'
import ora from 'ora'

yargs(hideBin(process.argv))
.command('$0', description, () => {}, async (argv) => {
p.intro(`${capitalizeFirstLetter(name)}: ${description}. Supported by Viarotel v${version}`)

const inputDir = await p.text({
message: 'Enter the TypeScript project directory to convert:',
validate: value => value.trim() === '' ? 'This field is required' : undefined,
})
function runCommand() {
yargs(hideBin(process.argv))
.command('$0', description, () => {}, async (argv) => {
p.intro(`${capitalizeFirstLetter(name)}: ${description}. Supported by Viarotel v${version}`)

const inputDir = await p.text({
message: 'Enter the TypeScript project directory to convert:',
validate: value => value.trim() === '' ? 'This field is required' : undefined,
})

const outputDir = await p.text({
message: 'Enter the output project directory:',
validate: value => value.trim() === '' ? 'This field is required' : undefined,
initialValue: './',
})

const replaceInternalImports = await p.confirm({
message: 'Automatically replace the suffix of inline imports?',
initialValue: true,
})

if (p.isCancel(inputDir) || p.isCancel(outputDir) || p.isCancel(replaceInternalImports)) {
p.cancel('Operation cancelled.')
process.exit(0)
}

const outputDir = await p.text({
message: 'Enter the output project directory:',
validate: value => value.trim() === '' ? 'This field is required' : undefined,
initialValue: './',
})
const spinner = ora('Converting project...').start()

const replaceInternalImports = await p.confirm({
message: 'Automatically replace the suffix of inline imports?',
initialValue: true,
})
try {
const progressCallback = ({ stage, progress }) => {
spinner.text = `${stage}: ${progress.toFixed(2)}%`
}

if (p.isCancel(inputDir) || p.isCancel(outputDir) || p.isCancel(replaceInternalImports)) {
p.cancel('Operation cancelled.')
process.exit(0)
}
const cleants = new Cleants(inputDir, outputDir, { progressCallback })

const spinner = ora('Converting project...').start()
await cleants.convert()

try {
const progressCallback = ({ stage, progress }) => {
spinner.text = `${stage}: ${progress.toFixed(2)}%`
spinner.succeed('Conversion completed successfully!')
}
catch (error) {
spinner.fail('An error occurred during conversion')
p.log.error(error.message)
process.exit(1)
}

const cleants = new Cleants(inputDir, outputDir, { progressCallback })

await cleants.convert()

spinner.succeed('Conversion completed successfully!')
}
catch (error) {
spinner.fail('An error occurred during conversion')
p.log.error(error.message)
process.exit(1)
}
p.outro('Thank you for using Cleants!')
})
.version(version)
.help()
.argv
}

p.outro('Thank you for using Cleants!')
})
.version(version)
.help()
.argv
runCommand()
42 changes: 42 additions & 0 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import path from 'node:path'
import fs from 'fs-extra'
import { pathToFileURL } from 'node:url'

import { extensionMap } from '../constants/index.js'

export function hasScriptTag(content) {
Expand Down Expand Up @@ -69,3 +72,42 @@ export function capitalizeFirstLetter(str) {
return str
return str.charAt(0).toUpperCase() + str.slice(1)
}

/**
* 加载当前工作目录下的 cleants.config.js 配置文件。
*
* @param configFileName 加载的配置文件名称
* @async
* @function loadConfig
* @returns {Promise<Object>} 返回配置对象。如果配置文件不存在,返回空对象或默认配置。
* @throws {Error} 如果加载配置文件时发生错误,抛出异常。
*
* @example
* (async () => {
* const config = await loadConfig();
* console.log('加载的配置:', config);
* })();
*/
export async function loadConfig(configFileName = 'cleants.config.js') {
const configFilePath = path.join(process.cwd(), configFileName)

try {
// 检查配置文件是否存在
const fileExists = await fs.pathExists(configFilePath)

if (!fileExists) {
return {}
}

// 动态导入配置文件
const configFileUrl = pathToFileURL(configFilePath).href

const config = await import(configFileUrl)

// 返回配置内容,确保导出为默认
return config.default || config
}
catch (error) {
return {}
}
}
46 changes: 29 additions & 17 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import path from 'node:path'
import { glob } from 'glob'
import ts from 'typescript'

import { loadConfig } from './helpers/index.js'

import { basePlugin, replacePlugin, vuePlugin } from './plugins/index.js'

let fileOptions = {}

loadConfig().then((configs) => {
fileOptions = configs
})

/**
* Cleants 类用于将 TypeScript 项目转换为 JavaScript 项目。
*/
Expand All @@ -22,40 +30,44 @@ class Cleants {
* @param {boolean} [options.replaceInternalImports] - 是否替换内部导入。
*/
constructor(inputDir, outputDir, options = {}) {
this.inputDir = inputDir
this.outputDir = outputDir
this.progressCallback = options.progressCallback || (() => false)

this.options = {
compilerOptions: options.compilerOptions || {},
ignoredCopyPatterns: options.ignoredCopyPatterns || [
compilerOptions: {},
ignoredCopyPatterns: [
'node_modules',
'.git',
'dist',
/\.d\.ts$/,
file => file.endsWith('.log'),
],
ignoredConversionPatterns: options.ignoredConversionPatterns || [
ignoredConversionPatterns: [
'vendor',
/\.min\.js$/,
file => file.includes('legacy'),
],
getOutputDir: options.getOutputDir || (inputDir => `${path.basename(inputDir)}.cleants`),
removeDependencies: options.removeDependencies || ['typescript', 'vue-tsc', '@types/node'],
replaceInternalImports: options.replaceInternalImports || true,
getOutputDir: inputDir => `${path.basename(inputDir)}.cleants`,
removeDependencies: ['typescript', 'vue-tsc', '@types/node'],
replaceInternalImports: false,
progressCallback: () => false,
plugins: [basePlugin, vuePlugin],
...fileOptions,
...options,
}

this.actualOutputDir = path.join(this.outputDir, this.options.getOutputDir(this.inputDir))
this.inputDir = inputDir ?? this.options.inputDir
this.outputDir = outputDir ?? this.options.outputDir

this.plugins = options.plugins || [basePlugin, vuePlugin]
this.progressCallback = this.options.progressCallback
this.plugins = this.options.plugins

if (this.options.replaceInternalImports) {
this.plugins.unshift(replacePlugin)
this.hooks = {
beforeConvert: this.options.hooks?.beforeConvert || (() => false),
afterConvert: this.options.hooks?.afterConvert || (() => false),
}

this.hooks = {
beforeConvert: options.hooks?.beforeConvert || (() => false),
afterConvert: options.hooks?.afterConvert || (() => false),
this.actualOutputDir = path.join(this.outputDir, this.options.getOutputDir(this.inputDir))

if (this.options.replaceInternalImports) {
this.plugins.unshift(replacePlugin)
}
}

Expand Down

0 comments on commit aa3ce02

Please sign in to comment.