Skip to content

Commit

Permalink
feat(nx-vite): ✨ support Vue app generation
Browse files Browse the repository at this point in the history
  • Loading branch information
linbudu599 committed Oct 3, 2021
1 parent 077a9f6 commit ed71cee
Show file tree
Hide file tree
Showing 32 changed files with 317 additions and 29 deletions.
1 change: 1 addition & 0 deletions packages/nx-plugin-devkit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './lib/generator-utils/node-app-setup';
export * from './lib/generator-utils/normalize-schema';
export * from './lib/generator-utils/minimal-generator';
export * from './lib/generator-utils/package-json';
export * from './lib/generator-utils/install-package-task';

export * from './lib/executor-utils/info';
export * from './lib/executor-utils/allow-ts';
Expand Down
1 change: 0 additions & 1 deletion packages/nx-plugin-devkit/src/lib/executor-utils/cli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import execa, { Options, SyncOptions } from 'execa';
import { Observable } from 'rxjs';
// import {} from 'rxjs/operators';

export function executeFromCLICommand(
command: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Target } from '@nrwl/tao/src/commands/run';
import type { ExecutorContext } from '@nrwl/tao/src/shared/workspace';

import { Workspaces } from '@nrwl/tao/src/shared/workspace';
import { combineOptionsForExecutor } from '@nrwl/tao/src/shared/params';

/**
* forked from @nrwl/devkit
*
* Reads and combines options for a given target.
* Works as if you invoked the target yourself without passing any command lint overrides.
*/
export function readTargetOptions(
{ project, target, configuration }: Target,
context: ExecutorContext
) {
const projectConfiguration = context.workspace.projects[project];
const targetConfiguration = projectConfiguration.targets[target];

const ws = new Workspaces(context.root);
const [nodeModule, executorName] = targetConfiguration.executor.split(':');
const { schema } = ws.readExecutor(nodeModule, executorName);

const defaultProject = ws.calculateDefaultProjectName(
context.cwd,
context.workspace
);

return combineOptionsForExecutor(
{},
configuration ?? '',
targetConfiguration,
schema,
defaultProject,
ws.relativeCwd(context.cwd)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { Tree } from '@nrwl/tao/src/shared/tree';
import { execSync } from 'child_process';
import { join } from 'path';
import {
detectPackageManager,
getPackageManagerCommand,
} from '@nrwl/tao/src/shared/package-manager';
import type { PackageManager } from '@nrwl/tao/src/shared/package-manager';
import { joinPathFragments } from '@nrwl/devkit';
import execa from 'execa';
import consola from 'consola';

let storedPackageJsonValue: string;

/**
* forked from @nrwl/devkit
*
* @param tree - the file system tree
* @param force - always run the command even if `package.json` hasn't changed.
* @param cwd cwd to execute install
* @param packageManager one of npm/yarn/pnpm
*/
export function installPackagesTask(
tree: Tree,
force = false,
cwd = '',
packageManager: PackageManager = detectPackageManager(cwd)
): void {
const packageJsonValue = tree.read(
joinPathFragments(cwd, 'package.json'),
'utf-8'
);

const shouldExecuteInstall =
tree
.listChanges()
.find((f) => f.path === joinPathFragments(cwd, 'package.json')) || force;

if (!shouldExecuteInstall) {
consola.info('Install skipped.');
return;
}

consola.info('Install task starting...');

// Don't install again if install was already executed with package.json
if (storedPackageJsonValue != packageJsonValue || force) {
storedPackageJsonValue = packageJsonValue;
const installCommand = getPackageManagerCommand(packageManager).install;

execa.sync(installCommand, {
cwd: join(tree.root, cwd),
stdio: 'inherit',
});

consola.success('Install task accomplished.');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export interface MinimalAppGeneratorSchema {
tags?: string;
directory?: string;
projectType?: ProjectType;
forceInstall: boolean;
}

interface MinimalNormalizedSchema extends MinimalAppGeneratorSchema {
export interface MinimalNormalizedSchema extends MinimalAppGeneratorSchema {
projectName: string;
projectRoot: string;
projectDirectory: string;
parsedTags: string[];

projectType: ProjectType;
}

Expand All @@ -31,10 +31,10 @@ interface MinimalNormalizedSchema extends MinimalAppGeneratorSchema {
* @param options
* @returns
*/
export function minimalNormalizeOptions(
host: Tree,
options: MinimalAppGeneratorSchema
): MinimalNormalizedSchema {
export function minimalNormalizeOptions<
TSchema extends MinimalAppGeneratorSchema,
NSchema extends MinimalNormalizedSchema
>(host: Tree, options: TSchema): NSchema {
const name = names(options.name).fileName;

const projectDirectory = options.directory
Expand All @@ -61,7 +61,7 @@ export function minimalNormalizeOptions(
projectDirectory,
parsedTags,
projectType,
};
} as unknown as NSchema;
}

/**
Expand All @@ -70,10 +70,10 @@ export function minimalNormalizeOptions(
* @param templatePath
* @param options
*/
export function minimalAddFiles(
export function minimalAddFiles<TSchema extends MinimalNormalizedSchema>(
host: Tree,
templatePath: string,
options: MinimalNormalizedSchema
options: TSchema
) {
const templateOptions = {
...options,
Expand All @@ -90,8 +90,10 @@ export function minimalAddFiles(
* @param normalizedOptions
* @returns
*/
export function minimalProjectConfiguration(
normalizedOptions: MinimalNormalizedSchema
export function minimalProjectConfiguration<
TSchema extends MinimalNormalizedSchema
>(
normalizedOptions: TSchema
): ProjectConfiguration & NxJsonProjectConfiguration {
return {
root: normalizedOptions.projectRoot,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
13 changes: 13 additions & 0 deletions packages/nx-plugin-vite/src/generators/app/files/vue/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
18 changes: 18 additions & 0 deletions packages/nx-plugin-vite/src/generators/app/files/vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "vite-vue3",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"serve": "vite preview"
},
"dependencies": {
"vue": "^3.2.16"
},
"devDependencies": {
"@vitejs/plugin-vue": "^1.9.2",
"typescript": "^4.4.3",
"vite": "^2.6.0",
"vue-tsc": "^0.3.0"
}
}
Binary file not shown.
21 changes: 21 additions & 0 deletions packages/nx-plugin-vite/src/generators/app/files/vue/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
</template>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ msg: string }>()
const count = ref(0)
</script>

<template>
<h1>{{ msg }}</h1>

<p>
Recommended IDE setup:
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
+
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
</p>

<p>See <code>README.md</code> for more information.</p>

<p>
<a href="https://vitejs.dev/guide/features.html" target="_blank">
Vite Docs
</a>
|
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
</p>

<button type="button" @click="count++">count is: {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>

<style scoped>
a {
color: #42b983;
}
label {
margin: 0 0.5em;
font-weight: bold;
}
code {
background-color: #eee;
padding: 2px 4px;
border-radius: 4px;
color: #304455;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// <reference types="vite/client" />

declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
15 changes: 15 additions & 0 deletions packages/nx-plugin-vite/src/generators/app/files/vue/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
Loading

0 comments on commit ed71cee

Please sign in to comment.