oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.26k stars 2.69k forks source link

add a flag to enforce file extensions in import specifiers #12599

Open huseeiin opened 2 months ago

huseeiin commented 2 months ago

What is the problem this feature would solve?

its a better practice to enter a specific extension that you want instead of leaving it empty in the import statement. this can also save time (and performance!) as trying to looking for ./my-module.js from just ./my-module can be expensive. this is explained better in https://vitejs.dev/guide/performance.html#reduce-resolve-operations

What is the feature you are proposing to solve the problem?

add a --strict-imports (the name doesn't matter) flag that requires extensions in CJS, ESM and dynamic imports. I'm imagining this in the Bun runtime specifically and does not apply to node_modules. it is up for the Bun team to decide whether they should incorporate this in bun build, bun test etc.

What alternatives have you considered?

none

huseeiin commented 1 month ago

like deno won't let you import ./file.ts without the ".ts"

Jarred-Sumner commented 1 month ago

this can be done via linter rules

huseeiin commented 1 month ago
// @ts-check

import { ESLintUtils } from "@typescript-eslint/utils";
import { existsSync } from "node:fs";

const createRule = ESLintUtils.RuleCreator(
    (name) => `https://example.com/rule/${name}`,
);

export const rule = createRule({
    create(context) {
        return {
            ImportDeclaration(node) {
                const module = node.source.value;

                if (
                    (module.startsWith("/") || module.startsWith("./") ||
                        module.startsWith("../")) && !existsSync(module)
                ) {
                    context.report({
                        node,
                        messageId: "extensionsInImports",
                    });
                }
            },
        };
    },
    name: "strict-import-extensions",
    meta: {
        docs: {
            description:
                "Use extensions for modules that are not in `node_modules`",
        },
        messages: {
            extensionsInImports:
                "Import specifier should include the file's correct extension",
        },
        type: "problem",
        schema: [],
    },
    defaultOptions: [],
});

this is the eslint rule (this also describes what this issue requests) if anyone needs it