# How to Run the Linter Locally in the HowToCook Repository

> Learn how to run the linter locally in the HowToCook repository with simple npm commands. Ensure your Markdown follows typography and style conventions effortlessly.

- Repository: [Anduin Xue/HowToCook](https://github.com/Anduin2017/HowToCook)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Execute `npm ci` followed by `npm run lint` to validate all Markdown files against Chinese typography rules, standard Markdown style, and repository-specific dish conventions.**

The Anduin2017/HowToCook repository maintains strict quality standards for its crowd-sourced cooking recipes. To ensure every dish submission follows the project's precise formatting guidelines for Chinese punctuation, Markdown structure, and metadata requirements, contributors must run the linter locally before opening pull requests.

## The Three-Layer Linting Architecture

The HowToCook project employs a composite linting strategy defined in [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json) (lines 16-22) that chains three distinct validation layers.

### Textlint for Chinese Typography

Configured in `.textlintrc`, **textlint** enforces Chinese-specific typographic standards. This includes validating full-width versus half-width character usage, proper punctuation placement, and other regional typography rules essential for consistent Chinese documentation.

### Markdownlint for Style Consistency

The **markdownlint** component, configured via [`.markdownlint.json`](https://github.com/Anduin2017/HowToCook/blob/main/.markdownlint.json), validates standard Markdown formatting issues. It checks heading hierarchy, line length limits, and structural consistency across the `./dishes` and `./tips` directories.

### Manual Lint for Repository Conventions

The custom Node.js script at [`.github/manual_lint.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/manual_lint.js) implements project-specific requirements that generic linters cannot enforce. It traverses every file under `./dishes` to validate:

- File naming conventions (prohibiting spaces and enforcing format)
- Required markdown sections and metadata structure
- Difficulty rating compliance
- Unit precision standards
- Mandatory footer text
- File size limits

## Running the Linter Locally

First, install the exact dependency versions locked in the repository:

```bash
npm ci

```

Then execute the complete validation suite using the composite script defined in [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json):

```bash
npm run lint

```

This command sequentially invokes `textlint`, `markdownlint`, and the custom `manuallint` script, ensuring your local environment mirrors the continuous integration checks.

For targeted debugging, run individual checkers:

```bash

# Validate Chinese typography only

npm run textlint

# Check Markdown style only

npm run markdownlint

# Verify repository-specific dish format only

npm run manuallint

```

## Interpreting Lint Failures

When validation fails, the scripts emit specific error messages indicating the offending file path and violated rule. For example, the manual linter in [`.github/manual_lint.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/manual_lint.js) outputs messages like "文件 … 不符合仓库的规范！文件名不能包含空格！" when detecting invalid filenames. The script exits with a non-zero status code, ensuring CI pipeline failures match local behavior and preventing non-compliant submissions from passing automated checks.

## Summary

- The HowToCook repository uses a three-tier linting system defined in [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json) combining **textlint**, **markdownlint**, and a custom manual validator at [`.github/manual_lint.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/manual_lint.js).
- Run `npm ci` once to install dependencies, then `npm run lint` to execute all checks locally before committing.
- The custom manual script enforces unique requirements including filename formatting, dish section completeness, difficulty ratings, and file size limits.
- Individual components can be run separately using `npm run textlint`, `npm run markdownlint`, or `npm run manuallint` for isolated debugging.

## Frequently Asked Questions

### What Node.js version is required to run the linter locally?

The project expects a modern Node.js environment with npm installed. The `npm ci` command installs exact dependency versions from [`package-lock.json`](https://github.com/Anduin2017/HowToCook/blob/main/package-lock.json), ensuring compatibility with the linting tools specified in [`package.json`](https://github.com/Anduin2017/HowToCook/blob/main/package.json) regardless of your global package versions.

### Can I run only the repository-specific checks without Markdownlint?

Yes. Execute `npm run manuallint` to run only the custom validation logic in [`.github/manual_lint.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/manual_lint.js). This script checks file naming conventions, required dish sections, difficulty ratings, and unit precision without invoking the standard Markdown or typography rules.

### Why does the manual linter reject my file names?

The [`.github/manual_lint.js`](https://github.com/Anduin2017/HowToCook/blob/main/.github/manual_lint.js) script enforces strict filename conventions, specifically prohibiting spaces and requiring a specific format for dish files. If your filename contains spaces or violates the project's naming schema, the linter exits with an error message specifying the exact restriction violated.

### How do I fix Chinese punctuation errors detected by textlint?

Run `npm run textlint` to identify specific half-width or full-width character violations. Correct these by converting punctuation to the proper full-width Chinese characters as defined in the `.textlintrc` configuration rules, then re-run the linter to verify compliance before submitting your pull request.