Механизм server.fs управляет доступом dev-сервера Vite к
файловой системе. Во время разработки Vite активно работает с локальными
файлами: загружает модули, обрабатывает зависимости, читает
конфигурацию, импортирует ресурсы и обслуживает содержимое проекта через
HTTP. Без ограничений такой доступ представлял бы серьёзную угрозу
безопасности.
Секция server.fs позволяет:
server.fsПо умолчанию Vite разрешает доступ только к определённым директориям проекта. Попытка обратиться к файлам за пределами допустимой области приводит к ошибке:
403 Restricted
Это особенно заметно при:
Пример проблемы:
import config from '../. ./shared/config.js'
Если каталог shared находится вне разрешённой области,
Vite заблокирует доступ.
server.fsКонфигурация располагается внутри секции server.
import { defineConfig } from 'vite'
export default defineConfig({
server: {
fs: {
}
}
})
Доступны параметры:
| Параметр | Назначение |
|---|---|
allow |
список разрешённых директорий |
deny |
список запрещённых файлов |
strict |
режим строгой проверки доступа |
server.fs.strictstrict включает строгую файловую изоляцию.
export default defineConfig({
server: {
fs: {
strict: true
}
}
})
При активном режиме Vite:
strict: trueРазрешается доступ:
allow.Запрещается:
export default defineConfig({
server: {
fs: {
strict: false
}
}
})
После отключения ограничения существенно ослабляются.
Dev-сервер получает возможность читать:
Это может привести к:
.env;strict: falseОтключение иногда применяется:
Для обычной разработки рекомендуется сохранять
strict: true.
server.fs.allowallow добавляет дополнительные пути, доступные
dev-серверу.
export default defineConfig({
server: {
fs: {
allow: ['..']
}
}
})
Теперь Vite сможет читать файлы уровнем выше текущего проекта.
import path from 'path'
export default defineConfig({
server: {
fs: {
allow: [
path.resolve(__dirname, '../shared')
]
}
}
})
Типичная структура:
workspace/
├── apps/
│ └── frontend/
├── packages/
│ └── ui/
Конфигурация:
import path from 'path'
export default defineConfig({
server: {
fs: {
allow: [
path.resolve(__dirname, '../. ./packages')
]
}
}
})
Теперь приложение может импортировать:
import { Button } from '../. ./packages/ui'
fs: {
allow: [
'/shared',
'/configs',
'/packages'
]
}
Vite корректно работает с абсолютными путями:
fs: {
allow: [
'D:/workspace/shared'
]
}
На Linux:
fs: {
allow: [
'/home/dev/shared'
]
}
Vite умеет автоматически находить workspace root.
Поддерживаются:
pnpm-workspace.yamllerna.jsonpackage.json с workspacesНапример:
repo/
├── package.json
├── apps/
├── packages/
В этом случае Vite может автоматически разрешить workspace-уровень
без ручного указания allow.
server.fs.denydeny запрещает доступ к определённым файлам даже при
наличии разрешений.
export default defineConfig({
server: {
fs: {
deny: ['.env', '.env.*']
}
}
})
Vite по умолчанию блокирует доступ к:
.env.env.local.env.productionЭто предотвращает случайную утечку конфиденциальных данных через браузер.
fs: {
deny: [
'*.pem',
'*.key',
'*.crt'
]
}
fs: {
deny: [
'secret/**'
]
}
При запросе файла Vite:
deny;allow;server.fs
и импорта модулейОграничения применяются ко всем типам загрузки:
Структура:
project/
├── node_modules/
└── linked-package -> ../shared-package
Даже если symlink находится внутри проекта, физический путь может располагаться вне разрешённой области.
import path from 'path'
export default defineConfig({
server: {
fs: {
allow: [
path.resolve(__dirname, '../shared-package')
]
}
}
})
При работе через Docker:
fs: {
allow: [
'/app',
'/workspace'
]
}
В WSL пути Linux и Windows отличаются.
Пример:
fs: {
allow: [
'/mnt/c/projects/shared'
]
}
root и server.fs.allowrootОпределяет:
index.html;allowОпределяет:
403 RestrictedThe request url is outside of Vite serving allow list.
import file from '../. ./. ./config.js'
allowfs: {
allow: []
}
Vite не всегда корректно определяет workspace root.
Физический путь находится вне разрешённой области.
console.log(
path.resolve(__dirname, '../shared')
)
Linux/macOS:
readlink -f node_modules/package
Windows PowerShell:
Get-Item node_modules/package
fs: {
strict: false
}
Если проблема исчезла — причина в ограничениях доступа.
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
server: {
fs: {
strict: true,
allow: [
path.resolve(__dirname, '../. ./packages'),
path.resolve(__dirname, '../. ./shared')
],
deny: [
'.env',
'.env.*',
'*.pem',
'*.key'
]
}
}
})
При неправильной настройке возможно:
.env;id_rsa
.env
database.yml
config.production.json
allowПлохо:
allow: ['..']
Лучше:
allow: [
'/shared/ui'
]
strict без необходимостиstrict: true
должен оставаться стандартным режимом.
deny: [
'*.pem',
'*.key',
'.env*'
]
Абсолютные пути уменьшают вероятность ошибок.
Параметры server.fs работают только во время
разработки.
На production-сборку они не влияют.
Команда:
vite build
не использует ограничения dev-сервера.
Некоторые плагины:
В таких случаях требуется корректный allow.
Пример:
fs: {
allow: [
'/packages',
'/generated'
]
}
Во время обработки запроса Vite использует:
Это делает dev-сервер существенно безопаснее обычного статического файлового сервера.
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
server: {
fs: {
strict: true,
allow: [
path.resolve(__dirname, '../shared'),
path.resolve(__dirname, '../packages/ui')
],
deny: [
'.env',
'.env.*',
'*.pem',
'*.key',
'*.crt'
]
}
}
})