Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Core components:
- `src/extension.ts` - Extension activation, creates ModuleResolver, PrettierEditService, and StatusBar
- `src/PrettierEditService.ts` - Registers VS Code document formatting providers, handles format requests
- `src/ModuleResolver.ts` - Resolves local/global Prettier installations, falls back to bundled Prettier
- `src/PrettierInstance.ts` - Interface for Prettier loading, with `PrettierMainThreadInstance` and `PrettierWorkerInstance` implementations
- `src/PrettierInstance.ts` - Interface for Prettier loading, with `PrettierMainThreadInstance` implementations

esbuild produces two bundles:

Expand Down Expand Up @@ -62,14 +62,13 @@ When reviewing pull requests, focus on:

### Prettier Compatibility

- Changes work with both Prettier v2 (sync) and v3+ (async/worker)
- Changes work with both Prettier v2 (sync) and v3+ (async)
- Module resolution fallback chain is maintained: local → global → bundled
- Config file watching covers all Prettier config formats

### Performance

- Avoid blocking the extension host main thread
- `PrettierWorkerInstance` runs Prettier in a worker thread to avoid blocking
- Module and config resolution results are cached appropriately

### Browser Compatibility
Expand Down
2 changes: 1 addition & 1 deletion .github/instructions/typescript.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This is a VS Code extension. Follow these patterns:
## Prettier Integration

- Support both Prettier v2 and v3+ via `PrettierInstance` interface
- `PrettierMainThreadInstance` loads directly, `PrettierWorkerInstance` uses worker thread
- `PrettierMainThreadInstance` loads directly
- Module resolution: local install → global install → bundled Prettier
- Handle `.prettierrc`, `.prettierignore`, and `package.json` prettier config

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to the "prettier-vscode" extension will be documented in thi

## [unreleased]

- Support configuration file with imported plugins
- [BREAKING CHANGE] Bundled Prettier upgraded from v2.8.8 to v3.x
- [BREAKING CHANGE] Updated `trailingComma` default from `"es5"` to `"all"` to match Prettier 3
- Maintained backward compatibility with projects using Prettier v2.x (projects with explicit Prettier v2 dependencies will continue to use their local version)
Expand Down
4 changes: 1 addition & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ Web tests are located in `src/test/web/suite/` and test the extension's browser
- Caches resolved modules and configurations
- Handles Workspace Trust restrictions

**Prettier Instance** (`PrettierInstance.ts`, `PrettierMainThreadInstance.ts`, `PrettierWorkerInstance.ts`):
**Prettier Instance** (`PrettierInstance.ts`, `PrettierMainThreadInstance.ts`):

- `PrettierInstance` is an interface with two implementations
- `PrettierMainThreadInstance` loads Prettier directly via `require()`
- `PrettierWorkerInstance` loads Prettier in a worker thread to avoid blocking
- Works with both Prettier v2 and v3+

### Bundling

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Key components:

- `PrettierEditService.ts` - Handles document formatting
- `ModuleResolver.ts` - Resolves Prettier installations (local, global, or bundled)
- `PrettierInstance.ts` - Interface for Prettier, with `PrettierMainThreadInstance` and `PrettierWorkerInstance` implementations
- `PrettierInstance.ts` - Interface for Prettier, with `PrettierMainThreadInstance` implementations

## Submitting Changes

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
</p>

> [!IMPORTANT]
> **Extension Migration:** This extension is being moved from `esbenp.prettier-vscode` to [`prettier.prettier-vscode`](https://marketplace.visualstudio.com/items?itemName=prettier.prettier-vscode). Version 12+ is only published to the new for now as it is a major change. Once it is stable, we will publish v12 to both extensions and deprecate the `esbenp.prettier-vscode` extension. **Version 12.x is currently not stable, use with caution in production environments.**
> **Extension Migration:** This extension is being moved from `esbenp.prettier-vscode` to [`prettier.prettier-vscode`](https://marketplace.visualstudio.com/items?itemName=prettier.prettier-vscode). Version 12+ is only published to the new for now as it is a major change. Once it is stable, we will publish v12 to both extensions and deprecate the `esbenp.prettier-vscode` extension. **Version 12.x is currently not stable, use with caution in production environments.**

## Installation

Expand Down
31 changes: 0 additions & 31 deletions esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -160,43 +160,12 @@ const webTestConfig = {
plugins: [esbuildProblemMatcherPlugin],
};

function copyWorkerFile() {
// Copy to dist (for production/esbuild bundle)
const distWorkerDir = "dist/worker";
if (!fs.existsSync(distWorkerDir)) {
fs.mkdirSync(distWorkerDir, { recursive: true });
}
fs.copyFileSync(
"src/worker/prettier-instance-worker.js",
"dist/worker/prettier-instance-worker.js",
);

// Copy to out (for tests/tsc output)
const outWorkerDir = "out/worker";
if (!fs.existsSync(outWorkerDir)) {
fs.mkdirSync(outWorkerDir, { recursive: true });
}
fs.copyFileSync(
"src/worker/prettier-instance-worker.js",
"out/worker/prettier-instance-worker.js",
);
}

async function main() {
const nodeCtx = await esbuild.context(nodeConfig);
const browserCtx = await esbuild.context(browserConfig);
const webTestCtx = await esbuild.context(webTestConfig);

// Copy worker file
copyWorkerFile();

if (watch) {
// Watch the worker file for changes
fs.watchFile("src/worker/prettier-instance-worker.js", () => {
console.log("[watch] copying worker file");
copyWorkerFile();
});

await Promise.all([
nodeCtx.watch(),
browserCtx.watch(),
Expand Down
1 change: 0 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default tseslint.config(
"node_modules/**",
".vscode-test/**",
".vscode-test-web/**",
"src/worker/**",
],
},

Expand Down
53 changes: 2 additions & 51 deletions src/ModuleResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ import {
getWorkspaceRelativePath,
} from "./utils/workspace";
import { PrettierInstance } from "./PrettierInstance";
import { PrettierWorkerInstance } from "./PrettierWorkerInstance";
import { PrettierMainThreadInstance } from "./PrettierMainThreadInstance";
import { loadNodeModule, resolveConfigPlugins } from "./utils/resolvers";
import { isAboveV3 } from "./utils/versions";
import { resolveConfigPlugins } from "./utils/resolvers";

const minPrettierVersion = "1.13.0";

Expand Down Expand Up @@ -128,45 +126,6 @@ export class ModuleResolver implements ModuleResolverInterface {
return prettier;
}

private loadPrettierVersionFromPackageJson(modulePath: string): string {
let cwd = "";
try {
fs.readdirSync(modulePath); // checking if dir with readdir will handle directories and symlinks
cwd = modulePath;
} catch {
cwd = path.dirname(modulePath);
}
const packageJsonPath = findUp.sync(
(dir) => {
const pkgFilePath = path.join(dir, "package.json");
if (fs.existsSync(pkgFilePath)) {
return pkgFilePath;
}
},
{ cwd },
);

if (!packageJsonPath) {
throw new Error("Cannot find Prettier package.json");
}

const prettierPkgJson = loadNodeModule(packageJsonPath) as {
version?: string;
} | null;

let version: string | null = null;

if (prettierPkgJson && typeof prettierPkgJson.version === "string") {
version = prettierPkgJson.version;
}

if (!version) {
throw new Error("Cannot load Prettier version from package.json");
}

return version;
}

/**
* Returns an instance of the prettier module.
* @param fileName The path of the file to use as the starting point. If none provided, the bundled prettier will be used.
Expand Down Expand Up @@ -246,16 +205,8 @@ export class ModuleResolver implements ModuleResolverInterface {
return moduleInstance;
} else {
try {
const prettierVersion =
this.loadPrettierVersionFromPackageJson(modulePath);
moduleInstance = new PrettierMainThreadInstance(modulePath);

const isAboveVersion3 = isAboveV3(prettierVersion);

if (isAboveVersion3) {
moduleInstance = new PrettierWorkerInstance(modulePath);
} else {
moduleInstance = new PrettierMainThreadInstance(modulePath);
}
if (moduleInstance) {
this.path2Module.set(modulePath, moduleInstance);
}
Expand Down
138 changes: 0 additions & 138 deletions src/PrettierWorkerInstance.ts

This file was deleted.

Loading