Skip to content

Latest commit

 

History

History
215 lines (174 loc) · 6.88 KB

README.md

File metadata and controls

215 lines (174 loc) · 6.88 KB

Uncouth

Remove the class from your Vue components.

Converts class based components to Composition API.

Forked from the great work of yoyo930021: https://github.com/yoyo930021/vc2c

Demo

Introduction

ASTConvertPlugins is the most important part of this project, it can convert AST to composition APIs. Custom decorator in ASTConvertPlugins are supported, such as @Subscription. See Writing a custom ASTConvert for more details.

Supports

The files to be converted must meet the criteria below:

  • Scripts must be written in Typescript. (JavaScript may be supported in the future.)
  • All syntax must be valid.
  • Node.js >= 8.16

Supported features

  • vue-class-component
    • Object
      • name
      • props
        • PropType<...>
      • data
      • computed
      • methods
      • watch
      • intervalHook (ex: mounted)
      • provide / inject
      • mixins
      • extends
      • render
    • Class
      • className
      • computed
      • data
      • intervalHook (ex: mounted)
      • render
      • methods
      • Mixins
      • $refs
  • vue-property-decorator
    • @Prop
    • @PropSync
    • @Model
    • @Watch
    • @Provide / @Inject
    • @ProvideReactive / @InjectReactive
    • @Emit
    • @Ref
  • vuex-class
    • @Action
    • @Getter
    • @Mutation
    • @State
    • @<namespace>
      • .Action
      • .Getter
      • .Mutation
      • .State
  • replace this to props, variable, or context.
  • sort by dependency.

Usage

The uncouth project has both CLI and API interface.

CLI

# npm
npx uncouth single [cliOptions] <VueOrTSfilePath>

# yarn
yarn add uncouth
yarn uncouth single [cliOptions] <VueOrTSfilePath>

# volta
sudo volta install uncouth
uncouth single [cliOptions] <VueOrTSfilePath>

Options

-v, --view             Output file content on stdout, and no write file.
-o, --output           Output result file path.
-r, --root <root>      Set root path for calc file absolute path. Default:`process.cwd()`.
-c, --config <config>  Set uncouth config file path. Default: `'.uncouth.js'`.
-h, --help             Output usage information.

API

const { convert, convertFile } = require("uncouth");

// Get convert result script
const resultScript = convert(
  /* scriptContent */ fileContent, // can't include vue file content, if vue file, only input script element content
  /* {UncouthConfig} */ options
);

// Get FileInfo and scriptResult
const { file, result } = convertFile(
  /* VueOrTSfilePath */ filePath,
  /* rootPath */ cmdOptions.root,
  /* UncouthConfigFilePath */ cmdOptions.config
);

Uncouth Config

{
  // root path for calc file absolute path, if in CLI, --root value will replace.
  root?: string, // Default:`process.cwd()`
  // show debug message.
  debug?: boolean, // Default: `false`
  // if true, use @vue/composition-api.
  compatible?: boolean, // Default: `false`
  // first setup function parameter name.
  setupPropsKey?: string, // Default: `props`
  // second setup function parameter name.
  setupContextKey?: string, // Default: `context`
  // Use custom version typescript.
  typescript?: typeof ts, // Default: Typescript 3.7.3
  // Use custom version vue-template-compiler, please match your project vue versions.
  vueTemplateCompiler?: typeof vueTemplateCompiler, // Default: vue-template-compiler 2.6.11
  // Use custom prettier config file path. if file does not exist, use default uncouth prettier config.
  prettierConfig?: string // Default: `.prettierrc`
  // Use custom ASTConvertPlugins for ASTConvert and ASTTransform
  plugins?: ASTConvertPlugins,
  // if using vuex-class the variable name to use for the store
  vuexKey?: string, // Default: `store`
}

Plugins

ASTConvertPlugins

import * as ts from "typescript";
// import { ASTConvertPlugins, ASTConverter, ASTTransform } from 'uncouth'
export interface ASTConvertPlugins {
  [ts.SyntaxKind.Decorator]: {
    // @Component decorator argument ASTConvert
    [ts.SyntaxKind.PropertyAssignment]: Array<ASTConverter<ts.PropertyAssignment>>;
    [ts.SyntaxKind.MethodDeclaration]: Array<ASTConverter<ts.MethodDeclaration>>;
  };
  // Class child AST will forEach ASTConverter until return ASTResult by AST SyntaxKind
  [ts.SyntaxKind.Identifier]: Array<ASTConverter<ts.Identifier>>;
  [ts.SyntaxKind.HeritageClause]: Array<ASTConverter<ts.HeritageClause>>;
  [ts.SyntaxKind.PropertyDeclaration]: Array<ASTConverter<ts.PropertyDeclaration>>;
  [ts.SyntaxKind.GetAccessor]: Array<ASTConverter<ts.GetAccessorDeclaration>>;
  [ts.SyntaxKind.SetAccessor]: Array<ASTConverter<ts.SetAccessorDeclaration>>;
  [ts.SyntaxKind.MethodDeclaration]: Array<ASTConverter<ts.MethodDeclaration>>;
  // When all ASTConvert finished, run ASTTransform.
  after: Array<ASTTransform>;
}

ASTConvertPlugins process

  • Vue Class @Component decorator Object:

    • Uncouth will parse object properties of @Component argument by running ASTConvert functions in plugins[ts.SyntaxKind.Decorator][property.kind as ts.SyntaxKind] array.
    • When ASTConvert returns a ASTResult, uncouth will record the ASTResult and proceed to the next object property.
    • If ASTConvert returns false, uncouth will run the next ASTConvert function in the array.
  • Vue Class:

    • Uncouth will parse Class AST childs by running ASTConvert functions in plugins[AST.kind as ts.SyntaxKind] array.
    • When ASTConvert returns a ASTResult, uncouth will record the ASTResult and proceed to the next object property.
    • If ASTConvert returns false, uncouth will run the next ASTConvert function in the array.
  • Transform:

    • Uncouth will run all ASTTransform functions in plugins.after array after finishing the two steps above.
    • You can use it to merge or sort AST. ex: computed, removeThis.

Tips

  • You can use https://ts-ast-viewer.com/ to get Typescript ast.
  • You can use built-in ASTConvert or ASTTransform in ASTConvertPlugins.
    import { BuiltInPlugins } from "uncouth";
    const astConvert: ASTConvert = BuiltInPlugins.convertProp;
  • You cas use built-in typescript AST utils.
    import { getDecoratorNames, isInternalHook } from "uncouth";
  • ASTConvert functions must be placed in order by it's strictness in ASTConvertPlugins. Stricter function should be placed up front.
  • If you want to use Vue any property, you can see link.

ASTConvert Example

Roadmap

  • Add more TODO: comments on needed.
  • Support more features.
  • Convert project.