The Workspace plugin contains executors and generators that are useful for any Nx workspace and serves as a foundation for other plugins.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Support for ESLint integration and linter configuration management. These utilities provide standardized linter type definitions for Nx workspace tooling.
Standardized linter types for workspace configuration (deprecated enum, use type instead).
/**
* @deprecated Use LinterType instead
* Enumeration of supported linter types
*/
enum Linter {
/** ESLint linter configuration */
EsLint = 'eslint',
/** No linter configuration */
None = 'none'
}
/**
* Modern type definition for linter options
*/
type LinterType = 'eslint' | 'none';Usage Examples:
import { Linter, LinterType } from "@nx/workspace";
// Using deprecated enum (still functional)
function setupLinterWithEnum(linter: Linter) {
switch (linter) {
case Linter.EsLint:
console.log("Setting up ESLint configuration");
break;
case Linter.None:
console.log("No linter configuration");
break;
}
}
// Using modern type (recommended)
function setupLinterWithType(linter: LinterType) {
switch (linter) {
case 'eslint':
console.log("Setting up ESLint configuration");
break;
case 'none':
console.log("No linter configuration");
break;
}
}
// Generator usage
setupLinterWithEnum(Linter.EsLint);
setupLinterWithType('eslint');Linter types are commonly used in generator schemas for project creation:
import { LinterType } from "@nx/workspace";
interface ProjectGeneratorSchema {
name: string;
directory?: string;
linter: LinterType;
skipFormat?: boolean;
}
function generateProject(schema: ProjectGeneratorSchema) {
console.log(`Creating project with ${schema.linter} linter`);
if (schema.linter === 'eslint') {
// Setup ESLint configuration
setupEslintConfig(schema.name);
}
}import { Tree } from "@nx/devkit";
import { LinterType } from "@nx/workspace";
function addLinterConfiguration(
tree: Tree,
projectRoot: string,
linter: LinterType
): void {
if (linter === 'eslint') {
// Create .eslintrc.json
const eslintConfig = {
extends: ["../../.eslintrc.json"],
ignorePatterns: ["!**/*"],
overrides: [
{
files: ["*.ts", "*.tsx", "*.js", "*.jsx"],
rules: {}
}
]
};
tree.write(
`${projectRoot}/.eslintrc.json`,
JSON.stringify(eslintConfig, null, 2)
);
console.log("ESLint configuration created");
} else {
console.log("No linter configuration requested");
}
}When using ESLint in an Nx workspace, the root configuration typically includes:
{
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nx"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"extends": ["@nx/eslint-plugin-nx/recommended"],
"rules": {}
}
]
}Individual projects extend the root configuration:
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"extends": [
"@nx/eslint-plugin-nx/typescript"
],
"rules": {}
}
]
}import { Tree } from "@nx/devkit";
import { LinterType } from "@nx/workspace";
interface LinterOptions {
linter: LinterType;
strict?: boolean;
includePrettier?: boolean;
}
function setupAdvancedLinter(
tree: Tree,
projectRoot: string,
options: LinterOptions
): void {
if (options.linter === 'none') {
console.log("Skipping linter setup");
return;
}
const eslintConfig: any = {
extends: ["../../.eslintrc.json"],
ignorePatterns: ["!**/*"],
overrides: [
{
files: ["*.ts", "*.tsx", "*.js", "*.jsx"],
rules: {}
}
]
};
// Add strict rules if requested
if (options.strict) {
eslintConfig.overrides[0].extends = [
"@nx/eslint-plugin-nx/typescript"
];
eslintConfig.overrides[0].rules = {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "error"
};
}
// Add Prettier integration
if (options.includePrettier) {
eslintConfig.extends.push("prettier");
}
tree.write(
`${projectRoot}/.eslintrc.json`,
JSON.stringify(eslintConfig, null, 2)
);
}import { LinterType } from "@nx/workspace";
function isValidLinterType(value: string): value is LinterType {
return value === 'eslint' || value === 'none';
}
function validateLinterOptions(options: any): LinterType {
if (!options.linter) {
return 'eslint'; // Default to ESLint
}
if (!isValidLinterType(options.linter)) {
throw new Error(`Invalid linter type: ${options.linter}. Must be 'eslint' or 'none'.`);
}
return options.linter;
}
// Usage in generators
function createProjectWithValidation(options: any) {
const linter = validateLinterOptions(options);
console.log(`Using linter: ${linter}`);
}import { Linter, LinterType } from "@nx/workspace";
// Migration helper function
function migrateLinterEnum(oldLinter: Linter): LinterType {
switch (oldLinter) {
case Linter.EsLint:
return 'eslint';
case Linter.None:
return 'none';
default:
return 'eslint';
}
}
// Usage during migration
function migrateOldConfiguration(oldConfig: { linter: Linter }) {
const newConfig = {
...oldConfig,
linter: migrateLinterEnum(oldConfig.linter)
};
return newConfig;
}When ESLint is selected, projects typically get a lint target:
{
"targets": {
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/my-app/**/*.{ts,tsx,js,jsx}"]
}
}
}
}import { Tree, updateProjectConfiguration, readProjectConfiguration } from "@nx/devkit";
import { LinterType } from "@nx/workspace";
function addLintTarget(
tree: Tree,
projectName: string,
linter: LinterType,
lintFilePatterns: string[]
): void {
if (linter === 'none') {
return; // Skip target creation
}
const projectConfig = readProjectConfiguration(tree, projectName);
projectConfig.targets = projectConfig.targets || {};
projectConfig.targets.lint = {
executor: "@nx/linter:eslint",
outputs: ["{options.outputFile}"],
options: {
lintFilePatterns
}
};
updateProjectConfiguration(tree, projectName, projectConfig);
}/**
* @deprecated Use LinterType instead
*/
enum Linter {
EsLint = 'eslint',
None = 'none'
}
/**
* Modern linter type definition
*/
type LinterType = 'eslint' | 'none';
interface LinterOptions {
linter: LinterType;
strict?: boolean;
includePrettier?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-nx--workspace