From 948d493e27c8f4f3bd53738170f47c57d954d9c7 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 4 Apr 2021 14:12:29 +0800 Subject: [PATCH 01/22] fix: new options fsServeRoot to prevent serving unrestricted files (fix #2820) --- packages/vite/src/node/server/index.ts | 9 ++++++++- .../vite/src/node/server/middlewares/static.ts | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 045e1d8dcda389..da1486728b609d 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -120,6 +120,13 @@ export interface ServerOptions { * Should start and end with the `/` character */ base?: string + /** + * Restrict files that can be served by the '/@fs/' plugin. + * + * Default to workspace root that contains `.git`, `package.json` with `workspace` field, + * `pnpm-workspace.yml` or the current project root. + */ + fsServeRoot?: string } /** @@ -438,7 +445,7 @@ export async function createServer( middlewares.use(transformMiddleware(server)) // serve static files - middlewares.use(serveRawFsMiddleware()) + middlewares.use(serveRawFsMiddleware(config)) middlewares.use(serveStaticMiddleware(root, config)) // spa fallback diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index c4c39c68028361..12074002bf6d68 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -72,9 +72,12 @@ export function serveStaticMiddleware( } } -export function serveRawFsMiddleware(): Connect.NextHandleFunction { +export function serveRawFsMiddleware( + config: ResolvedConfig +): Connect.NextHandleFunction { const isWin = os.platform() === 'win32' const serveFromRoot = sirv('/', sirvOptions) + const root = config.server?.fsServeRoot || config.root return (req, res, next) => { let url = req.url! @@ -84,6 +87,18 @@ export function serveRawFsMiddleware(): Connect.NextHandleFunction { // searching based from fs root. if (url.startsWith(FS_PREFIX)) { url = url.slice(FS_PREFIX.length) + + // restrict files out side of `fsServeRoot` + if ( + path + .relative(root, path.isAbsolute(url) ? url : `/${url}`) + .startsWith('../') + ) { + res.statusCode = 403 + res.end() + return + } + if (isWin) url = url.replace(/^[A-Z]:/i, '') req.url = url From d9059184ff5222e0973faf3299307dda9c88b2c3 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 4 Apr 2021 14:32:45 +0800 Subject: [PATCH 02/22] chore: update jsdoc --- packages/vite/src/node/server/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index da1486728b609d..5f0c793698b4a2 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -121,10 +121,9 @@ export interface ServerOptions { */ base?: string /** - * Restrict files that can be served by the '/@fs/' plugin. + * Restrict files that could be served via '/\@fs/'. * - * Default to workspace root that contains `.git`, `package.json` with `workspace` field, - * `pnpm-workspace.yml` or the current project root. + * Default to the project root (`config.root`). */ fsServeRoot?: string } From d4dd1060b78a02d08876c453973f0ec80e56a58f Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 4 Apr 2021 18:35:20 +0800 Subject: [PATCH 03/22] Update packages/vite/src/node/server/middlewares/static.ts Co-authored-by: Shinigami --- packages/vite/src/node/server/middlewares/static.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 12074002bf6d68..77388efcd406e6 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -88,7 +88,7 @@ export function serveRawFsMiddleware( if (url.startsWith(FS_PREFIX)) { url = url.slice(FS_PREFIX.length) - // restrict files out side of `fsServeRoot` + // restrict files outside of `fsServeRoot` if ( path .relative(root, path.isAbsolute(url) ? url : `/${url}`) From f47345b21a86f45defd84ecfe2214d759e0b8774 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 4 Apr 2021 20:02:37 +0800 Subject: [PATCH 04/22] chore: update docs --- docs/config/index.md | 8 ++++++++ packages/vite/src/node/server/index.ts | 4 +++- packages/vite/src/node/server/middlewares/static.ts | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 481c43c5844eec..62a45b25d88314 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -420,6 +420,14 @@ export default async ({ command, mode }) => { File system watcher options to pass on to [chokidar](https://github.com/paulmillr/chokidar#api). +### server.fsServeRoot + +- **Type:** `string` + + Restrict files that could be served via `/@fs/`. Acessing files outside this directory will result a 403. + + Default to [project root](/guide/#index-html-and-project-root). + ## Build Options ### build.target diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 5f0c793698b4a2..d0bbed8f32c075 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -122,8 +122,10 @@ export interface ServerOptions { base?: string /** * Restrict files that could be served via '/\@fs/'. + * Acessing files outside this directory will result a 403. * - * Default to the project root (`config.root`). + * Accepts absolute path or a path relative to project root. + * Default to the project root. */ fsServeRoot?: string } diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 77388efcd406e6..21781327e2a81b 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -77,7 +77,10 @@ export function serveRawFsMiddleware( ): Connect.NextHandleFunction { const isWin = os.platform() === 'win32' const serveFromRoot = sirv('/', sirvOptions) - const root = config.server?.fsServeRoot || config.root + const root = path.resolve( + config.root, + config.server?.fsServeRoot || config.root + ) return (req, res, next) => { let url = req.url! From a0e02211880b13c5163ebd6eb84e952a1e0507e0 Mon Sep 17 00:00:00 2001 From: Shinigami Date: Sun, 4 Apr 2021 20:47:59 +0200 Subject: [PATCH 05/22] Apply suggestions from code review --- docs/config/index.md | 2 +- packages/vite/src/node/server/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 62a45b25d88314..f92d742a0872a0 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -424,7 +424,7 @@ export default async ({ command, mode }) => { - **Type:** `string` - Restrict files that could be served via `/@fs/`. Acessing files outside this directory will result a 403. + Restrict files that could be served via `/@fs/`. Accessing files outside this directory will result in a 403. Default to [project root](/guide/#index-html-and-project-root). diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index d0bbed8f32c075..8dade4b27f3f00 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -122,7 +122,7 @@ export interface ServerOptions { base?: string /** * Restrict files that could be served via '/\@fs/'. - * Acessing files outside this directory will result a 403. + * Accessing files outside this directory will result in a 403. * * Accepts absolute path or a path relative to project root. * Default to the project root. From 7066730f45b3ab970cbf2611ba14dd4d78f5e3b3 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 5 Apr 2021 15:29:32 +0800 Subject: [PATCH 06/22] Update packages/vite/src/node/server/middlewares/static.ts Co-authored-by: patak --- packages/vite/src/node/server/middlewares/static.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 21781327e2a81b..4f98a9561f046a 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -89,19 +89,16 @@ export function serveRawFsMiddleware( // the paths are rewritten to `/@fs/` prefixed paths and must be served by // searching based from fs root. if (url.startsWith(FS_PREFIX)) { - url = url.slice(FS_PREFIX.length) - // restrict files outside of `fsServeRoot` if ( - path - .relative(root, path.isAbsolute(url) ? url : `/${url}`) - .startsWith('../') + normalizePath(path.relative(root, fsPathFromId(url))).startsWith('../') ) { res.statusCode = 403 res.end() return } + url = url.slice(FS_PREFIX.length) if (isWin) url = url.replace(/^[A-Z]:/i, '') req.url = url From 34334d9358395ae4da40e1b1c69b61e68ec1ee5a Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 5 Apr 2021 16:55:19 +0800 Subject: [PATCH 07/22] chore: fix imports --- packages/vite/src/node/server/middlewares/static.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 4f98a9561f046a..4254c0a8bdc2ce 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -4,7 +4,12 @@ import sirv, { Options } from 'sirv' import { Connect } from 'types/connect' import { ResolvedConfig } from '../..' import { FS_PREFIX } from '../../constants' -import { cleanUrl, isImportRequest } from '../../utils' +import { + cleanUrl, + fsPathFromId, + isImportRequest, + normalizePath +} from '../../utils' const sirvOptions: Options = { dev: true, From 3051625c9ae57934c90bc6669a13bccaacac2125 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 13:30:14 +0800 Subject: [PATCH 08/22] chore: add 403 page --- .../src/node/server/middlewares/static.ts | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 4254c0a8bdc2ce..f2792d9f10ab41 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -4,12 +4,7 @@ import sirv, { Options } from 'sirv' import { Connect } from 'types/connect' import { ResolvedConfig } from '../..' import { FS_PREFIX } from '../../constants' -import { - cleanUrl, - fsPathFromId, - isImportRequest, - normalizePath -} from '../../utils' +import { cleanUrl, fsPathFromId, isImportRequest } from '../../utils' const sirvOptions: Options = { dev: true, @@ -95,10 +90,9 @@ export function serveRawFsMiddleware( // searching based from fs root. if (url.startsWith(FS_PREFIX)) { // restrict files outside of `fsServeRoot` - if ( - normalizePath(path.relative(root, fsPathFromId(url))).startsWith('../') - ) { + if (!path.resolve(fsPathFromId(url)).startsWith(root + path.sep)) { res.statusCode = 403 + res.write(renderFsRestrictedHTML()) res.end() return } @@ -113,3 +107,29 @@ export function serveRawFsMiddleware( } } } + +function renderFsRestrictedHTML() { + // to have syntax highlighting and autocompletion in IDE + const html = String.raw + return html` + +

403 Restricted

+

+ For security concern, accessing files outside of project root is + restricted since Vite v2.3.x +

+

+ Refer to docs + https://vitejs.dev/config/#server-fsserveroot + for configurations and more details. +

+ + + ` +} From f4e386947ce1dee0d94a39fbe14bf0dcae4f99ef Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:06:49 +0800 Subject: [PATCH 09/22] feat: search for workspace root --- .../fixtures/none/nested/package.json | 3 ++ .../fixtures/pnpm/nested/package.json | 3 ++ .../__tests__/fixtures/pnpm/package.json | 3 ++ .../fixtures/pnpm/pnpm-workspace.yaml | 0 .../fixtures/yarn/nested/package.json | 3 ++ .../__tests__/fixtures/yarn/package.json | 6 +++ .../node/server/__tests__/search-root.spec.ts | 37 ++++++++++++++ packages/vite/src/node/server/searchRoot.ts | 50 +++++++++++++++++++ 8 files changed, 105 insertions(+) create mode 100644 packages/vite/src/node/server/__tests__/fixtures/none/nested/package.json create mode 100644 packages/vite/src/node/server/__tests__/fixtures/pnpm/nested/package.json create mode 100644 packages/vite/src/node/server/__tests__/fixtures/pnpm/package.json create mode 100644 packages/vite/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml create mode 100644 packages/vite/src/node/server/__tests__/fixtures/yarn/nested/package.json create mode 100644 packages/vite/src/node/server/__tests__/fixtures/yarn/package.json create mode 100644 packages/vite/src/node/server/__tests__/search-root.spec.ts create mode 100644 packages/vite/src/node/server/searchRoot.ts diff --git a/packages/vite/src/node/server/__tests__/fixtures/none/nested/package.json b/packages/vite/src/node/server/__tests__/fixtures/none/nested/package.json new file mode 100644 index 00000000000000..352055cdf83423 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/fixtures/none/nested/package.json @@ -0,0 +1,3 @@ +{ + "private": true +} diff --git a/packages/vite/src/node/server/__tests__/fixtures/pnpm/nested/package.json b/packages/vite/src/node/server/__tests__/fixtures/pnpm/nested/package.json new file mode 100644 index 00000000000000..352055cdf83423 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/fixtures/pnpm/nested/package.json @@ -0,0 +1,3 @@ +{ + "private": true +} diff --git a/packages/vite/src/node/server/__tests__/fixtures/pnpm/package.json b/packages/vite/src/node/server/__tests__/fixtures/pnpm/package.json new file mode 100644 index 00000000000000..352055cdf83423 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/fixtures/pnpm/package.json @@ -0,0 +1,3 @@ +{ + "private": true +} diff --git a/packages/vite/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml b/packages/vite/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/vite/src/node/server/__tests__/fixtures/yarn/nested/package.json b/packages/vite/src/node/server/__tests__/fixtures/yarn/nested/package.json new file mode 100644 index 00000000000000..352055cdf83423 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/fixtures/yarn/nested/package.json @@ -0,0 +1,3 @@ +{ + "private": true +} diff --git a/packages/vite/src/node/server/__tests__/fixtures/yarn/package.json b/packages/vite/src/node/server/__tests__/fixtures/yarn/package.json new file mode 100644 index 00000000000000..ac514d81ca831e --- /dev/null +++ b/packages/vite/src/node/server/__tests__/fixtures/yarn/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "workspaces": [ + "nested" + ] +} diff --git a/packages/vite/src/node/server/__tests__/search-root.spec.ts b/packages/vite/src/node/server/__tests__/search-root.spec.ts new file mode 100644 index 00000000000000..101e06ada1bb84 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/search-root.spec.ts @@ -0,0 +1,37 @@ +import { searchForWorkspaceRoot } from '../searchRoot' +import { resolve } from 'path' + +describe('searchForWorkspaceRoot', () => { + test('pnpm', () => { + const resolved = searchForWorkspaceRoot( + resolve(__dirname, 'fixtures/pnpm/nested'), + 5 + ) + expect(resolved).toBe(resolve(__dirname, 'fixtures/pnpm')) + }) + + test('yarn', () => { + const resolved = searchForWorkspaceRoot( + resolve(__dirname, 'fixtures/yarn/nested'), + 5 + ) + expect(resolved).toBe(resolve(__dirname, 'fixtures/yarn')) + }) + + test('none', () => { + const resolved = searchForWorkspaceRoot( + resolve(__dirname, 'fixtures/none/nested'), + 3 + ) + expect(resolved).toBe(resolve(__dirname, 'fixtures/none/nested')) + }) + + test('deeper', () => { + const resolved = searchForWorkspaceRoot( + resolve(__dirname, 'fixtures/none/nested'), + 10 + ) + // resolved to vite repo's root + expect(resolved).toBe(resolve(__dirname, '../../../../../..')) + }) +}) diff --git a/packages/vite/src/node/server/searchRoot.ts b/packages/vite/src/node/server/searchRoot.ts new file mode 100644 index 00000000000000..adec1fecfb1a26 --- /dev/null +++ b/packages/vite/src/node/server/searchRoot.ts @@ -0,0 +1,50 @@ +import fs from 'fs' +import { dirname } from 'path' +import { join } from 'path' + +// https://github.com/vitejs/vite/issues/2820#issuecomment-812495079 +const ROOT_FILES = [ + '.git', + + // https://pnpm.js.org/workspaces/ + 'pnpm-workspace.yaml' + + // https://rushjs.io/pages/advanced/config_files/ + // 'rush.json', + + // https://nx.dev/latest/react/getting-started/nx-setup + // 'workspace.json', + // 'nx.json' +] + +// npm: https://docs.npmjs.com/cli/v7/using-npm/workspaces#installing-workspaces +// yarn: https://classic.yarnpkg.com/en/docs/workspaces/#toc-how-to-use-it +function hasWorkspacePackageJSON(root: string): boolean { + const path = join(root, 'package.json') + if (!fs.existsSync(path)) return false + const content = JSON.parse(fs.readFileSync(path, 'utf-8')) || {} + return !!content.workspaces +} + +function hasRootFile(root: string): boolean { + for (const file of ROOT_FILES) { + if (fs.existsSync(join(root, file))) return true + } + return false +} + +export function searchForWorkspaceRoot( + current: string, + depth: number, + root = current +): string { + if (depth <= 0) return root + if (hasRootFile(current)) return current + if (hasWorkspacePackageJSON(current)) return current + + const dir = dirname(current) + // reach the fs root + if (dir === current) return root + + return searchForWorkspaceRoot(dir, depth - 1, root) +} From 391ad14076faa5a417e71e29becac5b88758233c Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:09:06 +0800 Subject: [PATCH 10/22] chore: update --- .../vite/src/node/server/middlewares/static.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index f2792d9f10ab41..355fed97978720 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -5,6 +5,7 @@ import { Connect } from 'types/connect' import { ResolvedConfig } from '../..' import { FS_PREFIX } from '../../constants' import { cleanUrl, fsPathFromId, isImportRequest } from '../../utils' +import { searchForWorkspaceRoot } from '../searchRoot' const sirvOptions: Options = { dev: true, @@ -77,9 +78,9 @@ export function serveRawFsMiddleware( ): Connect.NextHandleFunction { const isWin = os.platform() === 'win32' const serveFromRoot = sirv('/', sirvOptions) - const root = path.resolve( + const serveRoot = path.resolve( config.root, - config.server?.fsServeRoot || config.root + config.server?.fsServeRoot || searchForWorkspaceRoot(config.root, 5) ) return (req, res, next) => { @@ -90,9 +91,9 @@ export function serveRawFsMiddleware( // searching based from fs root. if (url.startsWith(FS_PREFIX)) { // restrict files outside of `fsServeRoot` - if (!path.resolve(fsPathFromId(url)).startsWith(root + path.sep)) { + if (!path.resolve(fsPathFromId(url)).startsWith(serveRoot + path.sep)) { res.statusCode = 403 - res.write(renderFsRestrictedHTML()) + res.write(renderFsRestrictedHTML(serveRoot)) res.end() return } @@ -108,15 +109,15 @@ export function serveRawFsMiddleware( } } -function renderFsRestrictedHTML() { +function renderFsRestrictedHTML(root: string) { // to have syntax highlighting and autocompletion in IDE const html = String.raw return html`

403 Restricted

- For security concern, accessing files outside of project root is - restricted since Vite v2.3.x + For security concern, accessing files outside of workspace root + (${root}) is restricted since Vite v2.3.x

Refer to docs From f9141dd0592cc5948f1f8fcb1e7bf9e8c5c73b04 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:14:36 +0800 Subject: [PATCH 11/22] docs: update --- docs/config/index.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/config/index.md b/docs/config/index.md index 69ba0da7bfe3fc..b87b65e68cf917 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -433,7 +433,12 @@ export default async ({ command, mode }) => { Restrict files that could be served via `/@fs/`. Accessing files outside this directory will result in a 403. - Default to [project root](/guide/#index-html-and-project-root). + Vite will search for the root of the potential workspace and use it as default. A valid workspace met the following conditions, otherwise will fallback to the [project root](/guide/#index-html-and-project-root). + - contains `workspaces` field in `package.json` + - contains one of the following directory/file + - `.git` + - `pnpm-workspace.yaml` + - should not be more than 5 levels up than the [project root](/guide/#index-html-and-project-root). ## Build Options From 2f06f538f696eb124c486db11001f00f241e464f Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:21:24 +0800 Subject: [PATCH 12/22] chore: update jsdoc --- packages/vite/src/node/server/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index ce3583c5db3169..4e9ab13dee43de 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -125,7 +125,7 @@ export interface ServerOptions { * Accessing files outside this directory will result in a 403. * * Accepts absolute path or a path relative to project root. - * Default to the project root. + * Will try to search up for workspace root by default. */ fsServeRoot?: string } From c8acfffd35327104956923541c7dad51f2208e5d Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:56:46 +0800 Subject: [PATCH 13/22] chore: remove depth limit --- .../node/server/__tests__/search-root.spec.ts | 20 +++++++------------ .../src/node/server/middlewares/static.ts | 2 +- packages/vite/src/node/server/searchRoot.ts | 6 ++---- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/vite/src/node/server/__tests__/search-root.spec.ts b/packages/vite/src/node/server/__tests__/search-root.spec.ts index 101e06ada1bb84..dd64ac00c43ab8 100644 --- a/packages/vite/src/node/server/__tests__/search-root.spec.ts +++ b/packages/vite/src/node/server/__tests__/search-root.spec.ts @@ -4,32 +4,26 @@ import { resolve } from 'path' describe('searchForWorkspaceRoot', () => { test('pnpm', () => { const resolved = searchForWorkspaceRoot( - resolve(__dirname, 'fixtures/pnpm/nested'), - 5 + resolve(__dirname, 'fixtures/pnpm/nested') ) expect(resolved).toBe(resolve(__dirname, 'fixtures/pnpm')) }) test('yarn', () => { const resolved = searchForWorkspaceRoot( - resolve(__dirname, 'fixtures/yarn/nested'), - 5 + resolve(__dirname, 'fixtures/yarn/nested') ) expect(resolved).toBe(resolve(__dirname, 'fixtures/yarn')) }) - test('none', () => { - const resolved = searchForWorkspaceRoot( - resolve(__dirname, 'fixtures/none/nested'), - 3 - ) - expect(resolved).toBe(resolve(__dirname, 'fixtures/none/nested')) + test('yarn at root', () => { + const resolved = searchForWorkspaceRoot(resolve(__dirname, 'fixtures/yarn')) + expect(resolved).toBe(resolve(__dirname, 'fixtures/yarn')) }) - test('deeper', () => { + test('none', () => { const resolved = searchForWorkspaceRoot( - resolve(__dirname, 'fixtures/none/nested'), - 10 + resolve(__dirname, 'fixtures/none/nested') ) // resolved to vite repo's root expect(resolved).toBe(resolve(__dirname, '../../../../../..')) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 355fed97978720..3a7695fdf0612b 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -80,7 +80,7 @@ export function serveRawFsMiddleware( const serveFromRoot = sirv('/', sirvOptions) const serveRoot = path.resolve( config.root, - config.server?.fsServeRoot || searchForWorkspaceRoot(config.root, 5) + config.server?.fsServeRoot || searchForWorkspaceRoot(config.root) ) return (req, res, next) => { diff --git a/packages/vite/src/node/server/searchRoot.ts b/packages/vite/src/node/server/searchRoot.ts index adec1fecfb1a26..7d210d0bddf171 100644 --- a/packages/vite/src/node/server/searchRoot.ts +++ b/packages/vite/src/node/server/searchRoot.ts @@ -35,16 +35,14 @@ function hasRootFile(root: string): boolean { export function searchForWorkspaceRoot( current: string, - depth: number, root = current ): string { - if (depth <= 0) return root if (hasRootFile(current)) return current if (hasWorkspacePackageJSON(current)) return current const dir = dirname(current) // reach the fs root - if (dir === current) return root + if (!dir || dir === current) return root - return searchForWorkspaceRoot(dir, depth - 1, root) + return searchForWorkspaceRoot(dir, root) } From 5db3fdcc4294ef596847d35c1053cd8e16522071 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 4 May 2021 14:57:59 +0800 Subject: [PATCH 14/22] chore: update docs --- docs/config/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/config/index.md b/docs/config/index.md index b87b65e68cf917..4d984ac2fb2080 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -438,7 +438,6 @@ export default async ({ command, mode }) => { - contains one of the following directory/file - `.git` - `pnpm-workspace.yaml` - - should not be more than 5 levels up than the [project root](/guide/#index-html-and-project-root). ## Build Options From 92b825c2bd07d51c22e3a3f6e3923317565330fa Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Wed, 5 May 2021 15:41:42 +0800 Subject: [PATCH 15/22] Update packages/vite/src/node/server/searchRoot.ts Co-authored-by: Shinigami --- packages/vite/src/node/server/searchRoot.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/vite/src/node/server/searchRoot.ts b/packages/vite/src/node/server/searchRoot.ts index 7d210d0bddf171..bdc4714237bb53 100644 --- a/packages/vite/src/node/server/searchRoot.ts +++ b/packages/vite/src/node/server/searchRoot.ts @@ -27,10 +27,7 @@ function hasWorkspacePackageJSON(root: string): boolean { } function hasRootFile(root: string): boolean { - for (const file of ROOT_FILES) { - if (fs.existsSync(join(root, file))) return true - } - return false + ROOT_FILES.some((file) => fs.existsSync(join(root, file))) } export function searchForWorkspaceRoot( From 3bb52aab1bf6d0b3ac8ac29bd43daa01f1dbece2 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Wed, 5 May 2021 15:53:39 +0800 Subject: [PATCH 16/22] chore: update --- packages/vite/src/node/server/searchRoot.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/searchRoot.ts b/packages/vite/src/node/server/searchRoot.ts index bdc4714237bb53..60cbb2327ae3d4 100644 --- a/packages/vite/src/node/server/searchRoot.ts +++ b/packages/vite/src/node/server/searchRoot.ts @@ -21,13 +21,17 @@ const ROOT_FILES = [ // yarn: https://classic.yarnpkg.com/en/docs/workspaces/#toc-how-to-use-it function hasWorkspacePackageJSON(root: string): boolean { const path = join(root, 'package.json') - if (!fs.existsSync(path)) return false + try { + fs.accessSync(path, fs.constants.R_OK) + } catch (e) { + return false + } const content = JSON.parse(fs.readFileSync(path, 'utf-8')) || {} return !!content.workspaces } function hasRootFile(root: string): boolean { - ROOT_FILES.some((file) => fs.existsSync(join(root, file))) + return ROOT_FILES.some((file) => fs.existsSync(join(root, file))) } export function searchForWorkspaceRoot( From 28c90bcfd43365ef91139a1e1a09f661fafa6952 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Wed, 5 May 2021 21:54:27 +0800 Subject: [PATCH 17/22] Update packages/vite/src/node/server/middlewares/static.ts Co-authored-by: Shinigami --- packages/vite/src/node/server/middlewares/static.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 3a7695fdf0612b..b440223e67917f 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -121,9 +121,9 @@ function renderFsRestrictedHTML(root: string) {

Refer to docs - https://vitejs.dev/config/#server-fsserveroot + + https://vitejs.dev/config/#server-fsserveroot + for configurations and more details.