Автообновление npm зависимостей
Многие до сих пор проверяют зависимости
Но есть инструмент, который сделает это удобнее и проще: npm-check-updates (ncu).
Установка:
Показать обновления до определенного уровня:
Показать обновления определенных пакетов:
Проверка обновлений глобальных зависимостей:
Игнорирование пакетов:
⚠️ Пока нет возможности ограничить пакеты только определенным интервалом версий.
#npm
Многие до сих пор проверяют зависимости
package.json вручную или через npm outdated.Но есть инструмент, который сделает это удобнее и проще: npm-check-updates (ncu).
Установка:
npm install --global npm-check-updates
ncu # показать обновления
ncu -u # обновить package.json
npm install # установить зависимости
Показать обновления до определенного уровня:
ncu --target patch
ncu --target minor
ncu --target latest
Показать обновления определенных пакетов:
ncu -f webpack # только webpack
ncu -x webpack # всё, кроме webpack
Проверка обновлений глобальных зависимостей:
ncu -g
Игнорирование пакетов:
// .ncurc
{
"reject": ["webpack", "eslint", "@types/*"]
}
⚠️ Пока нет возможности ограничить пакеты только определенным интервалом версий.
npm-check-updates даёт полный контроль, гибкость и удобство в настройке, лучше подходит для автоматизации процесса.#npm
Улучшение дефолтного поведения TypeScript
ts-reset — утилита, которая расширяет стандартную типизацию в TypeScript, устраняя устаревшие и нестрогие участки в базовых API.
Подключается на уровне проекта и повышает строгость типизации в ряде API.
Установка:
Также возможно установить отдельные правила:
Основные изменения:
•
•
•
•
⚠️ Не рекомендуется использовать в библиотеках, так как изменения глобальных типов могут повлиять на конечные проекты, в которые библиотека будет установлена.
Внутри существующих проектов подключение
Если после подключения появляются ошибки — скорее всего, это участки, где типизация и так была небезопасной.
#npm #typescript
ts-reset — утилита, которая расширяет стандартную типизацию в TypeScript, устраняя устаревшие и нестрогие участки в базовых API.
Подключается на уровне проекта и повышает строгость типизации в ряде API.
Установка:
npm install --save-dev ts-reset
// reset.d.ts
import "@total-typescript/ts-reset";
Также возможно установить отдельные правила:
// reset.d.ts
import "@total-typescript/ts-reset/json-parse";
import "@total-typescript/ts-reset/fetch";
Основные изменения:
•
JSON.parse, .json(), localStorage, sessionStorage теперь возвращают unknown, а не any•
.filter(Boolean) корректно удаляет falsy-значения•
.includes(), .indexOf(), Set.has(), Map.has() не требуют точного сравнения (чего и пытаемся добиться, вызывая их)•
Array.isArray() больше не считает any[] безопасным⚠️ Не рекомендуется использовать в библиотеках, так как изменения глобальных типов могут повлиять на конечные проекты, в которые библиотека будет установлена.
Внутри существующих проектов подключение
ts-reset, как правило, не вызывает проблем: типы становятся строже, но остаются совместимыми с корректным кодом.Если после подключения появляются ошибки — скорее всего, это участки, где типизация и так была небезопасной.
#npm #typescript
Total TypeScript
TS Reset - Official Docs
Learn how to use TypeScript to level-up your applications as a web developer through exercise driven self-paced workshops and tutorials hosted by TypeScript wizard Matt Pocock.
Типизация querySelector
typed-query-selector — улучшение типизации методов
⚠️ Требуется TypeScript версии 4.1 или выше.
Установка:
Результат:
#npm #typescript
typed-query-selector — улучшение типизации методов
querySelector и querySelectorAll с выводом типов на основе CSS-селекторов.⚠️ Требуется TypeScript версии 4.1 или выше.
Установка:
npm install --save-dev typed-query-selector
// typed-query-selector.d.ts
import "typed-query-selector";
Результат:
document.querySelector("div#app"); // HTMLDivElement
document.querySelector("div#app > form#login"); // HTMLFormElement
document.querySelectorAll("span.badge"); // NodeListOf<HTMLSpanElement>
document.querySelector("button#submit"); // HTMLButtonElement#npm #typescript
Аннотации над текстом с тегом ruby
Часто используется для японского и китайского, но работает и для любых других языков.
Элементы
Пример:
Зачем `<rp>`?
Обычно содержит скобки вокруг
#html
ruby (MDN) — HTML-элемент для аннотирования слов: переводы, транскрипции, пояснения.Часто используется для японского и китайского, но работает и для любых других языков.
Элементы
<ruby>, <rt> и <rp> входят в Baseline: поддерживаются всеми современными браузерами.Пример:
we usually say <ruby>привет<rp>(</rp><rt>hi</rt><rp>)</rp></ruby> as a greeting
Зачем `<rp>`?
<rp> (ruby parentheses) отображается только в браузерах без поддержки <ruby>.Обычно содержит скобки вокруг
<rt>, чтобы сохранить читаемость: привет (hi)#html
Переход с CommonJS на ESM
Модули на основе
Современный стек (включая Node.js) постепенно переходит на ESM (ECMAScript Modules),
который стал официальным стандартом.
Зачем рассматривать переход:
- ESM поддерживается во всех современных сборщиках
- даёт доступ к
- новые API Node.js, например
- всё больше библиотек публикуются только в ESM-формате
Подробнее: antfu.me/posts/move-on-to-esm-only
Подробная инструкция по миграции от sindresorhus
Для постепенного перехода можно включить правило prefer-module из
⚠️ Переход на ESM может быть затруднён, особенно в CLI-приложениях и проектах где используются зависимости, которые давно не обновлялись.
В таких случаях лучше придерживаться CommonJS до появления стабильной поддержки.
ESM — направление развития платформы. Если проект позволяет — стоит начинать миграцию. Но для некоторых типов приложений переход пока может быть преждевременным.
#build
Модули на основе
require() и module.exports (CommonJS) — устаревающий формат.Современный стек (включая Node.js) постепенно переходит на ESM (ECMAScript Modules),
который стал официальным стандартом.
Зачем рассматривать переход:
- ESM поддерживается во всех современных сборщиках
- даёт доступ к
import/export, top-level await, tree-shaking- новые API Node.js, например
import.meta, ориентированы на ESM- всё больше библиотек публикуются только в ESM-формате
Подробнее: antfu.me/posts/move-on-to-esm-only
Подробная инструкция по миграции от sindresorhus
Для постепенного перехода можно включить правило prefer-module из
eslint-plugin-unicorn.⚠️ Переход на ESM может быть затруднён, особенно в CLI-приложениях и проектах где используются зависимости, которые давно не обновлялись.
В таких случаях лучше придерживаться CommonJS до появления стабильной поддержки.
ESM — направление развития платформы. Если проект позволяет — стоит начинать миграцию. Но для некоторых типов приложений переход пока может быть преждевременным.
#build
Pinia: стоит ли использовать setup store
Документация Pinia описывает два способа создания стора: setup store и option-store.
Option-синтаксис:
Setup-синтаксис:
Дополнительно: приватное состояние возможно только через отдельные store-инстансы — например, так:
Подробнее:
– Pinia docs: Setup Stores
– Mastering Pinia: Private State
Таким образом, можно использовать
В большинстве проектов предпочтительнее продолжать использовать
#pinia
Документация Pinia описывает два способа создания стора: setup store и option-store.
Option-синтаксис:
export const useCounter = defineStore("counter", {
state: () => ({ count: 0 }),
actions: {
increment() { this.count++; }
}
});Setup-синтаксис:
export const useCounter = defineStore("counter", () => {
const count = ref(0);
function increment() { count.value++; }
return { count, increment }
});Setup store позволяет использовать Composition API внутри стора, но имеет ряд ограничений:Необходимо вручную вернуть все переменные и методы из setup().
Пропущенные значения приведут к проблемам с SSR, Vue Devtools и сторонними плагинами.
Типизация и линтинг работают ограниченно, проверки на уровне TS/ESLint отсутствуют.
Дополнительно: приватное состояние возможно только через отдельные store-инстансы — например, так:
const usePrivateState = defineStore("store-private", () => {
const secret = ref('Never seen outside');
return { secret }
});
export const useStore = defineStore("store", () => {
const privateState = usePrivateState();
const censoredSecret = computed(() => '*'.repeat(privateState.secret.length));
return { censoredSecret }
});Подробнее:
– Pinia docs: Setup Stores
– Mastering Pinia: Private State
Таким образом, можно использовать
setup store, однако мы не рекомендуем это делать, пока его архитектура остаётся неочевидной, а ошибки не выявляются инструментами.В большинстве проектов предпочтительнее продолжать использовать
option store — он безопаснее, прозрачнее и лучше поддерживается.#pinia
Агрегатор информации по доменным зонам
Если вы когда-либо покупали домен, то знаете, как это выглядит: нужно открыть десяток сайтов регистраторов, вручную вбивать доменные имена, разбираться в условиях, ждать загрузки, обходить рекламу…
А потом выясняется, что продление стоит в 3 раза дороже, а приватный WHOIS — платная опция.
tld-list решает все вопросы одной страницей.
Это агрегатор всей информации по доменным зонам:
- показывает цену регистрации и продления у популярных регистраторов (включая скрытые комиссии)
- отображает, какие зоны поддерживают WHOIS privacy
- позволяет отфильтровать домены по длине, символам, доступности
- сортирует по цене и особенностям (например, можно исключить зоны с премиум-ценами)
Никаких устаревших подборок, перебора регистраторов вручную и вопросов "а сколько .dev стоит у Namecheap?".
tld-list делает это за вас.
#service
Если вы когда-либо покупали домен, то знаете, как это выглядит: нужно открыть десяток сайтов регистраторов, вручную вбивать доменные имена, разбираться в условиях, ждать загрузки, обходить рекламу…
А потом выясняется, что продление стоит в 3 раза дороже, а приватный WHOIS — платная опция.
tld-list решает все вопросы одной страницей.
Это агрегатор всей информации по доменным зонам:
- показывает цену регистрации и продления у популярных регистраторов (включая скрытые комиссии)
- отображает, какие зоны поддерживают WHOIS privacy
- позволяет отфильтровать домены по длине, символам, доступности
- сортирует по цене и особенностям (например, можно исключить зоны с премиум-ценами)
Никаких устаревших подборок, перебора регистраторов вручную и вопросов "а сколько .dev стоит у Namecheap?".
tld-list делает это за вас.
#service
Tld-List
Compare Prices of All Top-Level Domains | TLD-List
Compare the prices of 3,495 domain extensions from 54 registrars. Check domain availability, discover free features, and find the best domain registrar.
Pinia: запрет неявной мутации
Одна из главных причин использовать TypeScript — это предсказуемость.
Любое изменение данных должно быть намеренным: мы либо вызываем функцию, либо обновляем
Но в случае с Pinia возможен такой код:
Явная vs неявная мутация
Что здесь не так?
- ❌
- ✅
Такое поведение ближе к
Именно эта намеренность и отделяет хорошую архитектуру от хрупкой.
Pinia и неявные мутации
В отличие от Vuex, Pinia по умолчанию позволяет напрямую менять
Нет ни
strict режим обсуждался ещё в 2020, но так и остался не реализован.
Как запретить неявные мутации
Мы можем вернуть контроль сами через типизацию. Делаем
Теперь:
Pinia предлагает гибкость, но вместе с ней — уязвимость.
Если вы хотите, чтобы изменения
Мы не ограничиваем возможности Pinia, мы лишь возвращаем понятную дисциплину, которая особенно нужна в команде или на долгосрочном проекте.
#pinia #typescript
Одна из главных причин использовать TypeScript — это предсказуемость.
Любое изменение данных должно быть намеренным: мы либо вызываем функцию, либо обновляем
ref.Но в случае с Pinia возможен такой код:
const store = useDummyStore()
store.stateValue = null // ❌ прямая мутация state, но нет ошибки
Явная vs неявная мутация
Что здесь не так?
- ❌
store.stateValue = null — выглядит как поле объекта, но на самом деле мутирует глобальное хранилище напрямую.- ✅
storeToRefs(store).stateValue.value = null — требует предварительного шага, вызов storeToRefs, и работы с .value, что делает намерение очевидным.Такое поведение ближе к
commit() из Vuex: мы не просто что-то присваиваем, мы просим хранилище редактировать свой state.Именно эта намеренность и отделяет хорошую архитектуру от хрупкой.
Pinia и неявные мутации
В отличие от Vuex, Pinia по умолчанию позволяет напрямую менять
state.Нет ни
mutations, ни встроенного запрета.strict режим обсуждался ещё в 2020, но так и остался не реализован.
Как запретить неявные мутации
Мы можем вернуть контроль сами через типизацию. Делаем
state доступным только для чтения:// env.d.ts
declare module 'pinia' {
export interface StoreDefinition<
Id extends string = string,
S extends StateTree = StateTree,
G = _GettersTree<S>,
A = _ActionsTree
> {
(pinia?: Pinia | null | undefined, hot?: StoreGeneric): Store<Id, Readonly<S>, G, A>
}
}
Теперь:
// Прямое присваивание
const store = useDummyStore()
store.stateValue = null // ❌ Error: Cannot assign to 'stateValue' because it is a read-only property
// Посредством storeToRefs
const { stateValue } = storeToRefs(useDummyStore())
stateValue.value = null // ✅
// Посредством action
store.setValue(null) // ✅
Pinia предлагает гибкость, но вместе с ней — уязвимость.
Если вы хотите, чтобы изменения
state всегда были преднамеренными и контролируемыми, настройка Readonly<StateTree> — хорошая отправная точка.Мы не ограничиваем возможности Pinia, мы лишь возвращаем понятную дисциплину, которая особенно нужна в команде или на долгосрочном проекте.
#pinia #typescript
Очистка node_modules от устаревших полифилов
Даже если вы используете Current или LTS версию Node.js, многие популярные пакеты по-прежнему тянут за собой устаревшие полифилы — вплоть до Node.js 4.
Они часто попадают в проект как зависимости — например,
Это увеличивает размер node_modules, замедляет установку и даже выполнение кода.
Всё потому, что некоторые из этих полифилов используются вместо нативных API, даже если они уже доступны в среде выполнения, что снижает производительность, хотя в этом нет нужды.
nolyfill — это CLI-инструмент, который автоматически находит и заменяет устаревшие полифилы на безопасные заглушки.
⚠️ Он вам не подойдет, если ваш проект запускается на версии Node.js ниже 12.4.0 или вы разрабатываете под среду, которая не поддерживает ECMAScript2019.
Использование:
Если вы часто меняете зависимости, чтобы не забывать запускать
Современный стек требует современных решений.
#npm
Даже если вы используете Current или LTS версию Node.js, многие популярные пакеты по-прежнему тянут за собой устаревшие полифилы — вплоть до Node.js 4.
Они часто попадают в проект как зависимости — например,
eslint-plugin-import, eslint-plugin-jsx-a11y, eslint-plugin-react.Это увеличивает размер node_modules, замедляет установку и даже выполнение кода.
Всё потому, что некоторые из этих полифилов используются вместо нативных API, даже если они уже доступны в среде выполнения, что снижает производительность, хотя в этом нет нужды.
nolyfill — это CLI-инструмент, который автоматически находит и заменяет устаревшие полифилы на безопасные заглушки.
⚠️ Он вам не подойдет, если ваш проект запускается на версии Node.js ниже 12.4.0 или вы разрабатываете под среду, которая не поддерживает ECMAScript2019.
Использование:
npx nolyfill // Найдёт полифилы в текущем проекте
npx nolyfill install // Заменит их на заглушки
Если вы часто меняете зависимости, чтобы не забывать запускать
nolyfill — добавьте вызов в postinstall:// package.json
{
"scripts": {
"postinstall": "npx nolyfill"
}
}
Современный стек требует современных решений.
nolyfill — это простой способ освободить проект от наследия старых зависимостей и сделать шаг к современному, быстрому и чистому JavaScript.#npm
npm
npm: nolyfill
Speed up your package installation process, reduce your disk usage, extend the lifespan of your precious SSD by reducing your node_modules size.. Latest version: 1.0.44, last published: 3 months ago. Start using nolyfill in your project by running `npm i…
