К основному содержанию
скилл CX Codex

module-pattern — скилл для Claude Code: что делает и как установить

Обучает ИИ-агента делить JavaScript и TypeScript на изолированные модули через ES2015. Помогает скрыть внутренние переменные и настроить чистый экспорт.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add PatternsDev/skills --skill module-pattern -a claude-code
Открыть на GitHub

Что делает module-pattern

Скилл задаёт правила инкапсуляции для файлов **/*.js и **/*.ts. Он ориентирует агента на синтаксис ES2015 с ключевыми словами import и export. Переменные и вспомогательные функции остаются закрытыми внутри файла, если их явно не экспортировали. Это предотвращает случайное засорение глобальной области видимости и исключает конфликты имён.

Инструкции описывают работу с именованными и дефолтными экспортами, псевдонимами через as и сборными импортами через звёздочку. Для уменьшения начального размера бандла скилл предписывает вызывать динамический import(). Код проектируется с прицелом на tree-shaking, чтобы сборщик мог отсечь неиспользуемые ветки.

Для тривиальных одноразовых скриптов модульная структура создаёт лишь лишний шум. Инструкция прямо советует избегать устаревших обёрток на базе IIFE, если проект уже собирается современным бандлером.

Какие задачи решает

  • Изолировать приватные переменные от глобальной области видимости
  • Разделить монолитный файл на переиспользуемые модули ES2015
  • Настроить именованный и дефолтный экспорт для поддержки tree-shaking
  • Устранить конфликты имён функций через псевдонимы as

Примеры запросов агенту

  • Разбей math.js на модульные функции с именованным экспортом и спрячь вспомогательные константы
  • Перепиши этот скрипт на стандартные ES2015-модули и настрой динамический импорт
  • Выдели приватную логику калькулятора, чтобы наружу уходили только методы add и multiply

Как установить module-pattern

1Через Skills CLI (Vercel)

npx skills add PatternsDev/skills --skill module-pattern -a claude-code

2Вручную: положить файлы

~/.claude/skills/module-pattern/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/module-pattern/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора44

command-pattern Обучает агента паттерну «Команда» для JavaScript и TypeScript. Помогает разделить вызов операции и её выполнение, настроить очередь задач или историю отмены. CX Codex +1 645установок singleton-pattern Обучает реализации паттерна «Одиночка» в JavaScript и TypeScript для создания единого экземпляра класса. Пригодится при настройке общих ресурсов или глобальной конфигурации. CX Codex +1 637установок observer-pattern Скилл объясняет паттерн наблюдателя и подсказывает агенту, как строить слабосвязанную подписку на события в JS и TS. CX Codex +1 638установок factory-pattern Учит агента создавать объекты через фабричные функции. Пригодится, когда логика создания объектов зависит от конфигурации или окружения. CX Codex +1 634установок islands-architecture Скилл объясняет паттерн островной архитектуры и частичной гидратации. Пригодится, когда страница почти вся статичная, а интерактив нужен точечно. CX Codex +1 624установок provider-pattern Учит агента выносить общие данные в React Context и раздавать их через Provider, когда пропсы приходится тянуть через десяток компонентов. CX Codex +1 620установок proxy-pattern Скилл объясняет паттерн Proxy в JavaScript: перехват чтения и записи свойств объекта, валидация и логирование. Пригодится, когда агенту нужно править такой код. CX Codex +1 612установок mediator-pattern Скилл объясняет паттерн «посредник»: компоненты общаются через одну точку, а не напрямую. Пригодится, когда связей между объектами стало слишком много. CX Codex +1 608установок

Похожие

webflow-code-component:pre-deploy-check webflow Проверяет компоненты Webflow Code Components перед публикацией: размер бандла, зависимости, пропсы, SSR и стили. Пригодится, когда до webflow library share остался один шаг. CX Codex +1 988установок nextjs-client-cookie-pattern wsimmonds Скилл показывает, как из клиентского компонента Next.js выставить серверную куку через server action. Пригодится для тем, авторизации и языковых настроек. CX Codex +1 323установок expo-module expo Справочник по разработке нативных модулей и view-компонентов на Swift, Kotlin и TypeScript для Expo приложений. Используй, когда пишешь новый модуль или добавляешь нативную функциональность — камеру, датчики, системные API. CX Codex +1 45 100установок typescript-review metabase Проверяет изменения в TypeScript и JavaScript по правилам Metabase. Пригодится для ревью pull request и diff с фронтенд-кодом. CX Codex +1 2 300установок electron-development Mindrally Скилл задаёт агенту правила разработки десктопных приложений на Electron: разделение процессов, IPC, безопасность окон. CX Codex +1 1 300установок rollup-bundler Mindrally Скилл задаёт агенту правила конфигурации Rollup.js: форматы вывода, внешние зависимости, tree-shaking и плагины для сборки библиотек. CX Codex +1 657установок

Рядом в теме «Фронтенд и UI»

Всё по теме «Фронтенд и UI» →

Вопросы о module-pattern

Как установить module-pattern в Claude Code?

Выполните в терминале команду: npx skills add PatternsDev/skills --skill module-pattern -a claude-code.

Зачем нужен скилл module-pattern?

Он учит языковую модель правильно разделять логику на модули в JavaScript и TypeScript. Это защищает глобальный скоуп от случайных перезаписей.

Когда этот паттерн применять не стоит?

Не используйте его в простых коротких скриптах, где модули только усложняют код. Также не нужны IIFE-модули, если в проекте уже настроен сборщик.

Исходный текст

SKILL.md · MIT
---
name: module-pattern
description: Teaches the module pattern for code organization and encapsulation. Use when structuring JavaScript into reusable, maintainable pieces with clear public and private boundaries.
paths:
  - "**/*.js"
  - "**/*.ts"
license: MIT
metadata:
  author: patterns.dev
  version: "1.1"
related_skills:
  - "singleton-pattern"
  - "observer-pattern"
---

# Module Pattern

## Table of Contents

- [When to Use](#when-to-use)
- [When NOT to Use](#when-not-to-use)
- [Instructions](#instructions)
- [Details](#details)
- [Source](#source)

As your application and codebase grow, it becomes increasingly important to keep your code maintainable and separated. The module pattern allows you to split up your code into smaller, reusable pieces.

Besides being able to split your code into smaller reusable pieces, modules allow you to keep certain values within your file _private_. Declarations within a module are scoped (_encapsulated_) to that module, by default. If we don't explicitly export a certain value, that value is not available outside that module. This reduces the risk of name collisions for values declared in other parts of your codebase, since the values are not available on the global scope.

## When to Use

- Use this when you need to organize code into maintainable, encapsulated units
- This is helpful when you want to keep certain values private to a module and avoid global scope pollution
- Use this to enable tree-shaking and reduce bundle sizes

## When NOT to Use

- When ES2015 native modules with static `import`/`export` are available — prefer static imports for better tooling and tree-shaking
- When the IIFE-based module pattern is used purely for encapsulation in a codebase that already uses a bundler
- For trivial scripts where module overhead adds unnecessary complexity

## Instructions

- Use ES2015 `import`/`export` syntax for module definitions
- Use named exports for multiple values and default exports for the primary value of a module
- Keep non-exported values private to reduce naming collision risks
- Use dynamic `import()` for on-demand module loading to reduce initial bundle size

## Details

### ES2015 Modules

ES2015 introduced built-in JavaScript modules. A module is a file containing JavaScript code, with some difference in behavior compared to a normal script.

Let's look at an example of a module called `math.js`, containing mathematical functions.

```js
export function add(x, y) {
  return x + y;
}

export function multiply(x) {
  return x * 2;
}

export function subtract(x, y) {
  return x - y;
}

export function square(x) {
  return x * x;
}
```

We have a `math.js` file containing some simple mathematical logic. We have functions that allow users to add, multiply, subtract, and get the square of values that they pass.

In order to make the functions from `math.js` available to other files, we first have to _export_ them. In order to export code from a module, we can use the `export` keyword. One way of exporting the functions, is by using _named exports_: we can simply add the `export` keyword in front of the parts that we want to publicly expose.

We can then import the values in another file using the `import` keyword. To let JavaScript know from which module we want to import these functions, we need to add a `from` value and the relative path to the module.

```js
import { add, multiply, subtract, square } from "./math.js";
```

A great benefit of having modules, is that we _only have access to the values that we explicitly exported_ using the `export` keyword. Values that we didn't explicitly export using the `export` keyword, are only available within that module.

Let's create a value that should only be referenceable within the `math.js` file, called `privateValue`.

```js
const privateValue = "This is a value private to the module!";

export function add(x, y) {
  return x + y;
}

export function multiply(x) {
  return x * 2;
}

export function subtract(x, y) {
  return x - y;
}

export function square(x) {
  return x * x;
}
```

Notice how we didn't add the `export` keyword in front of `privateValue`. Since we didn't export the `privateValue` variable, we don't have access to this value outside of the `math.js` module!

By keeping the value private to the module, there is a reduced risk of accidentally polluting the global scope. You don't have to fear that you will accidentally overwrite values created by developers using your module, that may have had the same name as your private value: it prevents naming collisions.

Sometimes, the names of the exports could collide with local values. In this case, we can _rename_ the imported values, by using the `as` keyword.

```js
import {
  add as addValues,
  multiply as multiplyValues,
  subtract,
  square,
} from "./math.js";

function add(...args) {
  return args.reduce((acc, cur) => cur + acc);
}

function multiply(...args) {
  return args.reduce((acc, cur) => cur * acc);
}

/* From math.js module */
addValues(7, 8);
multiplyValues(8, 9);
subtract(10, 3);
square(3);

/* From index.js file */
add(8, 9, 2, 10);
multiply(8, 9, 2, 10);
```

Besides named exports, you can also use a _default export_. You can only have **one** default export per module.

```js
export default function add(x, y) {
  return x + y;
}

export function multiply(x) {
  return x * 2;
}

export function subtract(x, y) {
  return x - y;
}

export function square(x) {
  return x * x;
}
```

The difference between named exports and default exports, is the way the value is exported from the module, effectively changing the way we have to import the value.

Previously, we had to use the brackets for our named exports: `import { module } from 'module'`.
With a default export, we can import the value _without_ the brackets: `import module from 'module'`.

```js
import add, { multiply, subtract, square } from "./math.js";

add(7, 8);
multiply(8, 9);
subtract(10, 3);
square(3);
```

Since JavaScript knows that this value is always the value that was exported by default, we can give the imported default value another name than the name we exported it with.

We can also import all exports from a module, meaning all named exports _and_ the default export, by using an asterisk `*` and giving the name we want to import the module as.

```js
import * as math from "./math.js";

math.default(7, 8);
math.multiply(8, 9);
math.subtract(10, 3);
math.square(3);
```

In this case, we're importing _all_ exports from a module. Be careful when doing this, since you may end up unnecessarily importing values.

Using the `*` only imports all exported values. Values private to the module are still not available in the file that imports the module, unless you explicitly exported them.

### React

When building applications with React, you often have to deal with a large amount of components. Instead of writing all of these components in one file, we can separate the components in their own files, essentially creating a module for each component.

We can split components into separate files:

- `TodoList.js` for the `List` component
- `Button.js` for the customized `Button` component
- `Input.js` for the customized `Input` component

Throughout the app, we don't want to use the default `Button` and `Input` component, imported from a UI library. Instead, we want to use our custom version of the components, by adding custom styles to it defined in the `styles` object in their files. Rather than importing the default `Button` and `Input` component each time in our application and adding custom styles to it over and over, we can now simply import the default `Button` and `Input` component once, add styles, and export our custom component.

Notice how we can have an object called `style` in both `Button.js` and `Input.js`. Since this value is _module-scoped_, we can reuse the variable name without risking a name collision.

### Dynamic import

When importing all modules on the top of a file, all modules get loaded before the rest of the file. In some cases, we only need to import a module based on a certain condition. With a **dynamic import**, we can import modules on demand.

```js
import("module").then((module) => {
  module.default();
  module.namedExport();
});

// Or with async/await
(async () => {
  const module = await import("module");
  module.default();
  module.namedExport();
})();
```

By dynamically importing modules, we can reduce the page load time. We only have to load, parse, and compile the code that the user really needs, _when_ the user needs it.

Besides being able to import modules on-demand, the `import()` function can receive an expression. It allows us to pass template literals, in order to dynamically load modules based on a given value.

```js
const res = await import(`../assets/dog${num}.png`);
```

This way, we're not dependent on hard-coded module paths. It adds flexibility to the way you can import modules based on user input, data received from an external source, the result of a function, and so on.


With the module pattern, we can encapsulate parts of our code that should not be publicly exposed. This prevents accidental name collision and global scope pollution, which makes working with multiple dependencies and namespaces less risky. In order to be able to use ES2015 modules in all JavaScript runtimes, a transpiler such as [Babel](https://babeljs.io/) is needed.

## Source

- [patterns.dev/vanilla/module-pattern](https://patterns.dev/vanilla/module-pattern)

© patterns.dev · MIT · PatternsDev/skills

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой