Skip to content

[Feature Request]: Allow unresolved imports to be configured as hard errors #9362

@garysassano

Description

@garysassano

What problem does this feature solve?

Rolldown currently supports checks.unresolvedImport as a boolean that controls whether unresolved import warnings are emitted:

export default {
  checks: {
    unresolvedImport: true,
  },
};

This is useful for suppressing or enabling the warning, but it does not appear to provide a built-in way to promote unresolved bare imports from warnings to hard build errors.

For browser-targeted SDK/library bundles, unresolved bare imports are often not acceptable. If a dependency accidentally fails to resolve, the generated browser bundle can still be emitted with an externalized import and fail later at runtime. In these cases, I want the build to fail immediately.

Today this can be implemented with onLog:

export default {
  onLog(level, log, defaultHandler) {
    if (log.code === 'UNRESOLVED_IMPORT') {
      defaultHandler('error', log);
      return;
    }

    defaultHandler(level, log);
  },
};

That works, but it is more imperative than the existing declarative checks configuration and is easy for users to miss. It also requires each project to know the exact log code and implement a custom handler.

The current behavior makes sense as a default because library builds sometimes intentionally leave dependencies external. However, for self-contained browser artifacts it would be useful to express the desired severity directly in config.

What does the proposed API look like?

One possible API is to allow check severities:

export default {
  checks: {
    unresolvedImport: 'error',
  },
};

For compatibility, the existing boolean behavior could remain:

export default {
  checks: {
    unresolvedImport: true,  // emit warning, current behavior
    unresolvedImport: false, // suppress warning, current behavior
  },
};

Possible accepted values:

type CheckSeverity = boolean | 'warning' | 'error';

interface ChecksOptions {
  unresolvedImport?: CheckSeverity;
}

If broader consistency is preferred, this could apply to all checks entries instead of only unresolvedImport:

export default {
  checks: {
    unresolvedImport: 'error',
    circularDependency: 'warning',
    eval: false,
  },
};

Alternative API if changing checks is not desirable:

export default {
  failOnWarnings: ['UNRESOLVED_IMPORT'],
};

or:

export default {
  logSeverity: {
    UNRESOLVED_IMPORT: 'error',
  },
};

The main goal is to make this common policy declarative without requiring a custom onLog hook.

Context

In the Rolldown source, checks.unresolvedImport is documented as controlling whether the warning is emitted. Unresolved path-like imports already become hard errors, while unresolved bare imports are treated as external dependencies and emitted as warnings. This request is specifically about making that latter behavior configurable for projects that require fully resolved/self-contained browser bundles.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Effort

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions