refactor: add explicit return types (#412)

This commit is contained in:
Pooya Parsa 2024-07-02 14:54:38 +02:00 committed by GitHub
parent 0cabd3c701
commit 6e82b090ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 83 additions and 59 deletions

View File

@ -37,7 +37,7 @@ CLI output also includes output size and exports for quick inspection.
Create `src/index.ts`:
```ts
```js
export const log = (...args) => {
console.log(...args);
};
@ -75,7 +75,7 @@ Configuration is automatically inferred from fields in `package.json` mapped to
Create `build.config.ts`:
```ts
```js
export default {
entries: ["./src/index"],
};
@ -87,7 +87,7 @@ See options [here](./src/types.ts).
Example:
```ts
```js
import { defineBuildConfig } from "unbuild";
export default defineBuildConfig({
@ -113,7 +113,7 @@ export default defineBuildConfig({
Or with multiple builds you can declare an array of configs:
```ts
```js
import { defineBuildConfig } from "unbuild";
export default defineBuildConfig([

View File

@ -3,14 +3,20 @@ import unjs from "eslint-config-unjs";
// https://github.com/unjs/eslint-config
export default unjs({
ignores: [
".git"
],
".git",
],
rules: {
"unicorn/no-null": 0,
"unicorn/prevent-abbreviations": 0,
"unicorn/prefer-module": 0,
"unicorn/prefer-top-level-await": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-unused-vars": 0
},
});
"unicorn/no-null": 0,
"unicorn/prevent-abbreviations": 0,
"unicorn/prefer-module": 0,
"unicorn/prefer-top-level-await": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-unused-vars": 0,
},
}, {
files: ["**/*.ts"],
rules: {
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/no-inferrable-types": "error",
}
});

View File

@ -1,3 +1,3 @@
export default function sum(a: number, b: number) {
export default function sum(a: number, b: number): number {
return a + b;
}

View File

@ -20,6 +20,7 @@ export const config = {
height: 10,
},
tags: {
$resolve: (val?: string[]) => ["tag1", ...(val || [])].filter(Boolean),
$resolve: (val?: string[]): string[] =>
["tag1", ...(val || [])].filter(Boolean),
},
};

View File

@ -16,7 +16,7 @@ type InferEntriesResult = {
export const autoPreset = definePreset(() => {
return {
hooks: {
"build:prepare"(ctx) {
"build:prepare"(ctx): void {
// Disable auto if entries already provided or pkg not available
if (!ctx.pkg || ctx.options.entries.length > 0) {
return;
@ -167,7 +167,7 @@ export function inferEntries(
return { entries, cjs, dts, warnings };
}
export const getEntrypointPaths = (path: string) => {
export const getEntrypointPaths = (path: string): string[] => {
const segments = normalize(path).split("/");
return segments
.map((_, index) => segments.slice(index).join("/"))

View File

@ -23,7 +23,7 @@ export async function build(
rootDir: string,
stub: boolean,
inputConfig: BuildConfig = {},
) {
): Promise<void> {
// Determine rootDir
rootDir = resolve(process.cwd(), rootDir || ".");
@ -67,7 +67,7 @@ async function _build(
cleanedDirs: string[],
_stubMode: boolean,
_watchMode: boolean,
) {
): Promise<void> {
// Resolve preset
const preset = await resolvePreset(
buildConfig.preset ||
@ -305,7 +305,7 @@ async function _build(
}
}
const rPath = (p: string) =>
const rPath = (p: string): string =>
relative(process.cwd(), resolve(options.outDir, p));
for (const entry of ctx.buildEntries.filter((e) => !e.chunk)) {
let totalBytes = entry.bytes || 0;

View File

@ -7,7 +7,7 @@ import consola from "consola";
const copy = fsp.cp || fsp.copyFile;
export async function copyBuild(ctx: BuildContext) {
export async function copyBuild(ctx: BuildContext): Promise<void> {
const entries = ctx.options.entries.filter(
(e) => e.builder === "copy",
) as CopyBuildEntry[];

View File

@ -4,7 +4,7 @@ import { symlink, rmdir } from "../../utils";
import type { MkdistBuildEntry, BuildContext } from "../../types";
import consola from "consola";
export async function mkdistBuild(ctx: BuildContext) {
export async function mkdistBuild(ctx: BuildContext): Promise<void> {
const entries = ctx.options.entries.filter(
(e) => e.builder === "mkdist",
) as MkdistBuildEntry[];

View File

@ -10,7 +10,7 @@ import { getChunkFilename } from "./utils";
import { rollupStub } from "./stub";
import { rollupWatch } from "./watch";
export async function rollupBuild(ctx: BuildContext) {
export async function rollupBuild(ctx: BuildContext): Promise<void> {
// Stub mode
if (ctx.options.stub) {
await rollupStub(ctx);

View File

@ -133,7 +133,7 @@ export function getRollupOptions(ctx: BuildContext): RollupOptions {
}),
ctx.options.rollup.preserveDynamicImports && {
renderDynamicImport() {
renderDynamicImport(): { left: string; right: string } {
return { left: "import(", right: ")" };
},
},

View File

@ -28,7 +28,7 @@ const require = __cjs_mod__.createRequire(import.meta.url);
`;
// Shim __dirname, __filename and require
function CJSToESM(code: string) {
function CJSToESM(code: string): { code: string; map: any } | null {
if (code.includes(CJSShim) || !CJSyntaxRe.test(code)) {
return null;
}

View File

@ -52,7 +52,7 @@ export function esbuild(options: EsbuildOptions): Plugin {
}
}
}
const getLoader = (id = "") => {
const getLoader = (id = ""): Loader | undefined => {
return loaders[extname(id)];
};
@ -61,7 +61,7 @@ export function esbuild(options: EsbuildOptions): Plugin {
return {
name: "esbuild",
async transform(code, id) {
async transform(code, id): Promise<null | { code: string; map: any }> {
if (!filter(id)) {
return null;
}
@ -79,15 +79,18 @@ export function esbuild(options: EsbuildOptions): Plugin {
printWarnings(id, result, this);
return (
result.code && {
code: result.code,
map: result.map || null,
}
);
return result.code
? {
code: result.code,
map: result.map || null,
}
: null;
},
async renderChunk(code, { fileName }) {
async renderChunk(
code,
{ fileName },
): Promise<null | undefined | { code: string; map: any }> {
if (!options.minify) {
return null;
}
@ -118,7 +121,7 @@ function printWarnings(
id: string,
result: TransformResult,
plugin: PluginContext,
) {
): void {
if (result.warnings) {
for (const warning of result.warnings) {
let message = "[esbuild]";

View File

@ -17,7 +17,7 @@ export function rawPlugin(opts: RawLoaderOptions = {}): Plugin {
const filter = createFilter(opts.include, opts.exclude);
return {
name: "unbuild-raw",
transform(code, id) {
transform(code, id): { code: string; map: any } | undefined {
if (filter(id)) {
return {
code: `export default ${JSON.stringify(code)}`,

View File

@ -9,7 +9,7 @@ const SHEBANG_RE = /^#![^\n]*/;
export function shebangPlugin(): Plugin {
return {
name: "unbuild-shebang",
async writeBundle(options, bundle) {
async writeBundle(options, bundle): Promise<void> {
for (const [fileName, output] of Object.entries(bundle)) {
if (output.type !== "chunk") {
continue;
@ -26,17 +26,17 @@ export function shebangPlugin(): Plugin {
export function removeShebangPlugin(): Plugin {
return {
name: "unbuild-remove-shebang",
renderChunk(code) {
renderChunk(code): string {
return code.replace(SHEBANG_RE, "");
},
};
}
export async function makeExecutable(filePath: string) {
export async function makeExecutable(filePath: string): Promise<void> {
await fsp.chmod(filePath, 0o755 /* rwx r-x r-x */).catch(() => {});
}
export function getShebang(code: string, append = "\n") {
export function getShebang(code: string, append = "\n"): string {
const m = code.match(SHEBANG_RE);
return m ? m + append : "";
}

View File

@ -7,7 +7,7 @@ import type { BuildContext } from "../../types";
import { makeExecutable, getShebang } from "./plugins/shebang";
import { DEFAULT_EXTENSIONS, resolveAliases } from "./utils";
export async function rollupStub(ctx: BuildContext) {
export async function rollupStub(ctx: BuildContext): Promise<void> {
const babelPlugins = ctx.options.stubOptions.jiti.transformOptions?.babel
?.plugins as any;
const importedBabelPlugins: Array<string> = [];

View File

@ -13,7 +13,7 @@ export const DEFAULT_EXTENSIONS = [
".json",
];
export function resolveAliases(ctx: BuildContext) {
export function resolveAliases(ctx: BuildContext): Record<string, string> {
const aliases: Record<string, string> = {
[ctx.pkg.name!]: ctx.options.rootDir,
...ctx.options.alias,
@ -57,7 +57,7 @@ export function getChunkFilename(
ctx: BuildContext,
chunk: PreRenderedChunk,
ext: string,
) {
): string {
if (chunk.isDynamicEntry) {
return `chunks/[name].${ext}`;
}

View File

@ -4,7 +4,7 @@ import type { RollupOptions } from "../../types";
import consola from "consola";
import chalk from "chalk";
export function rollupWatch(rollupOptions: RollupOptions) {
export function rollupWatch(rollupOptions: RollupOptions): void {
const watcher = _rollupWatch(rollupOptions);
let inputs: string[];

View File

@ -16,7 +16,7 @@ import type {
} from "../../types";
import consola from "consola";
export async function typesBuild(ctx: BuildContext) {
export async function typesBuild(ctx: BuildContext): Promise<void> {
const entries = ctx.options.entries.filter(
(entry) => entry.builder === "untyped",
) as UntypedBuildEntry[];

View File

@ -7,11 +7,11 @@ import type { PackageJson } from "pkg-types";
import { autoPreset } from "./auto";
import type { BuildPreset, BuildConfig, BuildContext } from "./types";
export async function ensuredir(path: string) {
export async function ensuredir(path: string): Promise<void> {
await fsp.mkdir(dirname(path), { recursive: true });
}
export function warn(ctx: BuildContext, message: string) {
export function warn(ctx: BuildContext, message: string): void {
if (ctx.warnings.has(message)) {
return;
}
@ -19,7 +19,11 @@ export function warn(ctx: BuildContext, message: string) {
ctx.warnings.add(message);
}
export async function symlink(from: string, to: string, force = true) {
export async function symlink(
from: string,
to: string,
force = true,
): Promise<void> {
await ensuredir(to);
if (force) {
await fsp.unlink(to).catch(() => {});
@ -27,7 +31,7 @@ export async function symlink(from: string, to: string, force = true) {
await fsp.symlink(from, to, "junction");
}
export function dumpObject(obj: Record<string, any>) {
export function dumpObject(obj: Record<string, any>): string {
return (
"{ " +
Object.keys(obj)
@ -37,19 +41,19 @@ export function dumpObject(obj: Record<string, any>) {
);
}
export function getpkg(id = "") {
export function getpkg(id = ""): string {
const s = id.split("/");
return s[0][0] === "@" ? `${s[0]}/${s[1]}` : s[0];
}
export async function rmdir(dir: string) {
export async function rmdir(dir: string): Promise<void> {
await fsp.unlink(dir).catch(() => {});
await fsp.rm(dir, { recursive: true, force: true }).catch(() => {});
}
export function listRecursively(path: string) {
export function listRecursively(path: string): string[] {
const filenames = new Set<string>();
const walk = (path: string) => {
const walk = (path: string): void => {
const files = readdirSync(path);
for (const file of files) {
const fullPath = resolve(path, file);
@ -143,7 +147,10 @@ export function extractExportFilenames(
);
}
export function arrayIncludes(arr: (string | RegExp)[], searchElement: string) {
export function arrayIncludes(
arr: (string | RegExp)[],
searchElement: string,
): boolean {
return arr.some((entry) =>
entry instanceof RegExp
? entry.test(searchElement)
@ -151,6 +158,6 @@ export function arrayIncludes(arr: (string | RegExp)[], searchElement: string) {
);
}
export function removeExtension(filename: string) {
export function removeExtension(filename: string): string {
return filename.replace(/\.(js|mjs|cjs|ts|mts|cts|json|jsx|tsx)$/, "");
}

View File

@ -5,7 +5,7 @@ import { PackageJson } from "pkg-types";
import { arrayIncludes, extractExportFilenames, getpkg, warn } from "./utils";
import { BuildContext } from "./types";
export function validateDependencies(ctx: BuildContext) {
export function validateDependencies(ctx: BuildContext): void {
const usedDependencies = new Set<string>();
const unusedDependencies = new Set<string>(
Object.keys(ctx.pkg.dependencies || {}),
@ -50,7 +50,7 @@ export function validatePackage(
pkg: PackageJson,
rootDir: string,
ctx: BuildContext,
) {
): void {
if (!pkg) {
return;
}

View File

@ -18,6 +18,7 @@ describe("validatePackage", () => {
"./cli": "./dist/cli",
},
module: "dist/mod",
// @ts-expect-error TODO: fix pkg-types
exports: {
"./runtime/*": "./runtime/*.mjs",
".": { node: "./src/index.mts" },
@ -60,6 +61,7 @@ describe("validateDependencies", () => {
stub: false,
alias: {},
replace: {},
// @ts-expect-error
rollup: {
replace: false,
alias: false,
@ -79,7 +81,11 @@ describe("validateDependencies", () => {
it("does not print implicit deps warning for peerDependencies", () => {
const logs: string[] = [];
consola.mockTypes((type) =>
type === "warn" ? (str: string) => logs.push(str) : () => {},
type === "warn"
? (str: string): void => {
logs.push(str);
}
: (): void => {},
);
validateDependencies({
@ -99,6 +105,7 @@ describe("validateDependencies", () => {
stub: false,
alias: {},
replace: {},
// @ts-expect-error
rollup: {
replace: false,
alias: false,