Skip to main content

Frequently asked questions

Other resources

Svelte FAQvite-plugin-svelte FAQ も、これらのライブラリに起因する疑問点には役立ちますのでご参照ください。

What can I make with SvelteKit?

SvelteKit can be used to create most kinds of applications. Out of the box, SvelteKit supports many features including:

SvelteKit can also be deployed to a wide spectrum of hosted architectures via adapters. In cases where SSR is used (or server-side logic is added without prerendering), those functions will be adapted to the target backend. Some examples include:

  • Self-hosted dynamic web applications with a Node.js backend.
  • Serverless web applications with backend loaders and APIs deployed as remote functions. See zero-config deployments for popular deployment options.
  • Static pre-rendered sites such as a blog or multi-page site hosted on a CDN or static host. Statically-generated sites are shipped without a backend.
  • Single-page Applications (SPAs) with client-side routing and rendering for API-driven dynamic content. SPAs are shipped without a backend and are not server-rendered. This option is commonly chosen when bundling SvelteKit with an app written in PHP, .Net, Java, C, Golang, Rust, etc.
  • A mix of the above; some routes can be static, and some routes can use backend functions to fetch dynamic information. This can be configured with page options that includes the option to opt out of SSR.

In order to support SSR, a JS backend — such as Node.js or Deno-based server, serverless function, or edge function — is required.

It is also possible to write custom adapters or leverage community adapters to deploy SvelteKit to more platforms such as specialized server environments, browser extensions, or native applications. See integrations for more examples and integrations.

SvelteKit で HMR を使うにはどうすればよいですか?

SvelteKit は svelte-hmr によってデフォルトで HMR が有効になっています。Rich の 2020 Svelte Summit のプレゼンテーション を見たことがあるなら、より強力そうに見えるバージョンの HMR をご覧になったかもしれません。あのデモでは svelte-hmrpreserveLocalState フラグがオンになっていました。このフラグは想定外の動作やエッジケースにつながる可能性があるため、現在はデフォルトでオフになっています。でもご心配なく、SvelteKit で HMR を利用することはできます!もしローカルの状態を保持したい場合は、svelte-hmr ページに説明があるように、@hmr:keep または @hmr:keep-all ディレクティブを使用することができます。

package.json の詳細をアプリケーションに含めるにはどうすればよいですか?

SvelteKit では svelte.config.js が ES module であることを想定しているため、JSON ファイルを直接要求することはできません。アプリケーションに、アプリケーションのバージョン番号やその他の情報を package.json から読み込みたい場合は、このように JSON を読み込むことができます:

svelte.config
import { 
function readFileSync(path: PathOrFileDescriptor, options?: {
    encoding?: null | undefined;
    flag?: string | undefined;
} | null): Buffer (+2 overloads)

Returns the contents of the path.

For detailed information, see the documentation of the asynchronous version of this API: {@link readFile } .

If the encoding option is specified then this function returns a string. Otherwise it returns a buffer.

Similar to {@link readFile } , when the path is a directory, the behavior of fs.readFileSync() is platform-specific.

import { readFileSync } from 'node:fs';

// macOS, Linux, and Windows
readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]

//  FreeBSD
readFileSync('<directory>'); // => <data>
@sincev0.1.8
@parampath filename or file descriptor
readFileSync
} from 'node:fs';
import { function fileURLToPath(url: string | URL, options?: FileUrlToPathOptions): string

This function ensures the correct decodings of percent-encoded characters as well as ensuring a cross-platform valid absolute path string.

import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);

new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
fileURLToPath('file:///C:/path/');// Correct:   C:\path\ (Windows)

new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)

new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
fileURLToPath('file:///你好.txt');// Correct:   /你好.txt (POSIX)

new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)
@sincev10.12.0
@paramurl The file URL string or URL object to convert to a path.
@returnThe fully-resolved platform-specific Node.js file path.
fileURLToPath
} from 'node:url';
const const path: stringpath = function fileURLToPath(url: string | URL, options?: FileUrlToPathOptions): string

This function ensures the correct decodings of percent-encoded characters as well as ensuring a cross-platform valid absolute path string.

import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);

new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
fileURLToPath('file:///C:/path/');// Correct:   C:\path\ (Windows)

new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)

new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
fileURLToPath('file:///你好.txt');// Correct:   /你好.txt (POSIX)

new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)
@sincev10.12.0
@paramurl The file URL string or URL object to convert to a path.
@returnThe fully-resolved platform-specific Node.js file path.
fileURLToPath
(new
new URL(input: string | {
    toString: () => string;
}, base?: string | URL): URL

Browser-compatible URL class, implemented by following the WHATWG URL Standard. Examples of parsed URLs may be found in the Standard itself. The URL class is also available on the global object.

In accordance with browser conventions, all properties of URL objects are implemented as getters and setters on the class prototype, rather than as data properties on the object itself. Thus, unlike legacy urlObjects, using the delete keyword on any properties of URL objects (e.g. delete myURL.protocol, delete myURL.pathname, etc) has no effect but will still return true.

@sincev7.0.0, v6.13.0
URL
('package.json', import.meta.ImportMeta.url: string

The absolute file: URL of the module.

url
));
const const pkg: anypkg = var JSON: JSON

An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

JSON
.JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): any

Converts a JavaScript Object Notation (JSON) string into an object.

@paramtext A valid JSON string.
@paramreviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.
parse
(
function readFileSync(path: PathOrFileDescriptor, options: {
    encoding: BufferEncoding;
    flag?: string | undefined;
} | BufferEncoding): string (+2 overloads)

Synchronously reads the entire contents of a file.

@parampath A path to a file. If a URL is provided, it must use the file: protocol. If a file descriptor is provided, the underlying file will not be closed automatically.
@paramoptions Either the encoding for the result, or an object that contains the encoding and an optional flag. If a flag is not provided, it defaults to 'r'.
readFileSync
(const path: stringpath, 'utf8'));

パッケージをインクルードしようとするとエラーが発生するのですが、どうすれば直せますか?

ライブラリのインクルードに関する問題は、ほとんどが不適切なパッケージングによるものです。ライブラリのパッケージングが Node.js に対応しているかどうかは、publint の web サイト でチェックできます。

以下は、ライブラリが正しくパッケージングされているかどうかをチェックする際に気を付けるべき点です:

  • exportsmainmodule などの他のエントリーポイントのフィールドよりも優先されます。exports フィールドを追加すると、deep import を妨げることになるため、後方互換性が失われる場合があります。
  • "type": "module" が指定されていない限り、ESM ファイルは .mjs で終わる必要があり、CommonJS ファイルは .cjs で終わる必要があります。
  • exports が定義されていない場合、main を定義する必要があり、それは CommonJS ファイル か ESM ファイル でなければならず、前項に従わなければなりません。module フィールドが定義されている場合、ESM ファイルを参照している必要があります。
  • Svelte コンポーネントは、コンパイルされていない .svelte ファイルとして配布し、パッケージに含まれる JS は ESM のみとして記述していなければなりません。TypeScript などのカスタムスクリプトや SCSS などのスタイル言語は、それぞれ vanilla JS と CSS にするために前処理(preprocess)をしなければなりません。Svelte ライブラリのパッケージングには、svelte-package を使用することを推奨しています。このパッケージによって、これらの作業が行われます。

ライブラリが ESM バージョンを配布している場合、特に Svelte コンポーネントライブラリがその依存関係に含まれている場合、Vite を使用するとブラウザ上で最適に動作します。ライブラリの作者に ESM バージョンを提供するよう提案すると良いでしょう。しかし、CommonJS (CJS) の依存関係も上手く扱えるようにするため、デフォルトで、vite-plugin-svelte が Vite にそれらを事前バンドルするよう指示します。Vite は esbuild を使ってそれらを ESM に変換します。

それでもまだ問題が解消されない場合は、Vite の issue tracker と 該当のライブラリの issue tracker を検索することを推奨します。optimizeDepsssr の設定値をいじることで問題を回避できる場合もありますが、これはあくまで一時的な回避策とし、問題のあるライブラリの修正を優先したほうが良いでしょう。

SvelteKit で view transitions API を使うにはどうすればよいですか?

SvelteKit では view transitions 向けの特別なインテグレーションはありませんが、onNavigate の中で document.startViewTransition を呼び出すことにより、クライアントサイドナビゲーション毎に view transition をトリガーすることができます。

import { function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<void | (() => void)>): void

A lifecycle function that runs the supplied callback immediately before we navigate to a new URL except during full-page navigations.

If you return a Promise, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use document.startViewTransition. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.

If a function (or a Promise that resolves to a function) is returned from the callback, it will be called once the DOM has updated.

onNavigate must be called during a component initialization. It remains active as long as the component is mounted.

onNavigate
} from '$app/navigation';
function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<void | (() => void)>): void

A lifecycle function that runs the supplied callback immediately before we navigate to a new URL except during full-page navigations.

If you return a Promise, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use document.startViewTransition. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.

If a function (or a Promise that resolves to a function) is returned from the callback, it will be called once the DOM has updated.

onNavigate must be called during a component initialization. It remains active as long as the component is mounted.

onNavigate
((navigation: OnNavigatenavigation) => {
if (!var document: Documentdocument.startViewTransition) return; return new
var Promise: PromiseConstructor
new <void | (() => void)>(executor: (resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => void, reject: (reason?: any) => void) => void) => Promise<void | (() => void)>

Creates a new Promise.

@paramexecutor A callback used to initialize the promise. This callback is passed two arguments: a resolve callback used to resolve the promise with a value or the result of another promise, and a reject callback used to reject the promise with a provided reason or error.
Promise
((resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => voidresolve) => {
var document: Documentdocument.startViewTransition(async () => { resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => voidresolve(); await navigation: OnNavigatenavigation.Navigation.complete: Promise<void>

A promise that resolves once the navigation is complete, and rejects if the navigation fails or is aborted. In the case of a willUnload navigation, the promise will never resolve

complete
;
}); }); });

もっと詳しく知りたければ、Svelte ブログの “Unlocking view transitions” をご参照ください。

SvelteKit で X を使うにはどうすればよいですか?

ドキュメントのインテグレーションのセクション をしっかり読み込んでください。それでも問題が解決しない場合のために、よくある問題の解決策を以下に示します。

データベースのセットアップはどう行えばよいですか?

データベースにクエリするコードを サーバールート(server route) に置いてください。.svelte ファイルの中でデータベースにクエリしないでください。コネクションをすぐにセットアップし、シングルトンとしてアプリ全体からクライアントにアクセスできるように db.js のようなものを作ると良いでしょう。hooks.server.js で1回セットアップするコードを実行し、データベースヘルパーを必要とするすべてのエンドポイントにインポートできます。

document や window に依存しているクライアントサイドオンリーなライブラリはどう使えばよいですか?

もし documentwindow 変数にアクセスする必要があったり、クライアントサイドだけで実行するコードが必要な場合は、browser チェックでラップしてください:

import { const browser: boolean

true if the app is running in the browser.

browser
} from '$app/environment';
if (const browser: boolean

true if the app is running in the browser.

browser
) {
// client-only code here }

コンポーネントが最初に DOM にレンダリングされた後にコードを実行したい場合は、onMount で実行することもできます:

import { function onMount<T>(fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)): void

The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component’s initialisation (but doesn’t need to live inside the component; it can be called from an external module).

If a function is returned synchronously from onMount, it will be called when the component is unmounted.

onMount does not run inside server-side components.

onMount
} from 'svelte';
onMount<void>(fn: () => void | (() => any) | Promise<void>): void

The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component’s initialisation (but doesn’t need to live inside the component; it can be called from an external module).

If a function is returned synchronously from onMount, it will be called when the component is unmounted.

onMount does not run inside server-side components.

onMount
(async () => {
const { const method: anymethod } = await import('some-browser-only-library'); const method: anymethod('hello world'); });

使用したいライブラリに副作用がなければ静的にインポートすることができますし、サーバー側のビルドでツリーシェイクされ、onMount が自動的に no-op に置き換えられます:

import { function onMount<T>(fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)): void

The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component’s initialisation (but doesn’t need to live inside the component; it can be called from an external module).

If a function is returned synchronously from onMount, it will be called when the component is unmounted.

onMount does not run inside server-side components.

onMount
} from 'svelte';
import { module "some-browser-only-library"method } from 'some-browser-only-library'; onMount<void>(fn: () => void | (() => any) | Promise<void>): void

The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component’s initialisation (but doesn’t need to live inside the component; it can be called from an external module).

If a function is returned synchronously from onMount, it will be called when the component is unmounted.

onMount does not run inside server-side components.

onMount
(() => {
module "some-browser-only-library"method('hello world'); });

最後に、{#await} ブロックのご使用も検討してみてください:

index
<script>
	import { browser } from '$app/environment';

	const ComponentConstructor = browser ?
		import('some-browser-only-library').then((module) => module.Component) :
		new Promise(() => {});
</script>

{#await ComponentConstructor}
	<p>Loading...</p>
{:then component}
	<svelte:component this={component} />
{:catch error}
	<p>Something went wrong: {error.message}</p>
{/await}

別のバックエンド API サーバーを使用するにはどうすれば良いですか?

外部の API サーバーにデータをリクエストするのに event.fetch を使用することができますが、CORS に対応しなければならず、一般的にはリクエストのプリフライトが必要になり、結果として高レイテンシーになるなど、複雑になることにご注意ください。別のサブドメインへのリクエストも、追加の DNS ルックアップや TLS セットアップなどのためにレイテンシーが増加する可能性があります。この方法を使いたい場合は、handleFetch が参考になるかもしれません。

別の方法は、頭痛の種である CORS をバイパスするためのプロキシーをセットアップすることです。本番環境では、/api などのパスを API サーバーに書き換えます(rewrite)。ローカルの開発環境では、Vite の server.proxy オプションを使用します。

本番環境で書き換え(rewrite)をセットアップする方法は、デプロイ先のプラットフォームに依存します。もし、書き換える方法がなければ、代わりに API route を追加します:

src/routes/api/[...path]/+server
/** @type {import('./$types').RequestHandler} */
export function 
function GET({ params, url }: {
    params: any;
    url: any;
}): Promise<Response>
@type{import('./$types').RequestHandler}
GET
({ params: anyparams, url: anyurl }) {
return function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> (+1 overload)fetch(`https://my-api-server.com/${params: anyparams.path + url: anyurl.search}`); }
import type { 
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
} from './$types';
export const const GET: RequestHandlerGET:
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler
= ({ params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object

params
, url: URL

The requested URL.

url
}) => {
return function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> (+1 overload)fetch(`https://my-api-server.com/${params: Record<string, any>

The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object

params
.path + url: URL

The requested URL.

url
.URL.search: stringsearch}`);
};

(必要に応じて、POST / PATCH などのリクエストもプロキシし、request.headers も転送(forward)する必要があることにご注意ください)

ミドルウェア(middleware)を使うにはどうすればよいですか?

adapter-node は、プロダクションモードで使用するためのミドルウェアを自分のサーバで構築します。開発モードでは、Vite プラグインを使用して Vite にミドルウェア(middleware) を追加することができます。例えば:

import { module "@sveltejs/kit/vite"sveltekit } from '@sveltejs/kit/vite';

/** @type {import('vite').Plugin} */
const const myPlugin: Plugin<any>
@type{import('vite').Plugin}
myPlugin
= {
OutputPlugin.name: stringname: 'log-request-middleware', Plugin<any>.configureServer?: ObjectHook<ServerHook> | undefined

Configure the vite server. The hook receives the {@link ViteDevServer }

instance. This can also be used to store a reference to the server for use in other hooks.

The hooks will be called before internal middlewares are applied. A hook can return a post hook that will be called after internal middlewares are applied. Hook can be async functions and will be called in series.

configureServer
(server: ViteDevServerserver) {
server: ViteDevServerserver.ViteDevServer.middlewares: Connect.Server

A connect app instance.

  • Can be used to attach custom middlewares to the dev server.
  • Can also be used as the handler function of a custom http server or as a middleware in any connect-style Node.js frameworks

https://github.com/senchalabs/connect#use-middleware

middlewares
.Connect.Server.use(fn: Connect.NextHandleFunction): Connect.Server (+3 overloads)

Utilize the given middleware handle to the given route, defaulting to /. This “route” is the mount-point for the middleware, when given a value other than / the middleware is only effective when that segment is present in the request’s pathname.

For example if we were to mount a function at /admin, it would be invoked on /admin, and /admin/settings, however it would not be invoked for /, or /posts.

use
((req: Connect.IncomingMessagereq, res: ServerResponse<IncomingMessage>res, next: Connect.NextFunctionnext) => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
(`Got request ${req: Connect.IncomingMessagereq.IncomingMessage.url?: string | undefined

Only valid for request obtained from {@link Server } .

Request URL string. This contains only the URL that is present in the actual HTTP request. Take the following request:

GET /status?name=ryan HTTP/1.1
Accept: text/plain

To parse the URL into its parts:

new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`);

When request.url is '/status?name=ryan' and process.env.HOST is undefined:

$ node
> new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`);
URL {
  href: 'http://localhost/status?name=ryan',
  origin: 'http://localhost',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost',
  hostname: 'localhost',
  port: '',
  pathname: '/status',
  search: '?name=ryan',
  searchParams: URLSearchParams { 'name' => 'ryan' },
  hash: ''
}

Ensure that you set process.env.HOST to the server’s host name, or consider replacing this part entirely. If using req.headers.host, ensure proper validation is used, as clients may specify a custom Host header.

@sincev0.1.90
url
}`);
next: (err?: any) => voidnext(); }); } }; /** @type {import('vite').UserConfig} */ const const config: UserConfig
@type{import('vite').UserConfig}
config
= {
UserConfig.plugins?: PluginOption[] | undefined

Array of vite plugins to use.

plugins
: [const myPlugin: Plugin<any>
@type{import('vite').Plugin}
myPlugin
, module "@sveltejs/kit/vite"sveltekit()]
}; export default const config: UserConfig
@type{import('vite').UserConfig}
config
;

順序を制御する方法など、詳しくは Vite の configureServer のドキュメント をご覧ください。

Yarn 2 で動作しますか?

多少は。Plug’n'Play 機能、通称 ‘pnp’ は動きません (Node のモジュール解決アルゴリズムから逸脱しており、SvelteKitが数多くのライブラリとともに使用しているネイティブの JavaScript モジュールではまだ動作しません)。.yarnrc.ymlnodeLinker: 'node-modules' を使用して pnp を無効にできますが、おそらく npm や pnpm を使用するほうが簡単でしょう。同じように高速で効率的ですが、互換性に頭を悩ませることはありません。

Yarn 3 を使用するにはどうすれば良いですか?

現時点の、最新の Yarn (version 3) の ESM サポート は experimental であるようです。

結果は異なるかもしれませんが、下記が有効なようです。

最初に新しいアプリケーションを作成します:

yarn create svelte myapp
cd myapp

And enable Yarn Berry:

yarn set version berry
yarn install

Yarn 3 global cache

Yarn Berry の興味深い機能の1つに、ディスク上のプロジェクトごとに複数のコピーを持つのではなく、パッケージ用に単一のグローバルキャッシュを持つことができる、というのがあります。しかし、enableGlobalCache の設定を true にするとビルドが失敗するため、.yarnrc.yml ファイルに以下を追加することを推奨します:

nodeLinker: node-modules

これによってパッケージはローカルの node_modules ディレクトリにダウンロードされますが、上記の問題は回避され、現時点では Yarn の version 3 を使用するベストな方法となります。

Edit this page on GitHub

previous next