or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md
tile.json

index.mddocs/

0

# Interpret

1

2

Interpret is a comprehensive dictionary of file extensions and their associated module loaders, enabling automatic registration of transpilers and compilers for various JavaScript variants and other file types. It provides mapping from file extensions to the appropriate Node.js require.extensions loaders for seamless transpilation support.

3

4

## Package Information

5

6

- **Package Name**: interpret

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install interpret`

10

11

## Core Imports

12

13

```javascript

14

const { extensions, jsVariants } = require('interpret');

15

```

16

17

For ESM (requires transpilation):

18

19

```javascript

20

import { extensions, jsVariants } from 'interpret';

21

```

22

23

## Basic Usage

24

25

```javascript

26

const interpret = require('interpret');

27

28

// Check if a file extension has a loader

29

const tsLoader = interpret.extensions['.ts'];

30

console.log(tsLoader); // Array of loader options for TypeScript

31

32

// Get only JavaScript variant extensions

33

const jsOnlyLoaders = interpret.jsVariants;

34

console.log(jsOnlyLoaders['.jsx']); // Loader options for JSX files

35

36

// Implementation pattern for using loaders

37

function registerLoader(extension) {

38

const loader = interpret.extensions[extension];

39

40

if (!loader) {

41

console.log('No loader for', extension);

42

return;

43

}

44

45

if (loader === null) {

46

// Use default Node.js loader

47

return;

48

}

49

50

if (typeof loader === 'string') {

51

// Simple module name

52

require(loader);

53

} else if (Array.isArray(loader)) {

54

// Try each loader until one works

55

for (const option of loader) {

56

try {

57

if (typeof option === 'string') {

58

require(option);

59

break;

60

} else if (option.module) {

61

const hook = require(option.module);

62

if (option.register) {

63

option.register(hook);

64

}

65

break;

66

}

67

} catch (err) {

68

// Try next option

69

}

70

}

71

} else if (loader.module) {

72

// Object with module and register function

73

const hook = require(loader.module);

74

if (loader.register) {

75

loader.register(hook);

76

}

77

}

78

}

79

```

80

81

## Capabilities

82

83

### Extensions Dictionary

84

85

Complete mapping of file extensions to their associated module loaders.

86

87

```javascript { .api }

88

/**

89

* Dictionary mapping file extensions to loader configurations

90

* @type {Object<string, LoaderConfig>}

91

*/

92

const extensions: {

93

[extension: string]: LoaderConfig;

94

};

95

96

/**

97

* Loader configuration can be:

98

* - null: Use default Node.js loader

99

* - string: Module name to require

100

* - LoaderObject: Module with custom registration

101

* - LoaderConfig[]: Array of fallback options

102

*/

103

type LoaderConfig = null | string | LoaderObject | LoaderConfig[];

104

105

/**

106

* Loader object with module and custom registration function

107

*/

108

interface LoaderObject {

109

/** Module name to require */

110

module: string;

111

/** Custom registration function */

112

register: (hook: any, config?: any) => void;

113

}

114

```

115

116

### JavaScript Variants Dictionary

117

118

Subset of extensions containing only JavaScript-related file types.

119

120

```javascript { .api }

121

/**

122

* Dictionary of JavaScript variant extensions and their loaders

123

* Same structure as extensions but filtered to JS-related types only

124

* @type {Object<string, LoaderConfig>}

125

*/

126

const jsVariants: {

127

[extension: string]: LoaderConfig;

128

};

129

```

130

131

## Supported Extensions

132

133

### JavaScript Variants (jsVariants)

134

135

Extensions included in the jsVariants object for JavaScript and JavaScript-like languages:

136

137

```javascript { .api }

138

// Native Node.js loaders

139

'.js': null,

140

'.cjs': 'interpret/cjs-stub',

141

'.mjs': 'interpret/mjs-stub',

142

143

// JSX support

144

'.jsx': [

145

{

146

module: '@babel/register',

147

register: (hook, config) => void

148

},

149

'sucrase/register/jsx'

150

],

151

152

// TypeScript support

153

'.ts': [

154

'ts-node/register',

155

'sucrase/register/ts',

156

{

157

module: '@babel/register',

158

register: (hook, config) => void

159

},

160

{

161

module: 'esbuild-register/dist/node',

162

register: (mod, config) => void

163

},

164

{

165

module: '@swc/register',

166

register: (hook, config) => void

167

}

168

],

169

170

'.tsx': [

171

'ts-node/register',

172

'sucrase/register/tsx',

173

{

174

module: '@babel/register',

175

register: (hook, config) => void

176

},

177

{

178

module: 'esbuild-register/dist/node',

179

register: (mod, config) => void

180

},

181

{

182

module: '@swc/register',

183

register: (hook, config) => void

184

}

185

],

186

187

// CoffeeScript support

188

'.coffee': 'coffeescript/register',

189

'.coffee.md': 'coffeescript/register',

190

'.litcoffee': 'coffeescript/register',

191

192

// ESM support

193

'.esm.js': {

194

module: 'esm',

195

register: (hook) => void

196

},

197

198

// MDX support

199

'.mdx': '@mdx-js/register'

200

```

201

202

### Transpiler-Specific Extensions

203

204

Extensions that target specific transpilers:

205

206

```javascript { .api }

207

// Babel-specific extensions

208

'.babel.js': {

209

module: '@babel/register',

210

register: (hook, config) => void

211

},

212

'.babel.jsx': {

213

module: '@babel/register',

214

register: (hook, config) => void

215

},

216

'.babel.ts': [{

217

module: '@babel/register',

218

register: (hook, config) => void

219

}],

220

'.babel.tsx': {

221

module: '@babel/register',

222

register: (hook, config) => void

223

},

224

225

// ESBuild-specific extensions

226

'.esbuild.js': {

227

module: 'esbuild-register/dist/node',

228

register: (mod, config) => void

229

},

230

'.esbuild.jsx': {

231

module: 'esbuild-register/dist/node',

232

register: (mod, config) => void

233

},

234

'.esbuild.ts': {

235

module: 'esbuild-register/dist/node',

236

register: (mod, config) => void

237

},

238

'.esbuild.tsx': {

239

module: 'esbuild-register/dist/node',

240

register: (mod, config) => void

241

},

242

243

// Sucrase-specific extensions

244

'.sucrase.js': {

245

module: 'sucrase/dist/register',

246

register: (hook, config) => void

247

},

248

'.sucrase.jsx': {

249

module: 'sucrase/dist/register',

250

register: (hook, config) => void

251

},

252

'.sucrase.ts': {

253

module: 'sucrase/dist/register',

254

register: (hook, config) => void

255

},

256

'.sucrase.tsx': {

257

module: 'sucrase/dist/register',

258

register: (hook, config) => void

259

},

260

261

// SWC-specific extensions

262

'.swc.js': {

263

module: '@swc/register',

264

register: (hook, config) => void

265

},

266

'.swc.jsx': {

267

module: '@swc/register',

268

register: (hook, config) => void

269

},

270

'.swc.ts': {

271

module: '@swc/register',

272

register: (hook, config) => void

273

},

274

'.swc.tsx': {

275

module: '@swc/register',

276

register: (hook, config) => void

277

}

278

```

279

280

### Extensions Only (not in jsVariants)

281

282

Extensions available in the main extensions object but not included in jsVariants:

283

284

```javascript { .api }

285

// Native Node.js loaders

286

'.json': null,

287

'.node': null,

288

289

// TypeScript CommonJS modules

290

'.cts': ['ts-node/register'],

291

292

// Data formats

293

'.json5': 'json5/lib/register',

294

'.yaml': 'yaml-hook/register',

295

'.yml': 'yaml-hook/register',

296

'.toml': {

297

module: 'toml-require',

298

register: (hook, config) => void

299

}

300

```

301

302

### Internal Helper Functions

303

304

The package includes internal helper functions used within loader configurations:

305

306

```javascript { .api }

307

/**

308

* Helper functions for matching specific file extensions

309

* These are used internally by the loader configurations

310

*/

311

function endsInJsx(filename: string): boolean;

312

function endsInTs(filename: string): boolean;

313

function endsInTsx(filename: string): boolean;

314

function endsInBabelJs(filename: string): boolean;

315

function endsInBabelJsx(filename: string): boolean;

316

function endsInBabelTs(filename: string): boolean;

317

function endsInBabelTsx(filename: string): boolean;

318

function endsInEsbuildJs(filename: string): boolean;

319

function endsInEsbuildJsx(filename: string): boolean;

320

function endsInEsbuildTs(filename: string): boolean;

321

function endsInEsbuildTsx(filename: string): boolean;

322

function endsInSucraseJs(filename: string): boolean;

323

function endsInSucraseJsx(filename: string): boolean;

324

function endsInSucraseTs(filename: string): boolean;

325

function endsInSucraseTsx(filename: string): boolean;

326

function endsInSwcJs(filename: string): boolean;

327

function endsInSwcJsx(filename: string): boolean;

328

function endsInSwcTs(filename: string): boolean;

329

function endsInSwcTsx(filename: string): boolean;

330

331

/**

332

* Helper function to check if a file is in node_modules

333

* Used for ignoring node_modules in some transpiler configurations

334

*/

335

function isNodeModules(file: string): boolean;

336

```

337

338

### Stub Files

339

340

The package includes stub files for CommonJS and ES Modules:

341

342

```javascript { .api }

343

/**

344

* Path to CommonJS stub file that registers .cjs extension

345

* Resolves to: path.join(__dirname, 'cjs-stub')

346

* Contents: require.extensions['.cjs'] = null;

347

*/

348

const cjsStub: string;

349

350

/**

351

* Path to ES Module stub file that registers .mjs extension

352

* Resolves to: path.join(__dirname, 'mjs-stub')

353

* Contents: require.extensions['.mjs'] = null;

354

*/

355

const mjsStub: string;

356

```

357

358

## Usage Patterns

359

360

### Basic Extension Check

361

362

```javascript

363

const interpret = require('interpret');

364

365

function hasLoader(extension) {

366

return extension in interpret.extensions;

367

}

368

369

function isJavaScriptVariant(extension) {

370

return extension in interpret.jsVariants;

371

}

372

```

373

374

### Loader Registration Implementation

375

376

```javascript

377

const interpret = require('interpret');

378

379

function attemptRequire(extension, filepath) {

380

const loader = interpret.extensions[extension];

381

382

if (!loader) {

383

throw new Error(`No loader available for ${extension}`);

384

}

385

386

if (loader === null) {

387

// Use default Node.js loader

388

return require(filepath);

389

}

390

391

// Register the appropriate loader

392

registerLoader(loader);

393

394

// Now require the file

395

return require(filepath);

396

}

397

398

function registerLoader(loader) {

399

if (typeof loader === 'string') {

400

require(loader);

401

} else if (Array.isArray(loader)) {

402

// Try each loader until one succeeds

403

for (const option of loader) {

404

try {

405

registerSingleLoader(option);

406

return;

407

} catch (err) {

408

// Continue to next option

409

}

410

}

411

throw new Error('No working loader found');

412

} else if (loader && loader.module) {

413

registerSingleLoader(loader);

414

}

415

}

416

417

function registerSingleLoader(loader) {

418

if (typeof loader === 'string') {

419

require(loader);

420

} else if (loader.module) {

421

const hook = require(loader.module);

422

if (loader.register) {

423

loader.register(hook);

424

}

425

}

426

}

427

```

428

429

### Configuration Examples

430

431

Most loaders accept configuration through the register function's second parameter:

432

433

```javascript

434

// Babel configuration example

435

const babelLoader = {

436

module: '@babel/register',

437

register: (hook, config) => {

438

const defaultConfig = {

439

rootMode: 'upward-optional',

440

overrides: [{

441

only: [filename => filename.endsWith('.tsx')],

442

presets: [

443

'@babel/preset-env',

444

'@babel/preset-react',

445

['@babel/preset-typescript', { isTSX: true, allExtensions: true }]

446

]

447

}]

448

};

449

450

hook(Object.assign({}, defaultConfig, config, { extensions: '.tsx' }));

451

}

452

};

453

454

// ESBuild configuration example

455

const esbuildLoader = {

456

module: 'esbuild-register/dist/node',

457

register: (mod, config) => {

458

const defaultConfig = {

459

target: 'node' + process.version.slice(1),

460

hookMatcher: filename => filename.endsWith('.ts')

461

};

462

463

mod.register(Object.assign({}, defaultConfig, config, { extensions: ['.ts'] }));

464

}

465

};

466

467

// SWC configuration example

468

const swcLoader = {

469

module: '@swc/register',

470

register: (hook, config) => {

471

const defaultConfig = {

472

only: [filename => filename.endsWith('.ts')],

473

ignore: [filepath => filepath.includes('node_modules')],

474

jsc: {

475

parser: { syntax: 'typescript' }

476

},

477

module: { type: 'commonjs' }

478

};

479

480

hook(Object.assign({}, defaultConfig, config, { extensions: '.ts' }));

481

}

482

};

483

```

484

485

## Error Handling

486

487

The package itself does not throw errors - it provides configuration data. However, when implementing loader registration, common error scenarios include:

488

489

- **Missing dependencies**: Loader modules not installed

490

- **Configuration errors**: Invalid configuration passed to register functions

491

- **Loader conflicts**: Multiple loaders registering for the same extension

492

- **Syntax errors**: Files that don't match the expected syntax for their extension

493

494

```javascript

495

function safeRegisterLoader(extension, filepath) {

496

try {

497

return attemptRequire(extension, filepath);

498

} catch (err) {

499

if (err.code === 'MODULE_NOT_FOUND') {

500

console.warn(`Loader for ${extension} not installed:`, err.message);

501

// Optionally fall back to default loader

502

return require(filepath);

503

}

504

throw err;

505

}

506

}

507

```