diff --git a/.editorconfig b/.editorconfig index ae10a5cc..aa4ac928 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +1,7 @@ -# editorconfig.org root = true [*] -charset = utf-8 end_of_line = lf -indent_size = 2 -indent_style = space +charset = utf-8 insert_final_newline = true trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore index d0c64e3a..db0b0d3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,153 +1,32 @@ -# https://github.com/toptal/gitignore/blob/master/templates/Node.gitignore - # Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* .pnpm-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ +# Dependency directory +node_modules -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ +# NX Cache +.nx # TypeScript cache *.tsbuildinfo -# Optional npm cache directory -.npm - -# Optional eslint cache +# Eslint cache .eslintcache -# Optional stylelint cache +# Stylelint cache .stylelintcache -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -# https://github.com/toptal/gitignore/blob/master/templates/Turbo.gitignore - -# Turborepo task cache -.turbo - -# Custom Additions - # Bundle output directories dist/ -build/ -# Jest folder of detailed test coverage -coverage/ +# Storybook bundle output +storybook-static -# nx -nx-cloud.env -.nx +# Jest test coverage +coverage -# Storybook -storybook-static +# Env files +nx-cloud.env diff --git a/.prettierignore b/.prettierignore index 6ba929fe..d612622d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ dist coverage +.nx pnpm-lock.yaml CHANGELOG.md diff --git a/.prettierrc.cjs b/.prettierrc.cjs index 16cc592f..d6ff644b 100644 --- a/.prettierrc.cjs +++ b/.prettierrc.cjs @@ -1,5 +1,4 @@ module.exports = { - endOfLine: 'lf', printWidth: 120, singleQuote: true, }; diff --git a/docs/repo/ARCHITECTURE.md b/docs/repo/ARCHITECTURE.md index a279d628..339c7029 100644 --- a/docs/repo/ARCHITECTURE.md +++ b/docs/repo/ARCHITECTURE.md @@ -41,11 +41,15 @@ We are using `lint-staged` to run linting and tests on staged files. This is the 1. Check for secrets (`secretlint`) 2. Fix file formatting (`prettier`) -3. Lint and fix issues of affected `.ts` and related files (`eslint` and `nx`) -4. Run tests of affected files (`jest`/`vitest` and `nx`) +3. Lint `package.json` files for package, dependency, and monorepo best practices +4. Lint and fix issues of affected `.ts` and related files (`eslint` and `nx`) +5. Run tests of affected files (`jest`/`vitest` and `nx`) +6. Lint exports on all `.ts` files (`knip` and `nx`) We limit automatic fixes to file formatting and linting when possible. For everything else, we let the user to decide on actions to take if there are errors. +We also use Github actions as an extra safeguard in case users bypass `lint-staged`. + ## Versioning All packages including `peerDependencies` are configured to use exact versions of packages. I prefer to have exact package versions to simplify debugging and reduce the likelihood of compatibility issues. I use `renovate` to automatically handle version updates. @@ -84,3 +88,7 @@ import { Button, type ButtonProps } from '@waldronmatt/demo-ui/lib/index.js'; ``` There are other ways to do this such as symlinking and/or stubbing via third-party packages, but I personally ran into issues using these other methods. Alternatively, some may choose to refernce them via a registry (`npm`) with specified versions so that changes do not break other apps in the monorepo. This may be preferred for larger teams and organizations. + +## ESM and CJS File Naming Conventions + +For the rare instances where I have both `esm` and `cjs` bundles, I set specific file extensions like `.cjs` for `cjs` and use the standard `.js` extension for `esm`. ESM is the module system industry standard and I would prefer to not label them specifically with a `.mjs` extension. Labelling `cjs` files differently helps to remind developers to upgrade in the future if both module systems must be supported. diff --git a/docs/repo/CICD.md b/docs/repo/CICD.md index 0227642d..509b71ec 100644 --- a/docs/repo/CICD.md +++ b/docs/repo/CICD.md @@ -6,20 +6,26 @@ Installer command to ensure that the exact versions of dependencies specified in pnpm bootstrap:ci ``` -Versioning command that will bypass prompts for avoiding manual intervention: +Lint the monorepo: ```bash -pnpm version:ci +pnpm lint:mr ``` -Publishing command that will bypass prompts for avoiding manual intervention: +Found in the workflow `.yml` cicd files, this command will run all three tasks in parallel for only affected files: ```bash -pnpm publish:ci +npx nx affected -t build,lint,test,lint:knip --parallel=4 ``` -Found in the workflow `.yml` cicd files, this command will run all three tasks in parallel for only affected files: +Versioning command that will bypass prompts for avoiding manual intervention: ```bash -npx nx affected -t build,lint,test --parallel=3 +pnpm version:ci +``` + +Publishing command that will bypass prompts for avoiding manual intervention: + +```bash +pnpm publish:ci ``` diff --git a/docs/repo/COMMANDS.md b/docs/repo/COMMANDS.md index 1a0a6986..f5e00813 100644 --- a/docs/repo/COMMANDS.md +++ b/docs/repo/COMMANDS.md @@ -20,6 +20,12 @@ Delete workspace root `node_modules` and `pnpm-lock.yaml` files: pnpm delete ``` +Find unused exports (applies to projects in `packages` folder): + +```bash +pnpm lint:knip +``` + Visualize the project structure/dependencies: ```bash diff --git a/docs/repo/MONOREPO.md b/docs/repo/MONOREPO.md index 514d7fa0..0032a49f 100644 --- a/docs/repo/MONOREPO.md +++ b/docs/repo/MONOREPO.md @@ -1,6 +1,6 @@ # Monorepo Commands -Lint your monorepo (executes all commands below): +Lint the monorepo (executes all commands below): ```bash pnpm lint:mr @@ -18,7 +18,7 @@ Check files for formatting issues: pnpm lint:format ``` -Validate package publishing best practices: +Validate package publishing best practices (applies to projects in `packages` folder): ```bash pnpm lint:packages @@ -35,9 +35,3 @@ Verify monorepo best practice: ```bash pnpm lint:monorepo ``` - -Find unused exports: - -```bash -pnpm lint:knip -``` diff --git a/docs/ui/tsconfig.json b/docs/ui/tsconfig.json index 9fe11125..b70c6515 100644 --- a/docs/ui/tsconfig.json +++ b/docs/ui/tsconfig.json @@ -4,6 +4,6 @@ "include": ["src"], "exclude": ["node_modules", "dist", "coverage"], "compilerOptions": { - "types": ["vitest/globals"], - }, + "types": ["vitest/globals"] + } } diff --git a/lint-staged.config.cjs b/lint-staged.config.cjs index 1c722f4c..ecdb2e82 100644 --- a/lint-staged.config.cjs +++ b/lint-staged.config.cjs @@ -1,5 +1,6 @@ module.exports = { '*': ['secretlint', 'prettier --cache --write --ignore-unknown'], + '**/package.json': ['node ./publint.js', 'npx syncpack lint --config .syncpackrc', 'manypkg check'], '*.{cjs,js,jsx,ts,tsx}': ['nx affected -t lint --fix --files'], - '*.{ts,tsx}': ['nx affected -t test --files'], + '*.{ts,tsx}': ['nx affected -t test --files', 'npx nx run-many -t lint:knip'], }; diff --git a/package.json b/package.json index c4843205..91537a68 100644 --- a/package.json +++ b/package.json @@ -17,18 +17,18 @@ "commit": "git-cz", "delete": "rimraf pnpm-lock.yaml .nx node_modules", "lint:secrets": "npx secretlint **/*", - "lint:format": "prettier --check .", + "lint:format": "prettier --write .", "lint:packages": "node ./publint.js", "lint:deps": "npx syncpack lint --config .syncpackrc", "lint:monorepo": "npx manypkg check", - "lint:knip": "knip --exports", - "lint:mr": "run-p lint:secrets lint:format lint:packages lint:deps lint:monorepo lint:knip", + "lint:mr": "run-p lint:secrets lint:format lint:packages lint:deps lint:monorepo", "nx:graph": "npx nx graph", "update:deps": "npx syncpack update", "list:deps": "npx syncpack list", "list:packages": "lerna ls -l -all", "list:changed": "lerna changed -l -all", "dev": "npx nx run-many -t dev", + "lint:knip": "npx nx run-many -t lint:knip", "lint": "npx nx run-many -t lint", "test": "npx nx run-many -t test", "test:watch": "npx nx run-many -t test:watch", @@ -50,7 +50,7 @@ "@lerna-lite/version": "3.3.1", "@manypkg/cli": "0.21.3", "@nrwl/cli": "15.9.3", - "@nrwl/nx-cloud": "16.5.2", + "@nrwl/nx-cloud": "18.0.1", "@secretlint/secretlint-rule-preset-recommend": "8.1.2", "@types/node": "20.11.30", "commitizen": "4.3.0", diff --git a/packages/basic-math/package.json b/packages/basic-math/package.json index 411afc2e..cc0f8027 100644 --- a/packages/basic-math/package.json +++ b/packages/basic-math/package.json @@ -18,6 +18,7 @@ "README.md" ], "scripts": { + "lint:knip": "knip --exports", "lint": "eslint . --ext ts --report-unused-disable-directives --max-warnings 0", "test": "jest --coverage", "test:watch": "jest --watch", diff --git a/packages/basic-math/tsconfig.json b/packages/basic-math/tsconfig.json index 8762c0a6..f172eda9 100644 --- a/packages/basic-math/tsconfig.json +++ b/packages/basic-math/tsconfig.json @@ -4,6 +4,6 @@ "include": ["src/**/*.ts"], "exclude": ["node_modules", "dist", "coverage"], "compilerOptions": { - "baseUrl": "./", - }, + "baseUrl": "./" + } } diff --git a/packages/parity/package.json b/packages/parity/package.json index 0798e216..42e9ffb8 100644 --- a/packages/parity/package.json +++ b/packages/parity/package.json @@ -18,6 +18,7 @@ "README.md" ], "scripts": { + "lint:knip": "knip --exports", "lint": "eslint . --ext ts --report-unused-disable-directives --max-warnings 0", "test": "jest --coverage", "test:watch": "jest --watch", diff --git a/packages/parity/tsconfig.json b/packages/parity/tsconfig.json index 8762c0a6..f172eda9 100644 --- a/packages/parity/tsconfig.json +++ b/packages/parity/tsconfig.json @@ -4,6 +4,6 @@ "include": ["src/**/*.ts"], "exclude": ["node_modules", "dist", "coverage"], "compilerOptions": { - "baseUrl": "./", - }, + "baseUrl": "./" + } } diff --git a/packages/tokens-ui/package.json b/packages/tokens-ui/package.json index 28e101f0..faafe44f 100644 --- a/packages/tokens-ui/package.json +++ b/packages/tokens-ui/package.json @@ -24,6 +24,7 @@ "**/*.css" ], "scripts": { + "lint:knip": "knip --exports", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "build": "tsc --p ./tsconfig.build.json && vite build", "clean": "rimraf dist coverage tsconfig.build.tsbuildinfo" diff --git a/packages/tokens-ui/tsconfig.json b/packages/tokens-ui/tsconfig.json index 10e3b4d9..e9eea76e 100644 --- a/packages/tokens-ui/tsconfig.json +++ b/packages/tokens-ui/tsconfig.json @@ -7,6 +7,6 @@ "outDir": "dist", "baseUrl": "./", "declaration": true, - "declarationMap": true, - }, + "declarationMap": true + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 46827a23..fad02f60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: 15.9.3 version: 15.9.3 '@nrwl/nx-cloud': - specifier: 16.5.2 - version: 16.5.2 + specifier: 18.0.1 + version: 18.0.1 '@secretlint/secretlint-rule-preset-recommend': specifier: 8.1.2 version: 8.1.2 @@ -382,13 +382,6 @@ importers: version: 5.4.3 packages/lit-override: - dependencies: - lit: - specifier: 3.1.2 - version: 3.1.2 - lit-html: - specifier: 3.1.2 - version: 3.1.2 devDependencies: '@open-wc/testing': specifier: 4.0.0 @@ -426,6 +419,12 @@ importers: jest-config: specifier: workspace:* version: link:../../configs/jest-config + lit: + specifier: 3.1.2 + version: 3.1.2 + lit-html: + specifier: 3.1.2 + version: 3.1.2 rimraf: specifier: 5.0.5 version: 5.0.5 @@ -543,6 +542,9 @@ importers: eslint-config-custom: specifier: workspace:* version: link:../../configs/eslint-config-custom + fs-extra: + specifier: 11.2.0 + version: 11.2.0 glob: specifier: 10.3.12 version: 10.3.12 @@ -3798,10 +3800,10 @@ packages: - debug dev: false - /@nrwl/nx-cloud@16.5.2: - resolution: {integrity: sha512-oHO5T1HRJsR9mbRd8eUqMBPCgqVZLSbAh3zJoPFmhEmjbM4YB9ePRpgYFT8dRNeZUOUd/8Yt7Pb6EVWOHvpD/w==} + /@nrwl/nx-cloud@18.0.1: + resolution: {integrity: sha512-uYVxoOXf0xlWJX8O5GBWajmIeL0PfIGvfqtvVNVnl7C6FiZRbmKEhXkWxEDekI6Jq+mI1G86o7d5YsIzq6e36A==} dependencies: - nx-cloud: 16.5.2 + nx-cloud: 18.0.1 transitivePeerDependencies: - debug dev: false @@ -4158,7 +4160,7 @@ packages: requiresBuild: true dependencies: node-addon-api: 3.2.1 - node-gyp-build: 4.8.0 + node-gyp-build: 4.8.1 dev: false /@pkgjs/parseargs@0.11.0: @@ -7423,14 +7425,6 @@ packages: resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} dev: false - /@yarnpkg/parsers@3.0.0: - resolution: {integrity: sha512-jVZa3njBv6tcOUw34nlUdUM/40wwtm/gnVF8rtk0tA6vNcokqYI8CFU1BZjlpFwUSZaXxYkrtuPE/f2MMFlTxQ==} - engines: {node: '>=18.12.0'} - dependencies: - js-yaml: 3.14.1 - tslib: 2.6.2 - dev: false - /@yarnpkg/parsers@3.0.0-rc.46: resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} engines: {node: '>=14.15.0'} @@ -14289,8 +14283,8 @@ packages: formdata-polyfill: 4.0.10 dev: false - /node-gyp-build@4.8.0: - resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} + /node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} hasBin: true dev: false @@ -14492,11 +14486,11 @@ packages: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: false - /nx-cloud@16.5.2: - resolution: {integrity: sha512-1t1Ii9gojl8r/8hFGaZ/ZyYR0Cb0hzvXLCsaFuvg+EJEFdvua3P4cfNya/0bdRrm+7Eb/ITUOskbvYq4TSlyGg==} + /nx-cloud@18.0.1: + resolution: {integrity: sha512-nxJfz0ZmW+DKSr8evmVVm6t1XcLn9WHR5I8kiE2BFNkLVwC+nx+MimjJ53opfHOepMqQiGJAdstZ5Ks630bJgg==} hasBin: true dependencies: - '@nrwl/nx-cloud': 16.5.2 + '@nrwl/nx-cloud': 18.0.1 axios: 1.1.3 chalk: 4.1.2 dotenv: 10.0.0 @@ -14504,7 +14498,7 @@ packages: node-machine-id: 1.1.12 open: 8.4.2 strip-json-comments: 3.1.1 - tar: 6.1.11 + tar: 6.2.1 yargs-parser: 21.1.1 transitivePeerDependencies: - debug @@ -14527,7 +14521,7 @@ packages: '@nrwl/tao': 15.9.3 '@parcel/watcher': 2.0.4 '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.0 + '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.6 axios: 1.6.8 chalk: 4.1.2 @@ -17156,18 +17150,6 @@ packages: streamx: 2.16.1 dev: true - /tar@6.1.11: - resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} - engines: {node: '>= 10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.3.6 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - /tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'}