diff --git a/.changeset/shaggy-impalas-bake.md b/.changeset/shaggy-impalas-bake.md new file mode 100644 index 0000000..e6de843 --- /dev/null +++ b/.changeset/shaggy-impalas-bake.md @@ -0,0 +1,6 @@ +--- +'@websublime/vtx-cli': patch +'@websublime/vtx-common': patch +--- + +Cli create lib template and command diff --git a/README.md b/README.md index 6bcb317..eedefbe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,111 @@ # VTX Workspace manager for vite +Vtx is an wrapper on vite cli tool to manage multi apps, libs and custom packages on monorepo style focus only with typescript support. + +## Dependencies + +- Node > 12 +- yarn + +## Install +Start to install cli as a globals package on your system. Monorepo is managed by yarn so it is mandatory using yarn as your dependency manager. +Install as: + +``` +yarn global add @websublime/vtx-cli +``` + +After this you will have binary vtx available as your cli tool. + +## Setup +Vtx cli tool can create, serve and build apps or libs. Run vtx --help for more info on the cli tool. + +``` +Usage: + $ vtx [root] + +Commands: + [root] + create-workspace + create-app + create-lib + +For more info, run any command with the `--help` flag: + $ vtx --help + $ vtx create-workspace --help + $ vtx create-app --help + $ vtx create-lib --help + +Options: + --host [host] [string] specify hostname + --port [number] specify port + --https [boolean] use TLS + HTTP/2 + --open [path] [boolean | string] open browser on startup + --cors [boolean] enable CORS + --strictPort [boolean] exit if specified port is already in use + --force [boolean] force the optimizer to ignore the cache and re-bundle + -b, --lib [string] use specified lib to build + -p, --app [string] use specified app to run + -c, --config [string] use specified config file + --base [string] public base path (default: /) + -l, --logLevel [string] info | warn | error | silent + --clearScreen [boolean] allow/disable clear screen when logging + -d, --debug [feat] [string | boolean] show debug logs + -f, --filter [string] filter debug logs + -m, --mode [string] set env mode + -h, --help Display this message + -v, --version Display version number +``` + +### Workspace +Start to create a workspace for your apps. Just run: + +``` +vtx create-workspace +``` + +And answer to the questions from the cli to config your workspace. + +### Vue App +After creating your workspace you are ready to add as many apps as you want. Inside your workspace directory run: + +``` +vtx create-app +``` + +And answer the questions to perform your app config. + +### Lib +Inside your workspace directory run: + +``` +vtx create-lib +``` + +### Run +By default your first app will be the default app to serve. If you want to run a different app just define the name the app you want to run. + +``` +vtx dev --app my-app +``` + +Or you can adjust your package.json script to run different apps like: + +``` +"scripts": { + "dev": "vtx dev --config ./vite.config.js --debug", + "dev:ready": "vtx dev --config ./vite.config.js --debug --app ready", + "build": "vtx build", + "preview": "vtx preview" +} +``` + +Vtx supports all options from vite-cli plus --app and --lib. + +## TODO + +More info about the tool + ## Publish - Run yarn changeset on branch diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index ee691b4..0ba951c 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -7,7 +7,7 @@ import { cac } from 'cac'; import { version } from '../package.json'; -import { promptCreateWorkspace, promptCreateApp } from './prompt'; +import { promptCreateWorkspace, promptCreateApp, promptCreateLib } from './prompt'; import { copy, writeJson, readJson } from 'fs-extra'; import { join, resolve } from 'path'; import { toValidPackageName } from '@websublime/vtx-common'; @@ -133,7 +133,72 @@ cli.command('create-app') cli.command('create-lib') .action(async () => { - console.dir('LIB'); + const { lib, namespace = '', target = process.cwd() } = await promptCreateLib(); + const pkg = await readJson(resolve(join(__dirname, './lib/package.json'))); + const tsconfig = await readJson(resolve(join(__dirname, './lib/tsconfig.json'))); + const pkgWorkspace = await readJson(resolve(join(target, './package.json'))); + + const hasNamespace = namespace.length > 0; + const name = hasNamespace ? `${namespace}/${toValidPackageName(lib)}` : toValidPackageName(lib); + + pkg.name = name; + + const destiny = join(target, './libs', toValidPackageName(lib)); + + pkgWorkspace.config.packages = { + ...pkgWorkspace.config.packages, + [toValidPackageName(lib)]: { + name: toValidPackageName(lib), + namespace: name, + dir: destiny, + type: 'application' + } + }; + + tsconfig.paths = { + ...tsconfig.paths, + [hasNamespace ? `${name}/*` : `@/${name}/*`]: ['./src/*'] + }; + + await copy(resolve(join(__dirname, './lib')), destiny, { recursive: true }); + await writeJson(join(destiny, 'package.json'), pkg, { encoding: 'utf8', spaces: 2, EOL }); + await writeJson(join(destiny, 'tsconfig.json'), tsconfig, { encoding: 'utf8', spaces: 2, EOL }); + await writeJson(join(target, 'package.json'), pkgWorkspace, { encoding: 'utf8', spaces: 2, EOL }); + }); + +cli.command('build') + .option('--target ', `[string] transpile target (default: 'modules')`) + .option('--outDir ', `[string] output directory (default: dist)`) + .option( + '--assetsDir ', + `[string] directory under outDir to place assets in (default: _assets)` + ) + .option( + '--assetsInlineLimit ', + `[number] static asset base64 inline threshold in bytes (default: 4096)` + ) + .option( + '--ssr [entry]', + `[string] build specified entry for server-side rendering` + ) + .option( + '--sourcemap', + `[boolean] output source maps for build (default: false)` + ) + .option( + '--minify [minifier]', + `[boolean | "terser" | "esbuild"] enable/disable minification, ` + + `or specify minifier to use (default: esbuild)` + ) + .option('--manifest', `[boolean] emit build manifest json`) + .option('--ssrManifest', `[boolean] emit ssr manifest json`) + .option( + '--emptyOutDir', + `[boolean] force empty outDir when it's outside of root` + ) + .option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`) + .action(async () => { + console.info('BUILD PROCESS'); }); cli.help(); diff --git a/packages/cli/src/prompt.ts b/packages/cli/src/prompt.ts index aca23ec..13230de 100644 --- a/packages/cli/src/prompt.ts +++ b/packages/cli/src/prompt.ts @@ -51,4 +51,28 @@ export const promptCreateApp = async () => { ], { onCancel: OperationCancel }); +}; + +export const promptCreateLib = async () => { + return await prompts([ + { + name: 'lib', + type: 'text', + message: 'Your lib name' + }, + { + name: 'namespace', + type: 'text', + message: 'Your namespace context: Example @lib or empty', + initial: '' + }, + { + name: 'target', + type: 'text', + message: 'Target directory', + initial: process.cwd() + } + ], { + onCancel: OperationCancel + }); }; \ No newline at end of file diff --git a/packages/cli/src/templates/lib/package.json b/packages/cli/src/templates/lib/package.json new file mode 100644 index 0000000..e3301ec --- /dev/null +++ b/packages/cli/src/templates/lib/package.json @@ -0,0 +1,23 @@ +{ + "name": "@monorepo/lib", + "version": "1.0.0", + "source": "src/index.ts", + "main": "./dist/index.umd.js", + "module": "./dist/index.es.js", + "exports": { + ".": { + "import": "./dist/index.es.js", + "require": "./dist/index.umd.js" + } + }, + "types": "src/index.ts", + "scripts": { + "build": "tsc" + }, + "dependencies": {}, + "devDependencies": { + "@types/node": "^16.11.12", + "typescript": "^4.5.2", + "vue": "^3.2.22" + } +} diff --git a/packages/cli/src/templates/lib/src/index.ts b/packages/cli/src/templates/lib/src/index.ts new file mode 100644 index 0000000..54f9764 --- /dev/null +++ b/packages/cli/src/templates/lib/src/index.ts @@ -0,0 +1,5 @@ +const hello = 'Hello World'; + +export { + hello +}; \ No newline at end of file diff --git a/packages/cli/src/templates/lib/tsconfig.json b/packages/cli/src/templates/lib/tsconfig.json new file mode 100644 index 0000000..15b191c --- /dev/null +++ b/packages/cli/src/templates/lib/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "paths": {}, + "types": ["vite/client"] + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/packages/cli/src/templates/workspace/package.json b/packages/cli/src/templates/workspace/package.json index 52c4eee..bea624d 100644 --- a/packages/cli/src/templates/workspace/package.json +++ b/packages/cli/src/templates/workspace/package.json @@ -1,8 +1,8 @@ { "name": "workspace", "devDependencies": { - "@websublime/vtx-common": "^0.0.6", - "@websublime/vtx-cli": "^0.0.7", + "@websublime/vtx-common": "latest", + "@websublime/vtx-cli": "latest", "@types/node": "^16.11.12", "@vitejs/plugin-vue": "1.10.0", "@vue/compiler-sfc": "3.2.22", diff --git a/packages/cli/src/vite.ts b/packages/cli/src/vite.ts index 3f5572d..ae0d046 100644 --- a/packages/cli/src/vite.ts +++ b/packages/cli/src/vite.ts @@ -5,7 +5,7 @@ * found in the LICENSE file at https://websublime.dev/license */ -import { createLogger, createServer } from 'vite'; +import { build, BuildOptions, createLogger, createServer } from 'vite'; import chalk from 'chalk'; export const viteServer = async (root: string, options: any, httpOptions: any) => { @@ -46,3 +46,9 @@ export const viteServer = async (root: string, options: any, httpOptions: any) = process.exit(1) } }; + +export const viteBuild = async (root: string, options: BuildOptions) => { + console.info(root); + + await build(options); +}; \ No newline at end of file