Browse Source
* feat(nx): add basic-lib generator for streamlined library creation This adds a new nx-plugin library with a generator for creating "common" type Bitwarden libs. It is set up to accept a lib name, description, team, and directory. It then - Creates a folder in the directory (default to libs) - Sets up complete library scaffolding: - README with team ownership - Build, lint and test task configuration - Test infrastructure - Configures TypeScript path mapping - Updates CODEOWNERS with team ownership - Runs npm i This will make library creation more consistent and reduce manual boilerplate setup. The plugin design itself was generated by `npx nx g plugin`. This means we used a plugin to generate a plugin that exports generators. To create our generator generator, we first needed a generator. * fix(dirt/card): correct tsconfig path in jest configuration Fix the relative path to tsconfig.base in the dirt/card library's Jest config. The path was incorrectly using four parent directory traversals (../../../../) when only three (../../../) were needed to reach the project root. * chore(codeowners): clarify some nx ownership stuffpull/14722/head
34 changed files with 1273 additions and 578 deletions
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
const nxPreset = require("@nx/jest/preset").default; |
||||
|
||||
module.exports = { ...nxPreset }; |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
# nx-plugin |
||||
|
||||
Owned by: Platform |
||||
|
||||
Custom Nx tools like generators and executors for Bitwarden projects |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
import baseConfig from "../../eslint.config.mjs"; |
||||
|
||||
export default [...baseConfig]; |
||||
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
{ |
||||
"generators": { |
||||
"basic-lib": { |
||||
"factory": "./src/generators/basic-lib", |
||||
"schema": "./src/generators/schema.json", |
||||
"description": "basic-lib generator" |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
export default { |
||||
displayName: "nx-plugin", |
||||
preset: "../../jest.preset.js", |
||||
testEnvironment: "node", |
||||
transform: { |
||||
"^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }], |
||||
}, |
||||
moduleFileExtensions: ["ts", "js", "html"], |
||||
coverageDirectory: "../../coverage/libs/nx-plugin", |
||||
}; |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
{ |
||||
"name": "@bitwarden/nx-plugin", |
||||
"version": "0.0.1", |
||||
"description": "Custom Nx tools like generators and executors for Bitwarden projects", |
||||
"private": true, |
||||
"type": "commonjs", |
||||
"main": "./src/index.js", |
||||
"types": "./src/index.d.ts", |
||||
"license": "GPL-3.0", |
||||
"author": "Platform", |
||||
"generators": "./generators.json" |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
{ |
||||
"name": "nx-plugin", |
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json", |
||||
"sourceRoot": "libs/nx-plugin/src", |
||||
"projectType": "library", |
||||
"tags": [], |
||||
"targets": { |
||||
"build": { |
||||
"executor": "@nx/js:tsc", |
||||
"outputs": ["{options.outputPath}"], |
||||
"options": { |
||||
"outputPath": "dist/libs/nx-plugin", |
||||
"main": "libs/nx-plugin/src/index.ts", |
||||
"tsConfig": "libs/nx-plugin/tsconfig.lib.json", |
||||
"assets": [ |
||||
"libs/nx-plugin/*.md", |
||||
{ |
||||
"input": "./libs/nx-plugin/src", |
||||
"glob": "**/!(*.ts)", |
||||
"output": "./src" |
||||
}, |
||||
{ |
||||
"input": "./libs/nx-plugin/src", |
||||
"glob": "**/*.d.ts", |
||||
"output": "./src" |
||||
}, |
||||
{ |
||||
"input": "./libs/nx-plugin", |
||||
"glob": "generators.json", |
||||
"output": "." |
||||
}, |
||||
{ |
||||
"input": "./libs/nx-plugin", |
||||
"glob": "executors.json", |
||||
"output": "." |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"lint": { |
||||
"executor": "@nx/eslint:lint" |
||||
}, |
||||
"test": { |
||||
"executor": "@nx/jest:jest", |
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], |
||||
"options": { |
||||
"jestConfig": "libs/nx-plugin/jest.config.ts" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
import { Tree, readProjectConfiguration } from "@nx/devkit"; |
||||
import { createTreeWithEmptyWorkspace } from "@nx/devkit/testing"; |
||||
|
||||
import { basicLibGenerator } from "./basic-lib"; |
||||
import { BasicLibGeneratorSchema } from "./schema"; |
||||
|
||||
describe("basic-lib generator", () => { |
||||
let tree: Tree; |
||||
const options: BasicLibGeneratorSchema = { |
||||
name: "test", |
||||
description: "test", |
||||
team: "platform", |
||||
directory: "libs", |
||||
}; |
||||
|
||||
beforeEach(() => { |
||||
tree = createTreeWithEmptyWorkspace(); |
||||
}); |
||||
|
||||
it("should update tsconfig.base.json paths", async () => { |
||||
tree.write("tsconfig.base.json", JSON.stringify({ compilerOptions: { paths: {} } })); |
||||
await basicLibGenerator(tree, options); |
||||
const tsconfigContent = tree.read("tsconfig.base.json"); |
||||
expect(tsconfigContent).not.toBeNull(); |
||||
const tsconfig = JSON.parse(tsconfigContent?.toString() ?? ""); |
||||
expect(tsconfig.compilerOptions.paths[`@bitwarden/${options.name}`]).toEqual([ |
||||
`libs/test/src/index.ts`, |
||||
]); |
||||
}); |
||||
|
||||
it("should update CODEOWNERS file", async () => { |
||||
tree.write(".github/CODEOWNERS", "# Existing content\n"); |
||||
await basicLibGenerator(tree, options); |
||||
const codeownersContent = tree.read(".github/CODEOWNERS"); |
||||
expect(codeownersContent).not.toBeNull(); |
||||
const codeowners = codeownersContent?.toString(); |
||||
expect(codeowners).toContain(`libs/test @bitwarden/team-platform-dev`); |
||||
}); |
||||
|
||||
it("should generate expected files", async () => { |
||||
await basicLibGenerator(tree, options); |
||||
|
||||
const config = readProjectConfiguration(tree, "test"); |
||||
expect(config).toBeDefined(); |
||||
|
||||
expect(tree.exists(`libs/test/README.md`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/eslint.config.mjs`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/jest.config.js`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/package.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.lib.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.spec.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/src/index.ts`)).toBeTruthy(); |
||||
}); |
||||
|
||||
it("should handle missing CODEOWNERS file gracefully", async () => { |
||||
const consoleSpy = jest.spyOn(console, "warn").mockImplementation(); |
||||
await basicLibGenerator(tree, options); |
||||
expect(consoleSpy).toHaveBeenCalledWith("CODEOWNERS file not found at .github/CODEOWNERS"); |
||||
consoleSpy.mockRestore(); |
||||
}); |
||||
|
||||
it("should map team names to correct GitHub handles", async () => { |
||||
tree.write(".github/CODEOWNERS", ""); |
||||
await basicLibGenerator(tree, { ...options, team: "vault" }); |
||||
const codeownersContent = tree.read(".github/CODEOWNERS"); |
||||
expect(codeownersContent).not.toBeNull(); |
||||
const codeowners = codeownersContent?.toString(); |
||||
expect(codeowners).toContain(`libs/test @bitwarden/team-vault-dev`); |
||||
}); |
||||
|
||||
it("should generate expected files", async () => { |
||||
await basicLibGenerator(tree, options); |
||||
expect(tree.exists(`libs/test/README.md`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/eslint.config.mjs`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/jest.config.js`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/package.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/project.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.lib.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/tsconfig.spec.json`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/src/index.ts`)).toBeTruthy(); |
||||
expect(tree.exists(`libs/test/src/test.spec.ts`)).toBeTruthy(); |
||||
}); |
||||
}); |
||||
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
import { execSync } from "child_process"; |
||||
import * as path from "path"; |
||||
|
||||
import { |
||||
formatFiles, |
||||
generateFiles, |
||||
Tree, |
||||
offsetFromRoot, |
||||
updateJson, |
||||
runTasksInSerial, |
||||
GeneratorCallback, |
||||
} from "@nx/devkit"; |
||||
|
||||
import { BasicLibGeneratorSchema } from "./schema"; |
||||
|
||||
/** |
||||
* An Nx generator for creating basic libraries. |
||||
* Generators help automate repetitive tasks like creating new components, libraries, or apps. |
||||
* |
||||
* @param {Tree} tree - The virtual file system tree that Nx uses to make changes |
||||
* @param {BasicLibGeneratorSchema} options - Configuration options for the generator |
||||
* @returns {Promise<void>} - Returns a promise that resolves when generation is complete |
||||
*/ |
||||
export async function basicLibGenerator( |
||||
tree: Tree, |
||||
options: BasicLibGeneratorSchema, |
||||
): Promise<GeneratorCallback> { |
||||
const projectRoot = `${options.directory}/${options.name}`; |
||||
const srcRoot = `${projectRoot}/src`; |
||||
|
||||
/** |
||||
* Generate files from templates in the 'files/' directory. |
||||
* This copies all template files to the new library location. |
||||
*/ |
||||
generateFiles(tree, path.join(__dirname, "files"), projectRoot, { |
||||
...options, |
||||
// `tmpl` is used in file names for template files. Setting it to an
|
||||
// empty string here lets use be explicit with the naming of template
|
||||
// files, and lets Nx handle stripping out "__tmpl__" from file names.
|
||||
tmpl: "", |
||||
// `name` is a variable passed to template files for interpolation into
|
||||
// their contents. It is set to the name of the library being generated.
|
||||
name: options.name, |
||||
root: projectRoot, |
||||
// `offsetFromRoot` is helper to calculate relative path from the new
|
||||
// library to project root.
|
||||
offsetFromRoot: offsetFromRoot(projectRoot), |
||||
}); |
||||
|
||||
// Add TypeScript path to the base tsconfig
|
||||
updateTsConfigPath(tree, options.name, srcRoot); |
||||
|
||||
// Update CODEOWNERS with the new lib
|
||||
updateCodeowners(tree, options.directory, options.name, options.team); |
||||
|
||||
// Format all new files with prettier
|
||||
await formatFiles(tree); |
||||
|
||||
const tasks: GeneratorCallback[] = []; |
||||
// Run npm i after generation. Nx ships a helper function for this called
|
||||
// installPackagesTask. When used here it was leaving package-lock in a
|
||||
// broken state, so a manual approach was used instead.
|
||||
tasks.push(() => { |
||||
execSync("npm install", { stdio: "inherit" }); |
||||
return Promise.resolve(); |
||||
}); |
||||
return runTasksInSerial(...tasks); |
||||
} |
||||
|
||||
/** |
||||
* Updates the base tsconfig.json file to include the new library. |
||||
* This allows importing the library using its alias path. |
||||
* |
||||
* @param {Tree} tree - The virtual file system tree |
||||
* @param {string} name - The library name |
||||
* @param {string} srcRoot - Path to the library's source files |
||||
*/ |
||||
function updateTsConfigPath(tree: Tree, name: string, srcRoot: string) { |
||||
updateJson(tree, "tsconfig.base.json", (json) => { |
||||
const paths = json.compilerOptions.paths || {}; |
||||
|
||||
paths[`@bitwarden/${name}`] = [`${srcRoot}/index.ts`]; |
||||
|
||||
json.compilerOptions.paths = paths; |
||||
return json; |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Updates the CODEOWNERS file to add ownership for the new library |
||||
* |
||||
* @param {Tree} tree - The virtual file system tree |
||||
* @param {string} directory - Directory where the library is created |
||||
* @param {string} name - The library name |
||||
* @param {string} team - The team responsible for the library |
||||
*/ |
||||
function updateCodeowners(tree: Tree, directory: string, name: string, team: string) { |
||||
const codeownersPath = ".github/CODEOWNERS"; |
||||
|
||||
if (!tree.exists(codeownersPath)) { |
||||
console.warn("CODEOWNERS file not found at .github/CODEOWNERS"); |
||||
return; |
||||
} |
||||
|
||||
const teamHandleMap: Record<string, string> = { |
||||
"admin-console": "@bitwarden/team-admin-console-dev", |
||||
auth: "@bitwarden/team-auth-dev", |
||||
autofill: "@bitwarden/team-autofill-dev", |
||||
billing: "@bitwarden/team-billing-dev", |
||||
"data-insights-and-reporting": "@bitwarden/team-data-insights-and-reporting-dev", |
||||
"key-management": "@bitwarden/team-key-management-dev", |
||||
platform: "@bitwarden/team-platform-dev", |
||||
tools: "@bitwarden/team-tools-dev", |
||||
"ui-foundation": "@bitwarden/team-ui-foundation", |
||||
vault: "@bitwarden/team-vault-dev", |
||||
}; |
||||
|
||||
const teamHandle = teamHandleMap[team] || `@bitwarden/team-${team}-dev`; |
||||
const libPath = `${directory}/${name}`; |
||||
|
||||
const newLine = `${libPath} ${teamHandle}\n`; |
||||
|
||||
const content = tree.read(codeownersPath)?.toString() || ""; |
||||
tree.write(codeownersPath, content + newLine); |
||||
} |
||||
|
||||
export default basicLibGenerator; |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
# <%= name %> |
||||
Owned by: <%= team %> |
||||
|
||||
<%= description %> |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
import baseConfig from "<%= offsetFromRoot %>eslint.config.mjs"; |
||||
|
||||
export default [...baseConfig]; |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
module.exports = { |
||||
displayName: '<%= name %>', |
||||
preset: '<%= offsetFromRoot %>jest.preset.js', |
||||
testEnvironment: 'node', |
||||
transform: { |
||||
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }], |
||||
}, |
||||
moduleFileExtensions: ['ts', 'js', 'html'], |
||||
coverageDirectory: '<%= offsetFromRoot %>coverage/libs/<%= name %>', |
||||
}; |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
{ |
||||
"name": "@bitwarden/<%= name %>", |
||||
"version": "0.0.1", |
||||
"description": "<%= description %>", |
||||
"private": true, |
||||
"type": "commonjs", |
||||
"main": "dist/index.js", |
||||
"types": "dist/index.d.ts", |
||||
"license": "GPL-3.0", |
||||
"author": "<%= team %>" |
||||
} |
||||
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
{ |
||||
"name": "<%= name %>", |
||||
"$schema": "<%= offsetFromRoot %>node_modules/nx/schemas/project-schema.json", |
||||
"sourceRoot": "libs/<%= name %>/src", |
||||
"projectType": "library", |
||||
"tags": [], |
||||
"targets": { |
||||
"build": { |
||||
"executor": "@nx/js:tsc", |
||||
"outputs": ["{options.outputPath}"], |
||||
"options": { |
||||
"outputPath": "dist/libs/<%= name %>", |
||||
"main": "libs/<%= name %>/src/index.ts", |
||||
"tsConfig": "libs/<%= name %>/tsconfig.lib.json", |
||||
"assets": ["libs/<%= name%>/*.md"] |
||||
} |
||||
}, |
||||
"lint": { |
||||
"executor": "@nx/eslint:lint", |
||||
"outputs": ["{options.outputFile}"], |
||||
"options": { |
||||
"lintFilePatterns": ["libs/<%= name %>/**/*.ts"] |
||||
} |
||||
}, |
||||
"test": { |
||||
"executor": "@nx/jest:jest", |
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], |
||||
"options": { |
||||
"jestConfig": "libs/<%= name %>/jest.config.js" |
||||
} |
||||
} |
||||
}, |
||||
} |
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
import * as lib from './index'; |
||||
|
||||
describe('<%= name %>', () => { |
||||
// This test will fail until something is exported from index.ts |
||||
it('should work', () => { |
||||
expect(lib).toBeDefined(); |
||||
}); |
||||
}); |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
{ |
||||
"extends": "<%= offsetFromRoot %>tsconfig.base.json", |
||||
"files": [], |
||||
"include": [], |
||||
"references": [ |
||||
{ |
||||
"path": "./tsconfig.lib.json" |
||||
}, |
||||
{ |
||||
"path": "./tsconfig.spec.json" |
||||
} |
||||
] |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc", |
||||
"declaration": true, |
||||
"types": ["node"] |
||||
}, |
||||
"include": ["src/**/*.ts"], |
||||
"exclude": ["jest.config.js", "src/**/*.spec.ts"] |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "<%= offsetFromRoot %>/dist/out-tsc", |
||||
"module": "commonjs", |
||||
"moduleResolution": "node10", |
||||
"types": ["jest", "node"] |
||||
}, |
||||
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
export interface BasicLibGeneratorSchema { |
||||
name: string; |
||||
description: string; |
||||
team: string; |
||||
directory: string; |
||||
} |
||||
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
{ |
||||
"$schema": "https://json-schema.org/schema", |
||||
"$id": "BasicLib", |
||||
"title": "", |
||||
"type": "object", |
||||
"properties": { |
||||
"name": { |
||||
"type": "string", |
||||
"description": "Library name", |
||||
"$default": { |
||||
"$source": "argv", |
||||
"index": 0 |
||||
}, |
||||
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$", |
||||
"x-prompt": "What name would you like to use? (kebab-case, alphanumeric)", |
||||
"x-priority": "important" |
||||
}, |
||||
"description": { |
||||
"type": "string", |
||||
"description": "Library description", |
||||
"x-prompt": "Please describe your library in one sentence (for package.json and README)", |
||||
"x-priority": "important" |
||||
}, |
||||
"directory": { |
||||
"type": "string", |
||||
"description": "Directory where the library will be created", |
||||
"default": "libs", |
||||
"x-prompt": "What directory would you like your lib in?", |
||||
"x-priority": "important" |
||||
}, |
||||
"team": { |
||||
"type": "string", |
||||
"description": "Maintaining team", |
||||
"x-priority": "important", |
||||
"x-prompt": { |
||||
"message": "What team maintains this library?", |
||||
"type": "list", |
||||
"items": [ |
||||
{ |
||||
"value": "admin-console", |
||||
"label": "Admin Console" |
||||
}, |
||||
{ |
||||
"value": "auth", |
||||
"label": "Auth" |
||||
}, |
||||
{ |
||||
"value": "autofill", |
||||
"label": "Autofill" |
||||
}, |
||||
{ |
||||
"value": "billing", |
||||
"label": "Billing" |
||||
}, |
||||
{ |
||||
"value": "data-insights-and-reporting", |
||||
"label": "Data Insights And Reporting" |
||||
}, |
||||
{ |
||||
"value": "key-management", |
||||
"label": "Key Management" |
||||
}, |
||||
{ |
||||
"value": "platform", |
||||
"label": "Platform" |
||||
}, |
||||
{ |
||||
"value": "tools", |
||||
"label": "Tools" |
||||
}, |
||||
{ |
||||
"value": "ui-foundation", |
||||
"label": "UI Foundation" |
||||
}, |
||||
{ |
||||
"value": "vault", |
||||
"label": "Vault" |
||||
} |
||||
] |
||||
}, |
||||
"enum": [ |
||||
"admin-console", |
||||
"auth", |
||||
"autofill", |
||||
"billing", |
||||
"data-insights-and-reporting", |
||||
"key-management", |
||||
"platform", |
||||
"tools", |
||||
"ui-foundation", |
||||
"vault" |
||||
] |
||||
} |
||||
}, |
||||
"required": ["name", "description", "team"] |
||||
} |
||||
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
{ |
||||
"extends": "../../tsconfig.base.json", |
||||
"compilerOptions": { |
||||
"module": "commonjs" |
||||
}, |
||||
"files": [], |
||||
"include": [], |
||||
"references": [ |
||||
{ |
||||
"path": "./tsconfig.lib.json" |
||||
}, |
||||
{ |
||||
"path": "./tsconfig.spec.json" |
||||
} |
||||
] |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "../../dist/out-tsc", |
||||
"declaration": true, |
||||
"types": ["node"] |
||||
}, |
||||
"include": ["src/**/*.ts"], |
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "../../dist/out-tsc", |
||||
"module": "commonjs", |
||||
"moduleResolution": "node10", |
||||
"types": ["jest", "node"] |
||||
}, |
||||
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] |
||||
} |
||||
@ -1,10 +1,42 @@
@@ -1,10 +1,42 @@
|
||||
{ |
||||
"$schema": "./node_modules/nx/schemas/nx-schema.json", |
||||
"cacheDirectory": ".nx/cache", |
||||
"defaultBase": "main", |
||||
"namedInputs": { |
||||
"default": ["{projectRoot}/**/*"], |
||||
"production": ["!{projectRoot}/**/*.spec.ts"] |
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"], |
||||
"production": ["default", "!{projectRoot}/**/*.spec.ts", "!{projectRoot}/tsconfig.spec.json"], |
||||
"sharedGlobals": ["{workspaceRoot}/tsconfig.base.json", "{workspaceRoot}/package.json"] |
||||
}, |
||||
"plugins": [ |
||||
{ |
||||
"plugin": "@nx/js", |
||||
"options": { |
||||
"compiler": "tsc", |
||||
"configName": "tsconfig.lib.json", |
||||
"targetName": "build" |
||||
} |
||||
}, |
||||
{ |
||||
"plugin": "@nx/jest/plugin", |
||||
"options": { |
||||
"targetName": "test" |
||||
} |
||||
}, |
||||
{ |
||||
"plugin": "@nx/eslint/plugin", |
||||
"options": { |
||||
"targetName": "lint" |
||||
} |
||||
}, |
||||
"@bitwarden/nx-plugin" |
||||
], |
||||
"parallel": 4, |
||||
"targetDefaults": {} |
||||
"targetDefaults": { |
||||
"build": { |
||||
"dependsOn": ["^build"], |
||||
"inputs": ["production", "^production"], |
||||
"outputs": ["{options.outputPath}"], |
||||
"cache": true |
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue