Resolving ESHOPMAN Linting Plugin Dependency Issues for Robust Development
Ensuring Robust ESHOPMAN Development: Tackling Hidden Linting Dependencies
The ESHOPMAN platform, built on Node.js/TypeScript, empowers developers to create powerful headless commerce solutions, manage storefronts within HubSpot, and deploy via HubSpot CMS. A critical part of maintaining code quality and ensuring consistent development practices for both the Admin API and Store API is our dedicated linting plugin.
Recently, a subtle but significant dependency issue was identified within the ESHOPMAN linting plugin. This insight from our community highlights how an undeclared dependency can disrupt development workflows, especially in environments with strict package management policies.
The Core Problem: A Missing Declaration
The ESHOPMAN linting plugin requires the @typescript-eslint/typescript-estree package for the proper functioning of several key rules. These rules are vital for ESHOPMAN's backend development, ensuring:
- Correct export of loaders in module definitions (
rules/loader-must-be-exported-in-module-definition/rule.ts). - Proper validation of request bodies or queries for Admin/Store API endpoints (
rules/use-validated-body-or-query/rule.ts). - Uniqueness of scheduled job names for background processes (
rules/scheduled-job-name-unique/rule.ts).
However, this crucial dependency was not explicitly declared in the plugin's package.json. While many package managers might implicitly resolve this due to hoisting (where it's a transitive dependency of @typescript-eslint/utils), strict package layouts or tools like pnpm with nodeLinker: isolated and hoist: false, or Yarn PnP, will strictly enforce declared dependencies. When this happens, the plugin fails to load.
Impact on ESHOPMAN Development Workflows
For ESHOPMAN developers, this issue manifests in two primary ways:
- Development Server Exit: When running the ESHOPMAN development server (e.g., via an equivalent to
eshopman dev) with linting configured to fail on errors, the server will exit prematurely, halting development. - Build Warnings: During the ESHOPMAN build process (e.g.,
eshopman build), the issue might only generate warnings, making it easy to overlook in continuous integration (CI) pipelines.
The problem has been observed across various Node.js versions (v22/v24) and is not operating system-specific.
Reproducing the Issue
To illustrate, here's a minimal package.json demonstrating the setup:
{
"devDependencies": {
"@eshopman/eslint-plugin": "2.21.2",
"eslint": "^9.0.0",
"typescript": "^5.0.0"
}
}
And a reproduction using pnpm with strict settings:
mkdir repro && cd repro
echo '{"name":"repro","private":true}' > package.json
printf 'nodeLinker: isolated
hoist: false
' > pnpm-workspace.yaml
pnpm add @eshopman/[email protected] eslint@9 typescript@5
node -e 'require("@eshopman/eslint-plugin")'
This would typically result in an error similar to:
Error: Cannot find module '@typescript-eslint/typescript-estree'
Require stack:
- .../node_modules/@eshopman/eslint-plugin/dist/rules/loader-must-be-exported-in-module-definition/rule.js
Workaround and Suggested Fix
Until a permanent fix is implemented in the ESHOPMAN linting plugin, developers can use a workaround, particularly with pnpm. By adding a packageExtensions entry, you can explicitly declare the missing dependency for the plugin:
# In your pnpm-workspace.yaml or .npmrc
packageExtensions:
"@eshopman/eslint-plugin":
dependencies:
"@typescript-eslint/typescript-estree": "^8.0.0"
The suggested permanent fix is for the ESHOPMAN linting plugin to explicitly declare "@typescript-eslint/typescript-estree": "^8.0.0" alongside its other @typescript-eslint/* dependencies in its own package.json file. This ensures that the plugin loads correctly in all environments, providing a more stable and predictable development experience for ESHOPMAN developers.
This community insight highlights the importance of robust dependency management in complex Node.js/TypeScript applications like ESHOPMAN, ensuring that our tools support seamless development of storefronts and backend services within the HubSpot ecosystem.