Coder Social home page Coder Social logo

feature-sliced / steiger Goto Github PK

View Code? Open in Web Editor NEW
29.0 29.0 1.0 373 KB

Universal file structure and project architecture linter

Home Page: https://www.npmjs.com/package/steiger

License: MIT License

TypeScript 97.21% JavaScript 2.79%
architecture folders imports linter naming-conventions

steiger's People

Contributors

illright avatar unordinarity avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

steiger's Issues

Implement `no-segments-on-sliced-layers`

Sliced layers (Shared, Features, Widgets, Pages) should not have folders with conventional segment names in direct children.

  • Write the rule
  • Write positive test
  • Write negative test
  • Add documentation in form of a README and link that in the main README of the repo

Implement `consistent-naming`

Detect consistent naming of slices on layers (singular vs plural, casing)

  • Implement singular/plural consistency checks
  • Add a special error for cases when an entity exists in both singular and plural (i.e. entities/product and entities/products at the same time)
  • Implement singular/plural fixes
  • Add support for multi-word slice names
  • Implement case consistency checks and fixes

Implement a TypeScript-compliant import resolver

Given a file name, an imported path, and a TSConfig object, produce an absolute path to the imported file.

Example (inside $PROJECT_FOLDER):

// ./src/pages/home/ui/HomePage.tsx
import { Button } from "~/shared/ui";
// ./tsconfig.json
{
  "include": ["**/*.ts", "**/*.tsx"],
  "compilerOptions": {
    "moduleResolution": "Bundler",
    "baseUrl": ".",
    "paths": {
      "~/*": ["./src/*"],
    },
  },
}

Expected output: $PROJECT_FOLDER/src/shared/ui/index.ts

insignificant-slice rule does not work correctly

returns an error:
image
but the project has more than one necessary import, for example:
image

reproduced on windows 10

configuration used:
tsconfig.json

path of the file importing utilities from entities/conference:
src/widgets/messenger-chat\ui\ChatHeader\ConferenceMembersIndicator.tsx

Implement `insignificant-slice`

Detect small (by LoC) slices on entities/features/widgets that are only used on a single page and suggest moving them into the page

Feature request: turn off a rule using a template path in config

Hey. I have a feature request: turn off a rule for specific folders/files by path. For example, we have some mocks (which located at an entity layer) and we deliberately don't add them to the public API to don't increase the bundle size.

 ✘ Forbidden sidestep of public API when importing "shared/lib/server/index.ts" from "widgets/ProductDetails/api/__mocks__/widgetProductDetailsHandlers.ts".  // no-public-api-sidestep

 ✘ Forbidden sidestep of public API when importing "entities/product/api/__mocks__/mockProductDtoByIds.ts" from "widgets/BaseProductList/ui/BaseProductList.stories.tsx".  // no-public-api-sidestep

It could look like this:

export default defineConfig({
  rules: {
    'no-public-api-sidestep': 'on',
  },
  overrides: [
    {
      // Maybe we should specify two types of groups ("when importing" files and "from" files) 
      // Allow import any file from `@/shared/lib/server/**/*.ts` from `**/__mocks__/**/*.ts`
      patternFrom: ['**/__mocks__/**/*.ts']
      patternTo: ['@/shared/lib/server/**/*.ts']
      rules: {
        'no-public-api-sidestep': 'off'
      }
    },
    {
      patternFrom: ['*.stories.tsx']
      patternTo: ['**/__mocks__/**/*.ts']
      rules: {
        'no-public-api-sidestep': 'off'
      }
    }
  ]
})

Feature request: add settings for current rules

Hey. I have a feature request: setup current rules from config file. For example, turn off some layers for "forbidden-import" rule.

 ✘ Forbidden cross-import on layer "entities" from "wishlist/model/slice.ts" to slice "product".  // forbidden-imports

 ✘ Forbidden cross-import on layer "entities" from "wishlist/lib/mapWishlist.ts" to slice "product".  // forbidden-imports

 ✘ Forbidden cross-import on layer "entities" from "wishlist/api/types.ts" to slice "product".  // forbidden-imports

 ✘ Forbidden cross-import on layer "entities" from "wishlist/api/wishlistApi.ts" to slice "product".  // forbidden-imports

 ✘ Forbidden cross-import on layer "entities" from "theme/lib/ThemeProvider.tsx" to slice "featureToggle".  // forbidden-imports

 ✘ Forbidden cross-import on layer "entities" from "category/model/types.ts" to slice "product".  // forbidden-imports

It could look like this:

export default defineConfig({
  rules: {
    'forbidden-imports': ['on', {
      ignoreLayers: ['entities']
    }],
  },
})

Cover with E2E tests

Take some projects from FSD examples, pin a commit hash and run the linter on that commit. Then make fixes and run again to see the issues go away.

The test should run on all OSes on Node 18+

Feature request: import self-written rules

Hey. I have a feature request: I want to write rules for my project and i import them via config.

It could look like:

import { defineConfig } from 'steiger'
import rules from '...'

export default defineConfig({
  preset: [...rules]
})

Implement auto-fixes for `no-public-api-sidestep`

Restrict imports that go inside the slice, sidestepping the public API.

Every slice (and segment on layers that don't have slices) must contain a public API definition.

Modules outside of this slice/segment can only reference the public API, not the internal file structure of the slice/segment.
https://feature-sliced.design/docs/reference/slices-segments#public-api-rule-on-slices

Examples of imports that violate this rule:

// src/pages/home/ui/HomePage.tsx
import { ArticlePreview } from "~/entities/article/ui/ArticlePreview`;

Pay attention in designing this rule that some people choose to sidestep the public API in Shared, especially shared/ui, to improve tree-shaking

  • Implement the rule
  • Implement auto-fixes

Feature request: Add links to files in console

Привет! В eslint инструментах есть удобная фича перехода по ссылке на файл по подсвеченной проблеме. Очень бы хотелось видеть это в steiger, т.к. это значительно повышает DX.
Сейчас путь до файла в консоли есть, но активной ссылки на этот текст нет. Это вносит определенные неудобства.

Feature request: Configure rule of cross-imports

Мы на проекте пришли к соглашению, что в слое виджетов мы разрешаем кросс-импорты в части композиции верстки (т.е. на уровне ui, а не моделей).
Было бы круто, если бы это можно было настроить в Steiger.

Implement `no-wildcard-exports`

Discourage wildcard exports export * from in public APIs.

Examples of code violating this rule:

// src/shared/ui/index.ts
export * from "./form";

Examples of code passing this rule:

// src/shared/ui/index.ts
export { Form, Field } from "./form";
export * as positions from "./tooltip-positions";

Support project-level rules

It would be nice to allow people to write custom rules in the lowest friction possible — by simply having rules in their project and linking them in the config file

Feature request: add warning mode

Hey. I have a feature request: I want to see errors in warning mode (like in eslint). This will allow you to see errors, but not crash in CI.

It could look like:

export default defineConfig({
  rules: {
    'forbidden-imports': 'warn'
  },
})

Feature request: IDE support

Для улучшения DX хотелось бы видеть в Steiger поддержку в двух популярных IDE (JetBrains, VS Code).

  • В первую очередь, для подсветки в коде
  • Для автофикса где это возможно (очень редкий кейс в случае с архитектурным линтингом)

Question: Public API in shared layer

Как мы знаем shared слой состоит не из слайсов, а из сегментов. Требование Public API для сегментов shared слоя не кажется избыточным? Может вы не учли исключение shared слоя при написании этого правила?

image

Sandbox: https://codesandbox.io/p/devbox/steiger-test-g4f4wp

==================================================

Из этого вытекает вторая проблема: если в shared слое т.к. он состоит из сегментов убирать Public API - в линтере нужна настройка разрешенной глубины импортов для конкретного слоя, чтобы это не выглядело нарушением Public API, e.g.:

import from 'shared/ui/card'

Воспроизвести в сэндбоксе быстро не получилось.

Question: Non-descriptive segment name

Сейчас имена сегментов захардкожены в линтере? И как я понимаю это правило не закастомизировать в данный момент: issue?

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.