Skip to content

Commit

Permalink
feat(js): add preset for TS standalone workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysoo committed May 26, 2023
1 parent 39f7459 commit 8989a8b
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 33 deletions.
34 changes: 23 additions & 11 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
determineDefaultBase,
determineNxCloud,
determinePackageManager,
determinePackageName,
determineTypeScriptUsage,
} from '../src/internal-utils/prompts';
import {
withAllPrompts,
Expand All @@ -42,6 +44,7 @@ interface Arguments extends CreateWorkspaceOptions {
nextAppDir: boolean;
routing: boolean;
bundler: Bundler;
js: boolean;
}

export const commandsObject: yargs.Argv<Arguments> = yargs
Expand Down Expand Up @@ -182,16 +185,17 @@ async function normalizeArgsMiddleware(
argv: yargs.Arguments<Arguments>
): Promise<void> {
try {
let name,
appName,
style,
preset,
framework,
bundler,
docker,
nextAppDir,
routing,
standaloneApi;
let name;
let appName;
let style;
let preset;
let framework;
let bundler;
let docker;
let nextAppDir;
let routing;
let standaloneApi;
let js;

output.log({
title:
Expand Down Expand Up @@ -224,6 +228,8 @@ async function normalizeArgsMiddleware(
preset = Preset.AngularStandalone;
} else if (monorepoStyle === 'node-standalone') {
preset = Preset.NodeStandalone;
} else if (monorepoStyle === 'ts-standalone') {
preset = Preset.TsStandalone;
} else {
// when choose integrated monorepo, further prompt for preset
preset = await determinePreset(argv);
Expand Down Expand Up @@ -269,6 +275,10 @@ async function normalizeArgsMiddleware(
argv.routing ??
(argv.interactive ? await determineRouting(argv) : true);
}
} else if (preset === Preset.TsStandalone) {
name = await determinePackageName(preset, argv);
appName = name;
js = !(await determineTypeScriptUsage(argv));
} else {
name = await determineRepoName(argv);
appName = await determineAppName(preset as Preset, argv);
Expand Down Expand Up @@ -308,6 +318,7 @@ async function normalizeArgsMiddleware(
bundler,
docker,
nextAppDir,
js,
});
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -671,7 +682,8 @@ async function determineStyle(
preset === Preset.Express ||
preset === Preset.ReactNative ||
preset === Preset.Expo ||
preset === Preset.NodeStandalone
preset === Preset.NodeStandalone ||
preset === Preset.TsStandalone
) {
return Promise.resolve(null);
}
Expand Down
55 changes: 54 additions & 1 deletion packages/create-nx-workspace/src/internal-utils/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as yargs from 'yargs';
import { messages } from '../utils/nx/ab-testing';
import enquirer = require('enquirer');
import { CI } from '../utils/ci/ci-list';
import { output } from '../utils/output';
import { deduceDefaultBase } from '../utils/git/default-base';
Expand All @@ -9,7 +8,9 @@ import {
PackageManager,
packageManagerList,
} from '../utils/package-manager';
import { Preset } from '../utils/preset/preset';
import { stringifyCollection } from '../utils/string-utils';
import enquirer = require('enquirer');

export async function determineNxCloud(
parsedArgs: yargs.Arguments<{ nxCloud: boolean }>
Expand Down Expand Up @@ -157,3 +158,55 @@ export async function determinePackageManager(

return Promise.resolve(detectInvokedPackageManager());
}

export async function determinePackageName(
preset: Preset,
parsedArgs: yargs.Arguments<{ name?: string }>
): Promise<string> {
if (parsedArgs.name) {
return Promise.resolve(parsedArgs.name);
}

return enquirer
.prompt<{ PackageName: string }>([
{
name: 'PackageName',
message: `Package name `,
type: 'input',
},
])
.then((a) => {
if (!a.PackageName) {
output.error({
title: 'Invalid name',
bodyLines: [`Name cannot be empty`],
});
process.exit(1);
}
return a.PackageName;
});
}

export async function determineTypeScriptUsage(
parsedArgs: yargs.Arguments<{ js?: boolean }>
): Promise<boolean> {
if (parsedArgs.js) return false;
return enquirer
.prompt<{ TypeScript: 'Yes' | 'No' }>([
{
name: 'TypeScript',
message: `Would you like to use TypeScript with this project?`,
type: 'autocomplete',
choices: [
{
name: 'Yes',
},
{
name: 'No',
},
],
initial: 'Yes' as any,
},
])
.then((a) => a.TypeScript === 'Yes');
}
1 change: 1 addition & 0 deletions packages/create-nx-workspace/src/utils/preset/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum Preset {
React = 'react',
Angular = 'angular',
NodeStandalone = 'node-standalone',
TsStandalone = 'ts-standalone',
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
'^.+\\\\.[tj]s$': ['@swc/jest', swcJestConfig],
},
moduleFileExtensions: ['ts', 'js', 'html'],
testEnvironment: 'jsdom',
coverageDirectory: '../../coverage/libs/my-lib',
};
"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ if (swcJestConfig.swcrc === undefined) {
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
},
moduleFileExtensions: ['ts', 'js', 'html'],
testEnvironment: '<%= testEnvironment %>',
coverageDirectory: '<%= offsetFromRoot %>coverage/<%= projectRoot %>'
};
14 changes: 0 additions & 14 deletions packages/js/src/generators/library/files/lib/tsconfig.json__tmpl__

This file was deleted.

32 changes: 31 additions & 1 deletion packages/js/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import jsInitGenerator from '../init/init';
import { PackageJson } from 'nx/src/utils/package-json';
import setupVerdaccio from '../setup-verdaccio/generator';
import { tsConfigBaseOptions } from '../../utils/typescript/create-ts-config';

export async function libraryGenerator(
tree: Tree,
Expand All @@ -63,6 +64,7 @@ export async function projectGenerator(
await jsInitGenerator(tree, {
...schema,
skipFormat: true,
tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
})
);
const options = normalizeOptions(tree, schema, destinationDir);
Expand Down Expand Up @@ -275,6 +277,9 @@ function addBabelRc(tree: Tree, options: NormalizedSchema) {

function createFiles(tree: Tree, options: NormalizedSchema, filesDir: string) {
const { className, name, propertyName } = names(options.name);

createProjectTsConfigJson(tree, options);

generateFiles(tree, filesDir, options.projectRoot, {
...options,
dot: '.',
Expand All @@ -286,7 +291,6 @@ function createFiles(tree: Tree, options: NormalizedSchema, filesDir: string) {
strict: undefined,
tmpl: '',
offsetFromRoot: offsetFromRoot(options.projectRoot),
rootTsConfigPath: getRelativePathToRootTsConfig(tree, options.projectRoot),
buildable: options.bundler && options.bundler !== 'none',
hasUnitTestRunner: options.unitTestRunner !== 'none',
});
Expand Down Expand Up @@ -403,6 +407,7 @@ function replaceJestConfig(
project: options.name,
offsetFromRoot: offsetFromRoot(options.projectRoot),
projectRoot: options.projectRoot,
testEnvironment: options.testEnvironment,
});
}

Expand Down Expand Up @@ -595,5 +600,30 @@ function getOutputPath(options: NormalizedSchema, destinationDir?: string) {
return joinPathFragments(...parts);
}

function createProjectTsConfigJson(tree: Tree, options: NormalizedSchema) {
const tsconfig = {
extends: options.rootProject
? undefined
: getRelativePathToRootTsConfig(tree, options.projectRoot),
compilerOptions: {
...(options.rootProject ? tsConfigBaseOptions : {}),
module: 'commonjs',
allowJs: options.js ? true : undefined,
},
files: [],
include: [],
references: [
{
path: './tsconfig.lib.json',
},
],
};
writeJson(
tree,
joinPathFragments(options.projectRoot, 'tsconfig.json'),
tsconfig
);
}

export default libraryGenerator;
export const librarySchematic = convertNxGenerator(libraryGenerator);
8 changes: 7 additions & 1 deletion packages/js/src/utils/swc/compile-swc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ function getSwcCmd(
{ swcrcPath, srcPath, destPath }: SwcCliOptions,
watch = false
) {
let swcCmd = `npx swc ${srcPath} -d ${destPath} --config-file=${swcrcPath}`;
let swcCmd = `npx swc ${
// TODO(jack): clean this up when we remove inline module support
// Handle root project
srcPath === '.' ? 'src' : srcPath
} -d ${destPath} --config-file=${swcrcPath}`;
return watch ? swcCmd.concat(' --watch') : swcCmd;
}

Expand Down Expand Up @@ -38,6 +42,8 @@ export async function compileSwc(
normalizedOptions: NormalizedSwcExecutorOptions,
postCompilationCallback: () => Promise<void>
) {
const isRootProject =
context.projectGraph.nodes[context.projectName].data.root === '.';
logger.log(`Compiling with SWC for ${context.projectName}...`);

if (normalizedOptions.clean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,27 @@ Visit the [Nx Documentation](https://nx.dev) to learn more.
"
`;
exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for TsStandalone preset 1`] = `
"# Proj
<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>
✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨
## Understand this workspace
Run \`nx graph\` to see a diagram of the dependencies of the projects.
## Remote caching
Run \`npx nx connect-to-nx-cloud\` to enable [remote caching](https://nx.app) and make CI faster.
## Further help
Visit the [Nx Documentation](https://nx.dev) to learn more.
"
`;
exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for WebComponents preset 1`] = `
"# Proj
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>

✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨<% if (!!appName) { %>

<% if (includeServe) { %>
## Development server

Run `nx serve <%= appName %>` for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.<% } %>

<% } %>
## Understand this workspace

Run `nx graph` to see a diagram of the dependencies of the projects.
Expand Down
2 changes: 2 additions & 0 deletions packages/workspace/src/generators/new/generate-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) {
opts.bundler ? `--bundler=${opts.bundler}` : null,
opts.framework ? `--framework=${opts.framework}` : null,
opts.docker ? `--docker=${opts.docker}` : null,
opts.js ? `--js` : null,
opts.nextAppDir ? `--nextAppDir=${opts.nextAppDir}` : null,
opts.packageManager ? `--packageManager=${opts.packageManager}` : null,
opts.standaloneApi !== undefined
Expand All @@ -98,6 +99,7 @@ function getPresetDependencies({
}: NormalizedSchema) {
switch (preset) {
case Preset.TS:
case Preset.TsStandalone:
return { dependencies: {}, dev: { '@nx/js': nxVersion } };

case Preset.AngularMonorepo:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
Preset.Express,
Preset.NodeStandalone,
Preset.NextJsStandalone,
Preset.TsStandalone,
].includes(Preset[preset])
) {
appName = 'app1';
Expand Down
Loading

0 comments on commit 8989a8b

Please sign in to comment.