1+ import fs from "fs" ;
12import path from "path" ;
23import prettier , { Options } from "prettier" ;
34import { ILoader } from "./_types" ;
45import { createLoader } from "./_utils" ;
6+ import { execSync } from "child_process" ;
57
68export type PrettierLoaderOptions = {
79 parser : Options [ "parser" ] ;
@@ -23,7 +25,7 @@ export default function createPrettierLoader(options: PrettierLoaderOptions): IL
2325 return data ;
2426 }
2527
26- const result = prettier . format ( data , {
28+ const config : Options = {
2729 ...( prettierConfig || { printWidth : 2500 , bracketSameLine : false } ) ,
2830 parser : options . parser ,
2931 // For HTML parser, preserve comments and quotes
@@ -34,9 +36,29 @@ export default function createPrettierLoader(options: PrettierLoaderOptions): IL
3436 embeddedLanguageFormatting : "off" ,
3537 }
3638 : { } ) ,
37- } ) ;
39+ } ;
3840
39- return result ;
41+ try {
42+ const result = await prettier . format ( data , config ) ;
43+ return result ;
44+ } catch ( error ) {
45+ if ( error instanceof Error && error . message . startsWith ( "Cannot find package" ) ) {
46+ console . log ( ) ;
47+ console . log ( "Prettier is missing some dependecies - installing all project dependencies" ) ;
48+
49+ // prettier is missing dependencies - install all project dependencies
50+ installDependencies ( ) ;
51+
52+ // clear file system structure cache to find newly installed dependencies
53+ await prettier . clearConfigCache ( ) ;
54+
55+ // try to format again
56+ const result = await prettier . format ( data , config ) ;
57+ return result ;
58+ } else {
59+ throw error ;
60+ }
61+ }
4062 } ,
4163 } ) ;
4264}
@@ -49,3 +71,24 @@ async function loadPrettierConfig(filePath: string) {
4971 return { } ;
5072 }
5173}
74+
75+ // install all dependencies using package manager
76+ async function installDependencies ( ) {
77+ const packageManager = await getPackageManager ( ) ;
78+ console . log ( `Installing dependencies using ${ packageManager } ` ) ;
79+ execSync ( `${ packageManager } install --frozen-lockfile` , { stdio : "inherit" } ) ;
80+ console . log ( `Dependencies installed` ) ;
81+ }
82+
83+ // determine if yarn or pnpm is used based on lockfile, otherwise use npm
84+ async function getPackageManager ( ) {
85+ const yarnLockfile = path . resolve ( process . cwd ( ) , "yarn.lock" ) ;
86+ const pnpmLockfile = path . resolve ( process . cwd ( ) , "pnpm-lock.yaml" ) ;
87+ if ( fs . existsSync ( yarnLockfile ) ) {
88+ return "yarn" ;
89+ }
90+ if ( fs . existsSync ( pnpmLockfile ) ) {
91+ return "pnpm" ;
92+ }
93+ return "npm" ;
94+ }
0 commit comments