feat(frontend): the folders are layers — an import only goes down, a module is reached through its index.ts
`local/layers` (eslint.config.js) resolves every import to its file and refuses one that goes up (lib/ → components/ui/ → features/ → modules/ → shell/) or that reaches into another module's own files. A module's index.ts is its public face: the stores, mounted at the root and read app-wide, which features/ may read too; a page is still opened lazily by import(). Its contract test probes every edge, and three mutants of the rule (off, no face check, a door for everyone) each turn it red. Six modules got that face; the shared channel UI (about, tags, tag manager) moved to features/channel, the filter chips and the saved-views context to features/filters, and the prefs store's controller type moved next to the store instead of importing it from its own page. The header's per-module controls and the eagerly loaded rails keep eight inline suppressions, each naming why: they go when the header gets slots and every rail loads lazily. `chunkGuard` fails the production build when a lazily imported module lands in a boot chunk (the entry, the shell, what they import) — e.g. a page re-exported from an index.ts, which makes its import() a silent no-op. Proved on a build with that mutant; today's build has none.
This commit is contained in:
@@ -33,14 +33,14 @@ import { useChannelActions } from "./useChannelActions";
|
||||
import { useContextMenu } from "../../components/ui/useContextMenu";
|
||||
import { LoadingState, StateMessage } from "../../components/ui/QueryState";
|
||||
import { useChannelTagActions } from "../../lib/useChannelTagActions";
|
||||
import { useTagSuggestions } from "./useTagSuggestions";
|
||||
import { useTagSuggestions } from "../../features/channel/useTagSuggestions";
|
||||
import { useChannelPriority } from "../../lib/useChannelPriority";
|
||||
import { placeByPriority } from "../../lib/channelOrder";
|
||||
import { focusNavItem } from "../../lib/listNav";
|
||||
import ViewSwitcher, { type ViewOption } from "../../components/ui/ViewSwitcher";
|
||||
import ColumnSortControl from "../../components/ui/ColumnSortControl";
|
||||
import FilterChipGroup from "../../components/ui/FilterChipGroup";
|
||||
import TagFilterChips from "../feed/TagFilterChips";
|
||||
import TagFilterChips from "../../features/filters/TagFilterChips";
|
||||
import ActionMenu, { type ActionMenuItem } from "../../components/ui/ActionMenu";
|
||||
import ChannelStatsPopover from "./ChannelStatsPopover";
|
||||
import Pager from "../../components/ui/Pager";
|
||||
@@ -57,10 +57,10 @@ import { menuGroups } from "../../components/ui/menuGroups";
|
||||
import { choiceSubmenu, sortSubmenu } from "../../components/ui/pageMenuItems";
|
||||
import { optionsFromColumns } from "../../lib/sortOptions";
|
||||
import ChannelDiscovery from "./ChannelDiscovery";
|
||||
import TagManager from "./TagManager";
|
||||
import TagManager from "../../features/channel/TagManager";
|
||||
import { useChannelLayout, useChannels, useChannelsActions } from "./channelsContext";
|
||||
import { useNavigationActions } from "../../features/navigation/navigationContext";
|
||||
import { useFeedFilters, useFeedFiltersActions } from "../feed/feedFiltersContext";
|
||||
import { useFeedFilters, useFeedFiltersActions } from "../feed";
|
||||
import { useWizard } from "../../features/wizard/wizardContext";
|
||||
import { useMe } from "../../lib/useMe";
|
||||
import { useTags } from "../../lib/useTags";
|
||||
|
||||
Reference in New Issue
Block a user