or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

analysis-correctness.mdconfigs.mdenvironment-specific.mdindex.mdmodule-systems.mdpath-resolution.mdstatic-analysis.mdstyle-organization.mdtypescript.md
tile.json

module-systems.mddocs/

Module System Rules

These rules enforce or forbid specific module system patterns (CommonJS, AMD, ES modules) to maintain consistency across the codebase. They help standardize module usage and prevent mixing incompatible module formats.

ES Module Enforcement

unambiguous

Forbids potentially ambiguous parse goals (files that could be interpreted as either script or module).

const unambiguous: RuleModule<'module', []>;

Example:

// ✗ BAD - ambiguous file (no imports/exports)
const helper = () => {
  return 'help';
};

// ✓ GOOD - unambiguous module (has import/export)
import utils from './utils';
const helper = () => {
  return 'help';  
};
export { helper };

// ✓ GOOD - unambiguous script (explicitly no module syntax)
// Use .cjs extension or configure as script

CommonJS Restrictions

no-commonjs

Forbids CommonJS require calls and module.exports or exports.* assignments.

const noCommonjs: RuleModule<'import' | 'export', [
  {
    allowRequire?: boolean;
    allowPrimitiveModules?: boolean;
    allowConditionalRequire?: boolean;
  }?
]>;

Options:

  • allowRequire (boolean): Allow require() calls (default: false)
  • allowPrimitiveModules (boolean): Allow primitive module.exports (default: false)
  • allowConditionalRequire (boolean): Allow conditional requires (default: true)

Example:

// ✗ BAD - CommonJS syntax
const utils = require('./utils');
module.exports = { helper };
exports.config = {};

// ✓ GOOD - ES module syntax
import utils from './utils';
export { helper };
export const config = {};

// ✓ GOOD - conditional require (if allowConditionalRequire: true)
if (typeof require !== 'undefined') {
  const optional = require('./optional');
}

no-import-module-exports

Forbids the use of import declarations with module.exports (mixing module systems).

const noImportModuleExports: RuleModule<'notBothAllowed', [
  {
    exceptions?: string[];
  }?
]>;

Options:

  • exceptions (string[]): File patterns to exclude from this rule

Example:

// ✗ BAD - mixing import and module.exports
import React from 'react';
module.exports = MyComponent;

// ✓ GOOD - consistent ES modules
import React from 'react';
export default MyComponent;

// ✓ GOOD - consistent CommonJS
const React = require('react');
module.exports = MyComponent;

AMD Restrictions

no-amd

Forbids AMD require and define calls.

const noAmd: RuleModule<'import' | 'export', []>;

Example:

// ✗ BAD - AMD syntax
define(['./utils'], function(utils) {
  return { helper: utils.helper };
});

require(['./utils'], function(utils) {
  utils.process();
});

// ✓ GOOD - ES module syntax
import utils from './utils';
export { helper: utils.helper };

Dynamic Import Restrictions

no-dynamic-require

Forbids require() calls with expressions.

const noDynamicRequire: RuleModule<'import' | 'require', [
  {
    esmodule?: boolean;
  }?
]>;

Options:

  • esmodule (boolean): Also forbid dynamic import() calls (default: false)

Example:

// ✗ BAD - dynamic require with variable
const moduleName = 'lodash';
const lib = require(moduleName);

// ✗ BAD - dynamic require with template literal
const lib = require(`./modules/${type}`);

// ✓ GOOD - static require
const lib = require('lodash');
const utils = require('./modules/utils');

// ✓ GOOD - dynamic import() (if esmodule: false)
const lib = await import('lodash');

Named Import Patterns

no-named-default

Forbids named default exports.

const noNamedDefault: RuleModule<'default', []>;

Example:

// ✗ BAD - named default export
export { default } from './module';
export { default as namedDefault } from './module';

// ✓ GOOD - proper default export
export { default } from './module'; // re-export as default
import defaultExport from './module';
export { defaultExport };

no-namespace

Forbids namespace (wildcard *) imports.

const noNamespace: RuleModule<'namespace', [
  {
    ignore?: string[];
  }?
]>;

Options:

  • ignore (string[]): Module patterns to ignore

Example:

// ✗ BAD - namespace import
import * as utils from './utils';

// ✓ GOOD - named imports
import { helper, process } from './utils';

// ✓ GOOD - default import
import utils from './utils';

Module Type Validation

consistent-type-specifier-style

Enforces consistent usage of type specifiers in import/export statements.

const consistentTypeSpecifierStyle: RuleModule<'typeOverValue' | 'valueOverType', [
  'prefer-inline' | 'prefer-top-level'
]>;

Options:

  • 'prefer-inline': Prefer inline type specifiers
  • 'prefer-top-level': Prefer top-level type imports

Example:

// With 'prefer-inline'
// ✗ BAD - top-level type import
import type { User } from './types';
import { getName } from './types';

// ✓ GOOD - inline type specifiers
import { type User, getName } from './types';

// With 'prefer-top-level'  
// ✗ BAD - mixed inline specifiers
import { type User, getName } from './types';

// ✓ GOOD - separate type and value imports
import type { User } from './types';
import { getName } from './types';

Module System Types

type ModuleSystem = 'commonjs' | 'amd' | 'es6' | 'umd';

interface ModuleInfo {
  system: ModuleSystem;
  hasImports: boolean;
  hasExports: boolean;
  hasDynamicImports: boolean;
  isAmbiguous: boolean;
}

interface CommonJSOptions {
  allowRequire?: boolean;
  allowPrimitiveModules?: boolean;
  allowConditionalRequire?: boolean;
}

interface TypeSpecifierOptions {
  style: 'prefer-inline' | 'prefer-top-level';
}

interface NamespaceOptions {
  ignore?: string[];
}

Migration Strategies

CommonJS to ES Modules

// Before (CommonJS)
const fs = require('fs');
const { join } = require('path');
const utils = require('./utils');

function helper() {
  return utils.process();
}

module.exports = { helper };

// After (ES Modules)
import fs from 'fs';
import { join } from 'path';
import utils from './utils';

function helper() {
  return utils.process();
}

export { helper };

AMD to ES Modules

// Before (AMD)
define(['./utils', 'lodash'], function(utils, _) {
  return {
    process: function(data) {
      return _.map(data, utils.transform);
    }
  };
});

// After (ES Modules)
import utils from './utils';
import _ from 'lodash';

export function process(data) {
  return _.map(data, utils.transform);
}