Skip to content

Commit

Permalink
Nested src dir shows up in out dir swc-project#108
Browse files Browse the repository at this point in the history
  • Loading branch information
kimhongsu committed Mar 12, 2022
1 parent d60fa69 commit 0faa881
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 42 deletions.
63 changes: 32 additions & 31 deletions src/swc/dir.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import slash from "slash";
import { existsSync, promises } from "fs";
import { dirname, relative, join } from "path";
import { dirname, relative, join, isAbsolute, resolve } from "path";
import { CompileStatus } from "./constants";
import { CliOptions } from "./options";
import { compile } from "./util";
Expand All @@ -11,6 +11,7 @@ import {
slitCompilableAndCopyable,
watchSources,
} from "./sources";
import { File } from "./file";

import type { Options } from "@swc/core";

Expand All @@ -29,36 +30,24 @@ const { mkdir, rmdir, rm, copyFile, unlink } = promises;
const cwd = process.cwd();
const recursive = { recursive: true };

/**
* Removes the leading directory, including all parent relative paths
*/
function stripComponents(filename: string) {
const components = filename.split("/").slice(1);
if (!components.length) {
return filename;
}
while (components[0] === "..") {
components.shift();
}
return components.join("/");
}
function getDest(file: File, outDir: string, ext?: string) {
const outDirAbsolutePath = slash(resolve(cwd, outDir));
let relativePath = slash(file.filename.slice(file.sourceLength));

function getDest(filename: string, outDir: string, ext?: string) {
const relativePath = slash(relative(cwd, filename));
let base = stripComponents(relativePath);
if (ext) {
base = base.replace(/\.\w*$/, ext);
relativePath = relativePath.replace(/\.\w*$/, ext);
}
return join(outDir, base);
return join(outDirAbsolutePath, relativePath);
}

async function handleCompile(
filename: string,
file: File,
outDir: string,
sync: boolean,
swcOptions: Options
) {
const dest = getDest(filename, outDir, ".js");
const dest = getDest(file, outDir, ".js");
const filename = file.filename;
const sourceFileName = slash(relative(dirname(dest), filename));

const options = { ...swcOptions, sourceFileName };
Expand All @@ -73,11 +62,11 @@ async function handleCompile(
}
}

async function handleCopy(filename: string, outDir: string) {
const dest = getDest(filename, outDir);
async function handleCopy(file: File, outDir: string) {
const filename = file.filename;
const dest = getDest(file, outDir);
const dir = dirname(dest);

console.log(filename);
await mkdir(dir, recursive);
await copyFile(filename, dest);

Expand All @@ -95,6 +84,15 @@ async function beforeStartCompilation(cliOptions: CliOptions) {
}
}

function absolutePath(filenames: string[], cwd: string): string[] {
return filenames.map((filename: string) => {
if (!isAbsolute(filename)) {
filename = resolve(cwd, filename);
}
return filename;
});
}

async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) {
const {
includeDotfiles,
Expand All @@ -110,26 +108,29 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) {
const results = new Map<string, CompileStatus>();

const start = process.hrtime();
const sourceFiles = await globSources(filenames, includeDotfiles);
const filenamesAbsolutePath = absolutePath(filenames, cwd);
const sourceFiles = await globSources(filenamesAbsolutePath, includeDotfiles);
const [compilable, copyable] = slitCompilableAndCopyable(
sourceFiles,
extensions,
copyFiles
);

if (sync) {
for (const filename of compilable) {
for (const file of compilable) {
const filename = file.filename;
try {
const result = await handleCompile(filename, outDir, sync, swcOptions);
const result = await handleCompile(file, outDir, sync, swcOptions);
results.set(filename, result);
} catch (err) {
console.error(err.message);
results.set(filename, CompileStatus.Failed);
}
}
for (const filename of copyable) {
for (const file of copyable) {
const filename = file.filename;
try {
const result = await handleCopy(filename, outDir);
const result = await handleCopy(file, outDir);
results.set(filename, result);
} catch (err) {
console.error(err.message);
Expand All @@ -149,7 +150,7 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) {
Promise.allSettled(copyable.map(file => handleCopy(file, outDir))),
]).then(([compiled, copied]) => {
compiled.forEach((result, index) => {
const filename = compilable[index];
const filename = compilable[index].filename;
if (result.status === "fulfilled") {
results.set(filename, result.value);
} else {
Expand All @@ -158,7 +159,7 @@ async function initialCompilation(cliOptions: CliOptions, swcOptions: Options) {
});

copied.forEach((result, index) => {
const filename = copyable[index];
const filename = copyable[index].filename;
if (result.status === "fulfilled") {
results.set(filename, result.value);
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/swc/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { CliOptions } from "./options";
import { globSources, isCompilableExtension, watchSources } from "./sources";
import * as util from "./util";

export interface File {
filename: string;
sourceLength: number;
}

export default async function ({
cliOptions,
swcOptions,
Expand Down
2 changes: 1 addition & 1 deletion src/swc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import dirCommand from "./dir";
import fileCommand from "./file";
import parseArgs, { initProgram } from "./options";

initProgram()
initProgram();
const opts = parseArgs(process.argv);
const fn = opts.cliOptions.outDir ? dirCommand : fileCommand;

Expand Down
35 changes: 25 additions & 10 deletions src/swc/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import glob from "fast-glob";
import slash from "slash";
import { stat } from "fs";
import { join, basename, extname } from "path";
import { File } from "./file";

/**
* Find all input files based on source globs
*/
export async function globSources(
sources: string[],
includeDotfiles = false
): Promise<string[]> {
): Promise<File[]> {
const globConfig = {
dot: includeDotfiles,
nodir: true,
Expand All @@ -19,28 +20,42 @@ export async function globSources(
sources
.filter(source => includeDotfiles || !basename(source).startsWith("."))
.map(source => {
return new Promise<string[]>(resolve => {
return new Promise<File[]>(resolve => {
stat(source, (err, stat) => {
if (err) {
resolve([]);
return;
}
if (!stat.isDirectory()) {
resolve([source]);
const file: File = {
filename: source,
sourceLength: basename(source).length,
};
resolve([file]);
} else {
glob(slash(join(source, "**")), globConfig)
.then(matches => resolve(matches))
.then(matches =>
resolve(
matches.map(match => {
const file: File = {
filename: match,
sourceLength: source.length,
};
return file;
})
)
)
.catch(() => resolve([]));
}
});
});
})
);

return Array.from(new Set<string>(files.flat()));
return Array.from(new Set<File>(files.flat()));
}

type Split = [compilable: string[], copyable: string[]];
type Split = [compilable: File[], copyable: File[]];

/**
* Test if a filename ends with a compilable extension.
Expand All @@ -57,15 +72,15 @@ export function isCompilableExtension(
* Split file list to files that can be compiled and copied
*/
export function slitCompilableAndCopyable(
files: string[],
files: File[],
allowedExtension: string[],
copyFiles: boolean
): Split {
const compilable: string[] = [];
const copyable: string[] = [];
const compilable: File[] = [];
const copyable: File[] = [];

for (const file of files) {
const isCompilable = isCompilableExtension(file, allowedExtension);
const isCompilable = isCompilableExtension(file.filename, allowedExtension);

if (isCompilable) {
compilable.push(file);
Expand Down

0 comments on commit 0faa881

Please sign in to comment.