Skip to content

Commit

Permalink
Enforce module boundaries with no-restricted-imports
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver committed May 21, 2024
1 parent 5fa98ac commit fd7f697
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 36 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
37 changes: 37 additions & 0 deletions bits/enforce-module-boundaries-with-no-restricted-imports/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Enforce module boundaries with no-restricted-imports
slug: enforce-module-boundaries-with-no-restricted-imports
date: 2024-05-21
tags: typescript, developer-experience, architecture
---

# Enforce module boundaries with no-restricted-imports

Define module boundaries in your project by restricting specific imports using ESLint's `no-restricted-imports` rule.
The rule allows you to prevent certain modules from being imported in specific files or directories.

From an architectural point of view this is useful to enforce module boundaries e.g. to prevent feature A to be imported within feature B, or prevent circular dependencies between modules.

There are also some alternative tools that allow you to define module boundaries such as [Sherrif](https://github.com/softarc-consulting/sheriff) or [Nx](https://nx.dev/features/enforce-module-boundaries).
If you're already using these tools, I think it's better to stick with them as they provide more flexibility and features.
However, I find the ESLint approach to be straightforward and the easiest to configure, and it doesn't require an additional dependency.

For more information about the ESLint rule, refer to the [official ESLint documentation](https://eslint.org/docs/rules/no-restricted-imports), or the TypeScript-variant at the [TypeScript ESLint documentation](https://typescript-eslint.io/rules/no-restricted-imports/). If you're using Biome, see the [Biome documentation](https://biomejs.dev/linter/rules/no-restricted-imports/).

```js{3-13}:.eslintrc.js
module.exports = {
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@feature-a'],
message: 'You cannot import feature A from this module.',
},
],
},
],
},
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Simplify Grouping Arrays in JavaScript with Object.groupBy()
slug: simplify-grouping-arrays-in-javascript-with-objectgroupby
date: 2024-02-13
tags: TypeScript, JavaScript
tags: TypeScript
---

# Simplify Grouping Arrays in JavaScript with Object.groupBy()
Expand Down
1 change: 0 additions & 1 deletion src/lib/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export function parseFileToHtmlAndMeta(file): {
slug: string;
date: string;
tags: string[];
no_banner?: boolean;
};
assetsSrc: string;
} {
Expand Down
35 changes: 25 additions & 10 deletions src/routes/bits/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,35 @@

{#each bits as bit, i}
{#if queryParts.length === 0 || bit.metadata.tags.some((tag) => tagSelected(tag))}
<h2>
{bits.length - i}.
<a
href="/bits/{bit.metadata.slug}"
class="mark-hover"
data-sveltekit-preload-data="hover"
style:--bit-title="bit-title-{bit.metadata.slug}">{bit.metadata.title}</a
>
</h2>
{@html bit.html}
<div class="bit">
<h2>
{bits.length - i}.
<a
href="/bits/{bit.metadata.slug}"
class="mark-hover"
data-sveltekit-preload-data="hover"
style:--bit-title="bit-title-{bit.metadata.slug}">{bit.metadata.title}</a
>
</h2>
{@html bit.html}

<hr />
</div>
{/if}
{/each}

<style>
hr {
border: none;
border-top: solid 2px var(--text-color);
margin: 4rem -2rem;
}
.bit:nth-child(even) hr {
transform: rotate(2deg);
}
.bit:nth-child(odd) hr {
transform: rotate(-2deg);
}
button {
color: var(--text-color-light);
transition: color 0.2s ease;
Expand Down
38 changes: 17 additions & 21 deletions src/routes/bits/[slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,33 +42,29 @@
<meta name="og:description" content={bit.metadata.description} />
<meta name="og:type" content="article" />

{#if bit.metadata.no_banner === false}
<meta name="image" content={bit.metadata.banner} />
<meta name="twitter:image" content={bit.metadata.banner} />
<meta name="og:image" content={bit.metadata.banner} />
{/if}
<meta name="image" content={bit.metadata.banner} />
<meta name="twitter:image" content={bit.metadata.banner} />
<meta name="og:image" content={bit.metadata.banner} />
</svelte:head>

<svelte:window bind:scrollY />

<div></div>
<h1 style:--bit-title="bit-title-{bit.metadata.slug}">{bit.metadata.title}</h1>
{#if bit.metadata.no_banner === false}
<img
src={bit.metadata.banner}
alt="banner"
style="--scroll: {(scrollY ?? 0) <= 150
? 1
: scrollY <= 200
? 0.75
: scrollY <= 300
? 0.5
: scrollY <= 500
? 0.25
: 0}"
loading="lazy"
/>
{/if}
<img
src={bit.metadata.banner}
alt="banner"
style="--scroll: {(scrollY ?? 0) <= 150
? 1
: scrollY <= 200
? 0.75
: scrollY <= 300
? 0.5
: scrollY <= 500
? 0.25
: 0}"
loading="lazy"
/>

{@html bit.html}

Expand Down
3 changes: 0 additions & 3 deletions src/routes/bits/_bits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const bits: {
slug: string;
date: string;
tags: string[];
no_banner: boolean;
};
}[] = [];

Expand All @@ -22,7 +21,6 @@ export async function readBits(): Promise<
slug: string;
date: string;
tags: string[];
no_banner: boolean;
};
}[]
> {
Expand Down Expand Up @@ -53,7 +51,6 @@ export async function readBits(): Promise<
slug: metadata.slug,
date: ISODate(metadata.date),
tags: tags.map((t) => t.toLowerCase()),
no_banner: metadata.no_banner ?? false,
},
};
})
Expand Down

0 comments on commit fd7f697

Please sign in to comment.