Skip to content

Commit

Permalink
feat(js): generate experimental simplified library with ts solution s…
Browse files Browse the repository at this point in the history
…etup
  • Loading branch information
leosvelperez committed Sep 18, 2024
1 parent eb61254 commit 9f7b8a6
Show file tree
Hide file tree
Showing 58 changed files with 2,002 additions and 686 deletions.
4 changes: 2 additions & 2 deletions docs/generated/packages/js/generators/init.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "init",
"factory": "./src/generators/init/init#initGenerator",
"factory": "./src/generators/init/init#initGeneratorInternal",
"schema": {
"$schema": "https://json-schema.org/schema",
"$id": "NxTypescriptInit",
Expand Down Expand Up @@ -54,7 +54,7 @@
"x-type": "init",
"description": "Initialize a TS/JS workspace.",
"hidden": true,
"implementation": "/packages/js/src/generators/init/init#initGenerator.ts",
"implementation": "/packages/js/src/generators/init/init#initGeneratorInternal.ts",
"path": "/packages/js/src/generators/init/schema.json",
"type": "generator"
}
43 changes: 26 additions & 17 deletions docs/generated/packages/js/generators/library.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,32 @@
"description": "A directory where the lib is placed.",
"x-priority": "important"
},
"projectNameAndRootFormat": {
"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`).",
"bundler": {
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
"type": "string",
"enum": ["as-provided", "derived"]
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
"x-priority": "important"
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint", "none"],
"default": "eslint"
"enum": ["none", "eslint"],
"default": "none",
"x-prompt": "Which linter would you like to use?",
"x-priority": "important"
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?"
"type": "string",
"enum": ["none", "jest", "vitest"],
"default": "none",
"x-prompt": "Which unit test runner would you like to use?",
"x-priority": "important"
},
"projectNameAndRootFormat": {
"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`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"tags": {
"type": "string",
Expand Down Expand Up @@ -118,18 +128,9 @@
"compiler": {
"type": "string",
"enum": ["tsc", "swc"],
"default": "tsc",
"description": "The compiler used by the build and test targets",
"x-deprecated": "Use the `bundler` option for greater control (swc, tsc, rollup, vite, esbuild, none)."
},
"bundler": {
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
"type": "string",
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
"default": "tsc",
"x-prompt": "Which bundler would you like to use to build the library? Choose 'none' to skip build setup.",
"x-priority": "important"
},
"skipTypeCheck": {
"type": "boolean",
"description": "Whether to skip TypeScript type checking for SWC compiler.",
Expand All @@ -144,6 +145,14 @@
"description": "Don't include the directory in the generated file name.",
"type": "boolean",
"default": false
},
"useProjectJson": {
"type": "boolean",
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
},
"setUpPrettier": {
"description": "Set up prettier configuration in the workspace if not already set up.",
"type": "boolean"
}
},
"required": ["name"],
Expand Down
6 changes: 6 additions & 0 deletions docs/generated/packages/vite/generators/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
"type": "string",
"enum": ["node", "jsdom", "happy-dom", "edge-runtime"],
"default": "jsdom"
},
"setUpPrettier": {
"type": "boolean",
"description": "Add Prettier and corresponding configuration files.",
"x-priority": "internal",
"default": false
}
},
"examplesFile": "---\ntitle: Examples for the Vite configuration generator\ndescription: This page contains examples for the Vite @nx/vite:configuration generator, which helps you set up Vite on your Nx workspace, or convert an existing project to use Vite.\n---\n\nThis generator is used for converting an existing React or Web project to use [Vite.js](https://vitejs.dev/).\n\nIt will create a `vite.config.ts` file at the root of your project with the correct settings, or if there's already a `vite.config.ts` file, it will modify it to include the correct settings.\n\n{% callout type=\"caution\" title=\"Your code will be modified!\" %}\nThis generator will modify your code, so make sure to commit your changes before running it.\n{% /callout %}\n\n```bash\nnx g @nx/vite:configuration\n```\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `project`, as the name of the project you want to generate the configuration for.\n- The `uiFramework` you want to use. Supported values are: `react` and `none`.\n\nYou must provide a `project` and a `uiFramework` for the generator to work.\n\nYou may also pass the `includeVitest` flag. This will also configure your project for testing with [Vitest](https://vitest.dev/), by adding the `test` configuration in your `vite.config.ts` file.\n\n## How to use\n\nIf you have an existing project that does not use Vite, you may want to convert it to use Vite. This can be a `webpack` project, a buildable JS library that uses the `@nx/js:babel`, the `@nx/js:swc` or the `@nx/rollup:rollup` executor, or even a non-buildable library.\nBy default, the `@nx/vite:configuration` generator will search your project to find the relevant configuration (either a `webpack.config.ts` file for example, or the `@nx/js` executors). If it determines that your project can be converted, then Nx will generate the configuration for you. If it cannot determine that your project can be converted, it will ask you if you want to convert it anyway or throw an error if it determines that it cannot be converted.\n\nYou can then test on your own if the result works or not, and modify the configuration as needed. It's suggested that you commit your changes before running the generator, so you can revert the changes if needed.\n\n## Projects that can be converted to use the `@nx/vite` executors\n\nUsually, React and Web projects generated with the `@nx/react` and the `@nx/web` generators can be converted to use the `@nx/vite` executors without any issues.\n\nThe list of executors for building, testing and serving that can be converted to use the `@nx/vite` executors is:\n\n### Supported `build` executors\n\n- `@nxext/vite:build`\n- `@nx/js:babel`\n- `@nx/js:swc`\n- `@nx/rollup:rollup`\n- `@nx/webpack:webpack`\n- `@nx/web:rollup`\n\n### Unsupported executors\n\n- `@nx/angular:ng-packagr-lite`\n- `@nx/angular:package`\n- `@nx/angular:webpack-browser`\n- `@angular-devkit/build-angular:browser`\n- `@angular-devkit/build-angular:dev-server`\n- `@nx/esbuild:esbuild`\n- `@nx/react-native:start`\n- `@nx/next:build`\n- `@nx/next:server`\n- `@nx/js:tsc`\n- any executor _not_ listed in the lists of \"supported executors\"\n- any project that does _not_ have a target for building, serving or testing\n\nWe **cannot** guarantee that projects using unsupported executors - _or any executor that is NOT listed in the list of \"supported executors\"_ - for either building, testing or serving will work correctly when converted to use Vite.\n\nYou can read more in the [Vite package overview page](/nx-api/vite).\n\n## Examples\n\n### Convert a React app to use Vite\n\n```bash\nnx g @nx/vite:configuration --project=my-react-app --uiFramework=react --includeVitest\n```\n\nThis will configure the `my-react-app` project to use Vite.\n\n### Convert a Web app to use Vite\n\n```bash\nnx g @nx/vite:configuration --project=my-web-app --uiFramework=none --includeVitest\n```\n\nThis will configure the `my-web-app` project to use Vite.\n",
Expand Down
6 changes: 6 additions & 0 deletions docs/generated/packages/vite/generators/vitest.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
"description": "The vitest environment to use. See https://vitest.dev/config/#environment.",
"type": "string",
"enum": ["node", "jsdom", "happy-dom", "edge-runtime"]
},
"setUpPrettier": {
"type": "boolean",
"description": "Add Prettier and corresponding configuration files.",
"x-priority": "internal",
"default": false
}
},
"required": ["project"],
Expand Down
1 change: 0 additions & 1 deletion e2e/esbuild/src/esbuild.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ describe('EsBuild Plugin', () => {
expect(
readJson(`dist/libs/${parentLib}/package.json`).dependencies
).toEqual({
'jsonc-eslint-parser': expect.any(String),
// Don't care about the versions, just that they exist
rambda: expect.any(String),
lodash: expect.any(String),
Expand Down
8 changes: 4 additions & 4 deletions e2e/eslint/src/linter-legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Linter (legacy)', () => {
runCLI(`generate @nx/react:app ${myapp} --tags=validtag`, {
env: { NX_ADD_PLUGINS: 'false' },
});
runCLI(`generate @nx/js:lib ${mylib}`, {
runCLI(`generate @nx/js:lib ${mylib} --linter=eslint`, {
env: { NX_ADD_PLUGINS: 'false' },
});
});
Expand Down Expand Up @@ -136,13 +136,13 @@ describe('Linter (legacy)', () => {
e2eTestRunner: 'none',
});
runCLI(
`generate @nx/js:lib ${mylib} --directory libs/${mylib} --projectNameAndRootFormat as-provided`,
`generate @nx/js:lib ${mylib} --directory libs/${mylib} --linter=eslint --projectNameAndRootFormat as-provided`,
{
env: { NX_ADD_PLUGINS: 'false' },
}
);
runCLI(
`generate @nx/js:lib ${mylib2} --directory libs/${mylib2} --projectNameAndRootFormat as-provided`,
`generate @nx/js:lib ${mylib2} --directory libs/${mylib2} --linter=eslint --projectNameAndRootFormat as-provided`,
{
env: { NX_ADD_PLUGINS: 'false' },
}
Expand Down Expand Up @@ -196,7 +196,7 @@ describe('Linter (legacy)', () => {
bundler: 'vite',
e2eTestRunner: 'none',
});
runCLI(`generate @nx/js:lib ${mylib}`, {
runCLI(`generate @nx/js:lib ${mylib} --linter=eslint`, {
env: { NX_ADD_PLUGINS: 'false' },
});

Expand Down
26 changes: 16 additions & 10 deletions e2e/eslint/src/linter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Linter', () => {
packages: ['@nx/react', '@nx/js', '@nx/eslint'],
});
runCLI(`generate @nx/react:app ${myapp} --tags=validtag`);
runCLI(`generate @nx/js:lib ${mylib}`);
runCLI(`generate @nx/js:lib ${mylib} --linter=eslint`);
});
afterAll(() => cleanupProject());

Expand Down Expand Up @@ -211,8 +211,12 @@ describe('Linter', () => {

runCLI(`generate @nx/react:app ${myapp2}`);
runCLI(`generate @nx/react:lib ${lazylib}`);
runCLI(`generate @nx/js:lib ${invalidtaglib} --tags=invalidtag`);
runCLI(`generate @nx/js:lib ${validtaglib} --tags=validtag`);
runCLI(
`generate @nx/js:lib ${invalidtaglib} --linter=eslint --tags=invalidtag`
);
runCLI(
`generate @nx/js:lib ${validtaglib} --linter=eslint --tags=validtag`
);

const eslint = readJson('.eslintrc.json');
eslint.overrides[0].rules[
Expand Down Expand Up @@ -274,9 +278,9 @@ describe('Linter', () => {

beforeAll(() => {
// make these libs non-buildable to avoid dep-checks triggering lint errors
runCLI(`generate @nx/js:lib ${libA} --bundler=none`);
runCLI(`generate @nx/js:lib ${libB} --bundler=none`);
runCLI(`generate @nx/js:lib ${libC} --bundler=none`);
runCLI(`generate @nx/js:lib ${libA} --linter=eslint --bundler=none`);
runCLI(`generate @nx/js:lib ${libB} --linter=eslint --bundler=none`);
runCLI(`generate @nx/js:lib ${libC} --linter=eslint --bundler=none`);

/**
* create tslib-a structure
Expand Down Expand Up @@ -594,7 +598,7 @@ describe('Linter', () => {
`generate @nx/react:lib ${reactLib} --directory=${reactLib} --projectNameAndRootFormat=as-provided`
);
runCLI(
`generate @nx/js:lib ${jsLib} --directory=${jsLib} --projectNameAndRootFormat=as-provided`
`generate @nx/js:lib ${jsLib} --directory=${jsLib} --linter=eslint --projectNameAndRootFormat=as-provided`
);

checkFilesExist(
Expand Down Expand Up @@ -686,7 +690,9 @@ describe('Linter', () => {
let e2eOverrides = JSON.stringify(e2eEslint.overrides);
expect(e2eOverrides).toContain('plugin:@nx/javascript');

runCLI(`generate @nx/js:lib ${mylib} --unitTestRunner=jest`);
runCLI(
`generate @nx/js:lib ${mylib} --linter=eslint --unitTestRunner=jest`
);
verifySuccessfulMigratedSetup(myapp, mylib);

appEslint = readJson(`.eslintrc.json`);
Expand Down Expand Up @@ -719,7 +725,7 @@ describe('Linter', () => {
let e2eOverrides = JSON.stringify(e2eEslint.overrides);
expect(e2eOverrides).toContain('plugin:@nx/javascript');

runCLI(`generate @nx/js:lib ${mylib} --no-interactive`);
runCLI(`generate @nx/js:lib ${mylib} --linter=eslint --no-interactive`);
verifySuccessfulMigratedSetup(myapp, mylib);

appEslint = readJson(`.eslintrc.json`);
Expand Down Expand Up @@ -752,7 +758,7 @@ describe('Linter', () => {
expect(e2eOverrides).toContain('plugin:@nx/javascript');
expect(e2eOverrides).toContain('plugin:@nx/typescript');

runCLI(`generate @nx/js:lib ${mylib} --no-interactive`);
runCLI(`generate @nx/js:lib ${mylib} --linter=eslint --no-interactive`);
verifySuccessfulMigratedSetup(myapp, mylib);

appEslint = readJson(`.eslintrc.json`);
Expand Down
4 changes: 3 additions & 1 deletion e2e/js/src/js-executor-tsc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ describe('js:tsc executor', () => {
libBuildProcess.kill();

const parentLib = uniq('parentlib');
runCLI(`generate @nx/js:lib ${parentLib} --bundler=tsc --no-interactive`);
runCLI(
`generate @nx/js:lib ${parentLib} --bundler=tsc --unitTestRunner=jest --no-interactive`
);
const parentLibPackageJson = readJson(`libs/${parentLib}/package.json`);
expect(parentLibPackageJson.scripts).toBeUndefined();
expect((await runCLIAsync(`test ${parentLib}`)).combinedOutput).toContain(
Expand Down
10 changes: 0 additions & 10 deletions e2e/js/src/js-packaging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,6 @@ describe('packaging libs', () => {
`libs/${swcEsmLib}/src/index.ts`,
`export * from './lib/${swcEsmLib}.js';`
);
// We also need to update the eslint config file extensions to be explicitly commonjs
// TODO: re-evaluate this once we support ESM eslint configs
renameFile(
`libs/${tscEsmLib}/eslint.config.js`,
`libs/${tscEsmLib}/eslint.config.cjs`
);
renameFile(
`libs/${swcEsmLib}/eslint.config.js`,
`libs/${swcEsmLib}/eslint.config.cjs`
);

// Add additional entry points for `exports` field
updateJson(join('libs', tscLib, 'project.json'), (json) => {
Expand Down
4 changes: 2 additions & 2 deletions e2e/nx/src/affected-graph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ describe('Nx Affected and Graph Tests', () => {
const mypublishablelib = uniq('mypublishablelib');
runCLI(`generate @nx/web:app ${myapp}`);
runCLI(`generate @nx/web:app ${myapp2}`);
runCLI(`generate @nx/js:lib ${mylib}`);
runCLI(`generate @nx/js:lib ${mylib} --unitTestRunner=jest`);
runCLI(`generate @nx/js:lib ${mylib2}`);
runCLI(
`generate @nx/js:lib ${mypublishablelib} --publishable --importPath=@${proj}/${mypublishablelib} --tags=ui`
`generate @nx/js:lib ${mypublishablelib} --publishable --importPath=@${proj}/${mypublishablelib} --unitTestRunner=jest --tags=ui`
);

updateFile(
Expand Down
6 changes: 3 additions & 3 deletions e2e/nx/src/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,9 @@ describe('cache', () => {
const parent = uniq('parent');
const child1 = uniq('child1');
const child2 = uniq('child2');
runCLI(`generate @nx/js:lib ${parent}`);
runCLI(`generate @nx/js:lib ${child1}`);
runCLI(`generate @nx/js:lib ${child2}`);
runCLI(`generate @nx/js:lib ${parent} --unitTestRunner=jest`);
runCLI(`generate @nx/js:lib ${child1} --unitTestRunner=jest`);
runCLI(`generate @nx/js:lib ${child2} --unitTestRunner=jest`);
updateJson(`nx.json`, (c) => {
c.namedInputs = {
default: ['{projectRoot}/**/*'],
Expand Down
8 changes: 6 additions & 2 deletions e2e/nx/src/extras.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,9 @@ NX_USERNAME=$FIRSTNAME $LASTNAME`

const baseLib = 'lib-base-123';
beforeAll(() => {
runCLI(`generate @nx/js:lib ${baseLib}`);
runCLI(
`generate @nx/js:lib ${baseLib} --linter=eslint --unitTestRunner=jest`
);
});

it('should correctly expand default task inputs', () => {
Expand All @@ -387,7 +389,9 @@ NX_USERNAME=$FIRSTNAME $LASTNAME`

it('should correctly expand dependent task inputs', () => {
const dependentLib = 'lib-dependent-123';
runCLI(`generate @nx/js:lib ${dependentLib}`);
runCLI(
`generate @nx/js:lib ${dependentLib} --linter=eslint --unitTestRunner=jest`
);

updateJson(join('libs', baseLib, 'project.json'), (config) => {
config.targets['build'].inputs = ['default', '^default'];
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint/src/generators/lint-project/lint-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ export async function lintProjectGeneratorInternal(
(p) => !['./src', '{projectRoot}', projectConfig.root].includes(p)
)
) {
projectConfig.targets ??= {};
projectConfig.targets['lint'] = {
command: `eslint ${lintFilePatterns
.join(' ')
.replace('{projectRoot}', projectConfig.root)}`,
};
}
} else {
projectConfig.targets ??= {};
projectConfig.targets['lint'] = {
executor: '@nx/eslint:lint',
};
Expand Down
2 changes: 1 addition & 1 deletion packages/js/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"description": "Create a library"
},
"init": {
"factory": "./src/generators/init/init#initGenerator",
"factory": "./src/generators/init/init#initGeneratorInternal",
"schema": "./src/generators/init/schema.json",
"aliases": ["lib"],
"x-type": "init",
Expand Down
2 changes: 2 additions & 0 deletions packages/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@
"@babel/runtime": "^7.22.6",
"@nx/devkit": "file:../devkit",
"@nx/workspace": "file:../workspace",
"@zkochan/js-yaml": "0.0.7",
"babel-plugin-const-enum": "^1.0.1",
"babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-typescript-metadata": "^0.3.1",
"chalk": "^4.1.0",
"columnify": "^1.6.0",
"detect-port": "^1.5.1",
"enquirer": "~2.3.6",
"fast-glob": "3.2.7",
"ignore": "^5.0.4",
"js-tokens": "^4.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'nx/src/internal-testing-utils/mock-project-graph';
import { readProjectConfiguration, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { join } from 'path';
import { LibraryGeneratorSchema } from '../../utils/schema';
import { LibraryGeneratorSchema } from '../library/schema';
import { libraryGenerator as jsLibraryGenerator } from '../library/library';
import { convertToSwcGenerator } from './convert-to-swc';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"compilerOptions": {
"allowJs": false,
"allowSyntheticDefaultImports": true,
"composite": true,
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"emitDecoratorMetadata": false,
"esModuleInterop": true,
"experimentalDecorators": false,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"isolatedModules": true,
"lib": ["es2022"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"pretty": true,
"removeComments": false,
"resolveJsonModule": false,
"skipDefaultLibCheck": false,
"skipLibCheck": true,
"sourceMap": false,
"strict": true,
"target": "es2022",
"verbatimModuleSyntax": false
}
}
Loading

0 comments on commit 9f7b8a6

Please sign in to comment.