@@ -7,7 +7,7 @@ const readFileSync = require('fs').readFileSync
77const Metalsmith = require ( '..' )
88const { Command } = require ( 'commander' )
99const program = new Command ( )
10- const { resolve, isAbsolute, dirname } = require ( 'path' )
10+ const { resolve, isAbsolute, dirname, extname } = require ( 'path' )
1111const { isString, isObject } = require ( '../lib/helpers' )
1212
1313const color = {
@@ -51,21 +51,38 @@ program.parse(process.argv)
5151
5252function buildCommand ( { config, ...options } ) {
5353 const dir = process . cwd ( )
54- const path = isAbsolute ( config ) ? config : resolve ( dir , config )
54+ let path = isAbsolute ( config ) ? config : resolve ( dir , config )
5555
5656 // Important addition of 2.5.x. Given local plugins with a relative path are written with __dirname in mind,
5757 // having a config-relative dir path makes sure the CLI runs properly
5858 // when the command is executed from a subfolder or outside of the ms directory
5959 const confRelativeDir = dirname ( path )
60- if ( ! exists ( path ) ) fatal ( `could not find a ${ config } configuration file.` )
60+ if ( ! exists ( path ) ) {
61+ // commander only supports a single default, so we must set default manually here
62+ if ( exists ( resolve ( confRelativeDir , 'metalsmith.js' ) ) ) {
63+ path = resolve ( confRelativeDir , 'metalsmith.js' )
64+ } else {
65+ fatal ( `could not find a ${ config } configuration file.` )
66+ }
67+ }
68+
69+ const format = extname ( path ) . slice ( 1 )
6170
6271 let json
6372 try {
64- // requiring json is incompatible with ESM, however given the metalsmith CLI is not meant to be "imported" or used in an ESM flow,
65- // it is ok to keep it here for now
66- json = JSON . parse ( readFileSync ( path , 'utf-8' ) )
73+ if ( format === 'js' || format === 'cjs' ) {
74+ json = require ( path )
75+ // when a JS file is required that forgets to export using exports or module.exports,
76+ // node instead returns an empty object. Though Metalsmith should in theory consider this a valid config
77+ // for a simple copy -> paste it is highly likely that this was not the user's intension
78+ if ( isObject ( json ) && Object . keys ( json ) . length === 0 ) {
79+ fatal ( `it seems like ${ config } is empty. Make sure it exports a metalsmith config object.` )
80+ }
81+ } else {
82+ json = JSON . parse ( readFileSync ( path , 'utf-8' ) )
83+ }
6784 } catch ( e ) {
68- fatal ( `it seems like ${ config } is malformed.` )
85+ fatal ( `it seems like ${ config } is malformed or unsupported (ESM) .` )
6986 }
7087
7188 /**
0 commit comments