Skip to content

Commit

Permalink
feat(vue): init and lib generators
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Sep 6, 2023
1 parent 5610f2a commit ddba7de
Show file tree
Hide file tree
Showing 26 changed files with 1,758 additions and 0 deletions.
Empty file added packages/vue/docs/.gitkeep
Empty file.
Empty file.
27 changes: 27 additions & 0 deletions packages/vue/src/generators/init/init.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { readJson, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { vueInitGenerator } from './init';
import { InitSchema } from './schema';

// TODO: more or different to be added here
describe('init', () => {
let tree: Tree;
let schema: InitSchema = {
skipFormat: false,
};

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

it('should add react dependencies', async () => {
await vueInitGenerator(tree, schema);
const packageJson = readJson(tree, 'package.json');
expect(packageJson.dependencies['vue']).toBeDefined();
});

it('should not add jest config if unitTestRunner is none', async () => {
await vueInitGenerator(tree, { ...schema, unitTestRunner: 'none' });
expect(tree.exists('jest.config.js')).toEqual(false);
});
});
70 changes: 70 additions & 0 deletions packages/vue/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
addDependenciesToPackageJson,
convertNxGenerator,
GeneratorCallback,
readNxJson,
removeDependenciesFromPackageJson,
runTasksInSerial,
Tree,
updateNxJson,
} from '@nx/devkit';

import { initGenerator as jsInitGenerator } from '@nx/js';
import { nxVersion, vueVersion } from '../../utils/versions';
import { InitSchema } from './schema';

function setDefault(host: Tree) {
const workspace = readNxJson(host);

workspace.generators = workspace.generators || {};
const vueGenerators = workspace.generators['@nx/vue'] || {};
const generators = {
...workspace.generators,
'@nx/vue': {
...vueGenerators,
application: {
...vueGenerators.application,
babel: true,
},
},
};

updateNxJson(host, { ...workspace, generators });
}

function updateDependencies(host: Tree, _schema: InitSchema) {
removeDependenciesFromPackageJson(host, ['@nx/vue'], []);

const dependencies = {
vue: vueVersion,
};

return addDependenciesToPackageJson(host, dependencies, {
'@nx/vue': nxVersion,
});
}

export async function vueInitGenerator(host: Tree, schema: InitSchema) {
const tasks: GeneratorCallback[] = [];

const jsInitTask = await jsInitGenerator(host, {
...schema,
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
skipFormat: true,
});

tasks.push(jsInitTask);

setDefault(host);

if (!schema.skipPackageJson) {
const installTask = updateDependencies(host, schema);
tasks.push(installTask);
}

return runTasksInSerial(...tasks);
}

export default vueInitGenerator;

export const vueInitSchematic = convertNxGenerator(vueInitGenerator);
9 changes: 9 additions & 0 deletions packages/vue/src/generators/init/schema.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface InitSchema {
unitTestRunner?: 'vitest' | 'none'; // TODO: more or different to be added here
e2eTestRunner?: 'cypress' | 'playwright' | 'none'; // TODO: more or different to be added here
skipFormat?: boolean;
skipPackageJson?: boolean;
js?: boolean;
rootProject?: boolean;
// TODO: more or different to be added here
}
43 changes: 43 additions & 0 deletions packages/vue/src/generators/init/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "NxVueInit",
"title": "Init Vue Plugin",
"description": "Initialize a Vue Plugin.",
"cli": "nx",
"type": "object",
"properties": {
"unitTestRunner": {
"description": "Adds the specified unit test runner.",
"type": "string",
"enum": ["vitest", "none"],
"default": "vitest"
},
"e2eTestRunner": {
"description": "Adds the specified E2E test runner.",
"type": "string",
"enum": ["cypress", "playwright", "none"],
"default": "cypress"
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false
},
"skipPackageJson": {
"description": "Do not add dependencies to `package.json`.",
"type": "boolean",
"default": false
},
"js": {
"type": "boolean",
"description": "Use JavaScript instead of TypeScript",
"default": false
},
"rootProject": {
"description": "Create a project at the root of the workspace",
"type": "boolean",
"default": false
}
},
"required": []
}
7 changes: 7 additions & 0 deletions packages/vue/src/generators/library/files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# <%= name %>

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test <%= name %>` to execute the unit tests via [Vitest](https://vitest.dev/).
12 changes: 12 additions & 0 deletions packages/vue/src/generators/library/files/package.json__tmpl__
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "<%= name %>",
"version": "0.0.1",
"main": "./index.js",
"types": "./index.d.ts",
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js"
}
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"outDir": "<%= offsetFromRoot %>dist/out-tsc",
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"types": ["node"]
},
"exclude": [
"src/**/__tests__/*",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"],
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.lib.json",
"exclude": [],
"compilerOptions": {
"composite": true,
"lib": [],
"types": ["node", "jsdom"]
}
}
Empty file.
45 changes: 45 additions & 0 deletions packages/vue/src/generators/library/lib/add-linting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Tree } from 'nx/src/generators/tree';
import { Linter, lintProjectGenerator } from '@nx/linter';
import { joinPathFragments } from 'nx/src/utils/path';
import { addDependenciesToPackageJson, runTasksInSerial } from '@nx/devkit';

import { NormalizedSchema } from '../schema';
import { extraEslintDependencies } from '../../../utils/lint';
import {
addExtendsToLintConfig,
isEslintConfigSupported,
} from '@nx/linter/src/generators/utils/eslint-file';

export async function addLinting(host: Tree, options: NormalizedSchema) {
if (options.linter === Linter.EsLint) {
const lintTask = await lintProjectGenerator(host, {
linter: options.linter,
project: options.name,
tsConfigPaths: [
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
],
unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true,
skipPackageJson: options.skipPackageJson,
setParserOptionsProject: options.setParserOptionsProject,
});

if (isEslintConfigSupported(host)) {
addExtendsToLintConfig(host, options.projectRoot, 'plugin:@nx/vue');
}

let installTask = () => {};
if (!options.skipPackageJson) {
installTask = await addDependenciesToPackageJson(
host,
extraEslintDependencies.dependencies,
extraEslintDependencies.devDependencies
);
}

return runTasksInSerial(lintTask, installTask);
} else {
return () => {};
}
}
49 changes: 49 additions & 0 deletions packages/vue/src/generators/library/lib/create-files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Tree } from '@nx/devkit';
import {
generateFiles,
joinPathFragments,
names,
offsetFromRoot,
toJS,
writeJson,
} from '@nx/devkit';
import { getRelativePathToRootTsConfig } from '@nx/js';
import { NormalizedSchema } from '../schema';
import { createTsConfig } from '../../../utils/create-ts-config';

export function createFiles(host: Tree, options: NormalizedSchema) {
const relativePathToRootTsConfig = getRelativePathToRootTsConfig(
host,
options.projectRoot
);
const substitutions = {
...options,
...names(options.name),
tmpl: '',
offsetFromRoot: offsetFromRoot(options.projectRoot),
fileName: options.fileName,
};

generateFiles(
host,
joinPathFragments(__dirname, '../files'),
options.projectRoot,
substitutions
);

if (!options.publishable && !options.buildable) {
host.delete(`${options.projectRoot}/package.json`);
}

if (options.js) {
toJS(host);
}

createTsConfig(
host,
options.projectRoot,
'lib',
options,
relativePathToRootTsConfig
);
}
Loading

0 comments on commit ddba7de

Please sign in to comment.