diff --git a/docs/cli/shortcuts.md b/docs/cli/shortcuts.md
index e3e70ff6..beeac60f 100644
--- a/docs/cli/shortcuts.md
+++ b/docs/cli/shortcuts.md
@@ -1,6 +1,6 @@
# Command Shortcuts
-Package managers that execute scripts from a `package.json` or `deno.(json|jsonc)` file can be shortened when in concurrently.
+Package managers that execute scripts from a `package.json` / `package.json5` or `deno.(json|jsonc)` file can be shortened when in concurrently.
The following are supported:
| Syntax | Expands to |
diff --git a/lib/command-parser/expand-wildcard.spec.ts b/lib/command-parser/expand-wildcard.spec.ts
index 1a6d1afb..8e985abd 100644
--- a/lib/command-parser/expand-wildcard.spec.ts
+++ b/lib/command-parser/expand-wildcard.spec.ts
@@ -99,6 +99,9 @@ describe('#readPackage()', () => {
name: 'concurrently',
version: '6.4.0',
};
+ vi.spyOn(fs, 'existsSync').mockImplementation((path: PathOrFileDescriptor) => {
+ return path === 'package.json';
+ });
vi.spyOn(fs, 'readFileSync').mockImplementation((path: PathOrFileDescriptor) => {
if (path === 'package.json') {
return JSON.stringify(expectedPackage);
@@ -118,6 +121,47 @@ describe('#readPackage()', () => {
expect(() => ExpandWildcard.readPackage()).not.toThrow();
expect(ExpandWildcard.readPackage()).toEqual({});
});
+
+ it('can read package.json5', () => {
+ const expectedPackage = {
+ name: 'concurrently',
+ version: '6.4.0',
+ scripts: {
+ 'test:unit': '',
+ },
+ };
+ vi.spyOn(fs, 'existsSync').mockImplementation((path: PathOrFileDescriptor) => {
+ return path === 'package.json5';
+ });
+ vi.spyOn(fs, 'readFileSync').mockImplementation((path: PathOrFileDescriptor) => {
+ if (path === 'package.json5') {
+ return `/* comment */\n${JSON.stringify(expectedPackage)}`;
+ }
+ return '';
+ });
+
+ const actualReadPackage = ExpandWildcard.readPackage();
+ expect(actualReadPackage).toEqual(expectedPackage);
+ });
+
+ it('prefers package.json over package.json5', () => {
+ const expectedPackage = {
+ name: 'from-json',
+ version: '1.0.0',
+ };
+ vi.spyOn(fs, 'existsSync').mockImplementation((path: PathOrFileDescriptor) => {
+ return path === 'package.json' || path === 'package.json5';
+ });
+ vi.spyOn(fs, 'readFileSync').mockImplementation((path: PathOrFileDescriptor) => {
+ if (path === 'package.json') {
+ return JSON.stringify(expectedPackage);
+ }
+ return '';
+ });
+
+ const actualReadPackage = ExpandWildcard.readPackage();
+ expect(actualReadPackage).toEqual(expectedPackage);
+ });
});
it('returns same command if not an npm run command', () => {
diff --git a/lib/command-parser/expand-wildcard.ts b/lib/command-parser/expand-wildcard.ts
index 4aa37ecc..557ebc09 100644
--- a/lib/command-parser/expand-wildcard.ts
+++ b/lib/command-parser/expand-wildcard.ts
@@ -32,8 +32,15 @@ export class ExpandWildcard implements CommandParser {
static readPackage() {
try {
- const json = fs.readFileSync('package.json', { encoding: 'utf-8' });
- return JSON.parse(json);
+ let json: string = '{}';
+
+ if (fs.existsSync('package.json')) {
+ json = fs.readFileSync('package.json', { encoding: 'utf-8' });
+ } else if (fs.existsSync('package.json5')) {
+ json = fs.readFileSync('package.json5', { encoding: 'utf-8' });
+ }
+
+ return JSONC.parse(json);
} catch {
return {};
}