Skip to content

Commit 49c5a73

Browse files
leosvelperezjaysoo
andauthored
feat(js): generate experimental simplified library with ts solution setup (#27910)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # --------- Co-authored-by: Jack Hsu <[email protected]>
1 parent 5724deb commit 49c5a73

File tree

80 files changed

+2997
-1464
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2997
-1464
lines changed

docs/generated/packages/js/generators/init.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
{
22
"name": "init",
3-
"factory": "./src/generators/init/init#initGenerator",
3+
"factory": "./src/generators/init/init#initGeneratorInternal",
44
"schema": {
55
"$schema": "https://json-schema.org/schema",
66
"$id": "NxTypescriptInit",
77
"cli": "nx",
88
"title": "Init nx/js",
99
"description": "Init generator placeholder for nx/js.",
1010
"properties": {
11+
"formatter": {
12+
"description": "The tool to use for code formatting.",
13+
"type": "string",
14+
"enum": ["none", "prettier"],
15+
"default": "none"
16+
},
1117
"js": {
1218
"type": "boolean",
1319
"default": false,
@@ -40,12 +46,6 @@
4046
"type": "string",
4147
"description": "Customize the generated base tsconfig file name.",
4248
"x-priority": "internal"
43-
},
44-
"setUpPrettier": {
45-
"type": "boolean",
46-
"description": "Add Prettier and corresponding configuration files.",
47-
"x-priority": "internal",
48-
"default": false
4949
}
5050
},
5151
"presets": []
@@ -54,7 +54,7 @@
5454
"x-type": "init",
5555
"description": "Initialize a TS/JS workspace.",
5656
"hidden": true,
57-
"implementation": "/packages/js/src/generators/init/init#initGenerator.ts",
57+
"implementation": "/packages/js/src/generators/init/init#initGeneratorInternal.ts",
5858
"path": "/packages/js/src/generators/init/schema.json",
5959
"type": "generator"
6060
}

docs/generated/packages/js/generators/library.json

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,28 @@
2121
"description": "A directory where the lib is placed.",
2222
"x-priority": "important"
2323
},
24-
"projectNameAndRootFormat": {
25-
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
24+
"bundler": {
25+
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
2626
"type": "string",
27-
"enum": ["as-provided", "derived"]
27+
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
28+
"x-priority": "important"
2829
},
2930
"linter": {
3031
"description": "The tool to use for running lint checks.",
3132
"type": "string",
32-
"enum": ["eslint", "none"],
33-
"default": "eslint"
33+
"enum": ["none", "eslint"],
34+
"x-priority": "important"
3435
},
3536
"unitTestRunner": {
36-
"type": "string",
37-
"enum": ["jest", "vitest", "none"],
3837
"description": "Test runner to use for unit tests.",
39-
"x-prompt": "Which unit test runner would you like to use?"
38+
"type": "string",
39+
"enum": ["none", "jest", "vitest"],
40+
"x-priority": "important"
41+
},
42+
"projectNameAndRootFormat": {
43+
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
44+
"type": "string",
45+
"enum": ["as-provided", "derived"]
4046
},
4147
"tags": {
4248
"type": "string",
@@ -112,18 +118,9 @@
112118
"compiler": {
113119
"type": "string",
114120
"enum": ["tsc", "swc"],
115-
"default": "tsc",
116121
"description": "The compiler used by the build and test targets",
117122
"x-deprecated": "Use the `bundler` option for greater control (swc, tsc, rollup, vite, esbuild, none)."
118123
},
119-
"bundler": {
120-
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
121-
"type": "string",
122-
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
123-
"default": "tsc",
124-
"x-prompt": "Which bundler would you like to use to build the library? Choose 'none' to skip build setup.",
125-
"x-priority": "important"
126-
},
127124
"skipTypeCheck": {
128125
"type": "boolean",
129126
"description": "Whether to skip TypeScript type checking for SWC compiler.",
@@ -138,6 +135,10 @@
138135
"description": "Don't include the directory in the generated file name.",
139136
"type": "boolean",
140137
"default": false
138+
},
139+
"useProjectJson": {
140+
"type": "boolean",
141+
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
141142
}
142143
},
143144
"required": ["name"],

docs/generated/packages/workspace/generators/new.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
"prefix": {
8484
"description": "The prefix to use for Angular component and directive selectors.",
8585
"type": "string"
86+
},
87+
"formatter": {
88+
"description": "The tool to use for code formatting.",
89+
"type": "string",
90+
"enum": ["none", "prettier"],
91+
"default": "none"
8692
}
8793
},
8894
"additionalProperties": true,

e2e/eslint/src/linter-legacy.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Linter (legacy)', () => {
3333
env: { NX_ADD_PLUGINS: 'false' },
3434
}
3535
);
36-
runCLI(`generate @nx/js:lib ${mylib} --directory=apps/${mylib}`, {
36+
runCLI(`generate @nx/js:lib ${mylib} --directory=libs/${mylib}`, {
3737
env: { NX_ADD_PLUGINS: 'false' },
3838
});
3939
});

packages/angular/src/generators/library/library.spec.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,34 +1212,34 @@ describe('lib', () => {
12121212
12131213
module.exports = [
12141214
...baseConfig,
1215-
...nx.configs["flat/angular"],
1216-
...nx.configs["flat/angular-template"],
1217-
{
1218-
files: ["**/*.ts"],
1219-
rules: {
1220-
"@angular-eslint/directive-selector": [
1221-
"error",
1222-
{
1223-
type: "attribute",
1224-
prefix: "lib",
1225-
style: "camelCase"
1226-
}
1227-
],
1228-
"@angular-eslint/component-selector": [
1229-
"error",
1230-
{
1231-
type: "element",
1232-
prefix: "lib",
1233-
style: "kebab-case"
1234-
}
1235-
]
1215+
...nx.configs["flat/angular"],
1216+
...nx.configs["flat/angular-template"],
1217+
{
1218+
files: ["**/*.ts"],
1219+
rules: {
1220+
"@angular-eslint/directive-selector": [
1221+
"error",
1222+
{
1223+
type: "attribute",
1224+
prefix: "lib",
1225+
style: "camelCase"
1226+
}
1227+
],
1228+
"@angular-eslint/component-selector": [
1229+
"error",
1230+
{
1231+
type: "element",
1232+
prefix: "lib",
1233+
style: "kebab-case"
1234+
}
1235+
]
1236+
}
1237+
},
1238+
{
1239+
files: ["**/*.html"],
1240+
// Override or add rules here
1241+
rules: {}
12361242
}
1237-
},
1238-
{
1239-
files: ["**/*.html"],
1240-
// Override or add rules here
1241-
rules: {}
1242-
}
12431243
];
12441244
"
12451245
`);

packages/create-nx-workspace/bin/create-nx-workspace.ts

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ interface BaseArguments extends CreateWorkspaceOptions {
3737

3838
interface NoneArguments extends BaseArguments {
3939
stack: 'none';
40-
workspaceType: 'package-based' | 'integrated' | 'standalone';
41-
js: boolean;
42-
appName: string | undefined;
40+
workspaceType?: 'package-based' | 'integrated' | 'standalone';
41+
js?: boolean;
42+
appName?: string | undefined;
43+
formatter?: 'none' | 'prettier';
4344
}
4445

4546
interface ReactArguments extends BaseArguments {
@@ -394,7 +395,11 @@ async function determineStack(
394395
choices: [
395396
{
396397
name: `none`,
397-
message: `None: Configures a TypeScript/JavaScript project with minimal structure.`,
398+
message:
399+
process.env.NX_ADD_PLUGINS !== 'false' &&
400+
process.env.NX_ADD_TS_PLUGIN === 'true'
401+
? `None: Configures a TypeScript/JavaScript monorepo.`
402+
: `None: Configures a TypeScript/JavaScript project with minimal structure.`,
398403
},
399404
{
400405
name: `react`,
@@ -441,34 +446,14 @@ async function determinePresetOptions(
441446
async function determineNoneOptions(
442447
parsedArgs: yargs.Arguments<NoneArguments>
443448
): Promise<Partial<NoneArguments>> {
444-
let preset: Preset;
445-
let workspaceType: 'package-based' | 'standalone' | 'integrated' | undefined =
446-
undefined;
447-
let appName: string | undefined = undefined;
448-
let js: boolean | undefined;
449-
450-
if (parsedArgs.preset) {
451-
preset = parsedArgs.preset;
452-
} else {
453-
workspaceType = await determinePackageBasedOrIntegratedOrStandalone();
454-
if (workspaceType === 'standalone') {
455-
preset = Preset.TsStandalone;
456-
} else if (workspaceType === 'integrated') {
457-
preset = Preset.Apps;
458-
} else {
459-
preset = Preset.NPM;
460-
}
461-
}
462-
463-
if (parsedArgs.js !== undefined) {
464-
js = parsedArgs.js;
465-
} else if (preset === Preset.TsStandalone) {
466-
// Only standalone TS preset generates a default package, so we need to provide --js and --appName options.
467-
appName = parsedArgs.name;
468-
const reply = await enquirer.prompt<{ ts: 'Yes' | 'No' }>([
449+
if (
450+
process.env.NX_ADD_PLUGINS !== 'false' &&
451+
process.env.NX_ADD_TS_PLUGIN === 'true'
452+
) {
453+
const reply = await enquirer.prompt<{ prettier: 'Yes' | 'No' }>([
469454
{
470-
name: 'ts',
471-
message: `Would you like to use TypeScript with this project?`,
455+
name: 'prettier',
456+
message: `Would you like to use Prettier for code formatting?`,
472457
type: 'autocomplete',
473458
choices: [
474459
{
@@ -478,14 +463,68 @@ async function determineNoneOptions(
478463
name: 'No',
479464
},
480465
],
481-
initial: 0,
466+
initial: 1,
482467
skip: !parsedArgs.interactive || isCI(),
483468
},
484469
]);
485-
js = reply.ts === 'No';
486-
}
470+
return {
471+
preset: Preset.TS,
472+
formatter: reply.prettier === 'Yes' ? 'prettier' : 'none',
473+
};
474+
} else {
475+
let preset: Preset;
476+
let workspaceType:
477+
| 'package-based'
478+
| 'standalone'
479+
| 'integrated'
480+
| undefined = undefined;
481+
let appName: string | undefined = undefined;
482+
let js: boolean | undefined;
483+
484+
if (parsedArgs.preset) {
485+
preset = parsedArgs.preset;
486+
} else {
487+
workspaceType = await determinePackageBasedOrIntegratedOrStandalone();
488+
if (workspaceType === 'standalone') {
489+
preset = Preset.TsStandalone;
490+
} else if (workspaceType === 'integrated') {
491+
preset = Preset.Apps;
492+
} else {
493+
preset = Preset.NPM;
494+
}
495+
}
496+
497+
if (preset === Preset.TS) {
498+
return { preset, formatter: 'prettier' };
499+
}
487500

488-
return { preset, js, appName };
501+
if (parsedArgs.js !== undefined) {
502+
js = parsedArgs.js;
503+
} else if (preset === Preset.TsStandalone) {
504+
// Only standalone TS preset generates a default package, so we need to provide --js and --appName options.
505+
appName = parsedArgs.name;
506+
const reply = await enquirer.prompt<{ ts: 'Yes' | 'No' }>([
507+
{
508+
name: 'ts',
509+
message: `Would you like to use TypeScript with this project?`,
510+
type: 'autocomplete',
511+
choices: [
512+
{
513+
name: 'Yes',
514+
},
515+
{
516+
name: 'No',
517+
},
518+
],
519+
initial: 0,
520+
skip: !parsedArgs.interactive || isCI(),
521+
},
522+
]);
523+
js = reply.ts === 'No';
524+
}
525+
526+
return { preset, js, appName };
527+
}
489528
}
490529

491530
async function determineReactOptions(

0 commit comments

Comments
 (0)