Skip to content

Commit

Permalink
feat: support configuration file written in TypeScript (#2227)
Browse files Browse the repository at this point in the history
* chore: add editorconfig to the project

This unifies all editors configuration

* refactor: move loadConfig out of rspack-cli

* feat: support using ts as configuration file

* test: add test for typescript config file

fix #2188

* feat: report ts-node require error
  • Loading branch information
HerringtonDarkholme committed Mar 13, 2023
1 parent 665aae9 commit c4c20d6
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-cameras-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rspack/cli": patch
---

Support TypeScript as configuration file.
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
root = true

[*.{js,ts}]
indent_style = tab
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80

[*.{yml,yaml,json}]
indent_style = space
indent_size = 2

[test/cases/parsing/bom/bomfile.{css,js}]
charset = utf-8-bom

[*.md]
trim_trailing_whitespace = false
5 changes: 4 additions & 1 deletion packages/rspack-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"source-map-support": "^0.5.19",
"ts-node": "10.9.1"
},
"peerDependencies": {
"ts-node": "10.9.1"
},
"dependencies": {
"@discoveryjs/json-ext": "^0.5.7",
"@rspack/core": "workspace:*",
Expand All @@ -37,4 +40,4 @@
"webpack-bundle-analyzer": "4.6.1",
"yargs": "17.6.2"
}
}
}
46 changes: 2 additions & 44 deletions packages/rspack-cli/src/rspack-cli.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import { hideBin } from "yargs/helpers";
import yargs from "yargs";
import util from "util";
import path from "path";
import fs from "fs";
import { RspackCLIColors, RspackCLILogger, RspackCLIOptions } from "./types";
import { BuildCommand } from "./commands/build";
import { ServeCommand } from "./commands/serve";
import {
RspackOptions,
MultiCompilerOptions,
createMultiCompiler,
createCompiler,
MultiCompiler,
Compiler,
rspack,
MultiRspackOptions
} from "@rspack/core";
import { normalizeEnv } from "./utils/options";
import { loadRspackConfig } from "./utils/loadConfig";
import { Mode } from "@rspack/core/src/config";

const defaultConfig = "rspack.config.js";
const defaultEntry = "src/index.js";
type Callback<T> = <T>(err: Error, res?: T) => void;
type RspackEnv = "development" | "production";
export class RspackCLI {
colors: RspackCLIColors;
Expand Down Expand Up @@ -181,42 +174,7 @@ export class RspackCLI {
async loadConfig(
options: RspackCLIOptions
): Promise<RspackOptions | MultiRspackOptions> {
let loadedConfig:
| undefined
| RspackOptions
| MultiRspackOptions
| ((
env: Record<string, any>,
argv: Record<string, any>
) => RspackOptions | MultiRspackOptions);
// if we pass config paras
if (options.config) {
const resolvedConfigPath = path.resolve(process.cwd(), options.config);
if (!fs.existsSync(resolvedConfigPath)) {
throw new Error(`config file "${resolvedConfigPath}" not exists`);
}
loadedConfig = require(resolvedConfigPath);
} else {
let defaultConfigPath = path.resolve(process.cwd(), defaultConfig);
if (fs.existsSync(defaultConfigPath)) {
loadedConfig = require(defaultConfigPath);
} else {
let entry: Record<string, string> = {};
if (options.entry) {
entry = {
main: options.entry.map(x => path.resolve(process.cwd(), x))[0] // Fix me when entry supports array
};
} else {
entry = {
main: path.resolve(process.cwd(), defaultEntry)
};
}
loadedConfig = {
entry
};
}
}

let loadedConfig = loadRspackConfig(options);
if (options.configName) {
const notFoundConfigNames: string[] = [];

Expand Down
83 changes: 83 additions & 0 deletions packages/rspack-cli/src/utils/loadConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import path from "path";
import fs from "fs";
import { RspackCLIOptions } from "../types";
import { RspackOptions, MultiRspackOptions } from "@rspack/core";

const supportedExtensions = [".js", ".ts"];
const defaultConfig = "rspack.config";
const defaultEntry = "src/index";

export type LoadedRspackConfig =
| undefined
| RspackOptions
| MultiRspackOptions
| ((
env: Record<string, any>,
argv: Record<string, any>
) => RspackOptions | MultiRspackOptions);

export function loadRspackConfig(
options: RspackCLIOptions
): LoadedRspackConfig {
let loadedConfig: LoadedRspackConfig;
// if we pass config paras
if (options.config) {
const resolvedConfigPath = path.resolve(process.cwd(), options.config);
if (!fs.existsSync(resolvedConfigPath)) {
throw new Error(`config file "${resolvedConfigPath}" not exists`);
}
loadedConfig = requireWithAdditionalExtension(resolvedConfigPath);
} else {
let defaultConfigPath = findFileWithSupportedExtensions(
path.resolve(process.cwd(), defaultConfig)
);
if (defaultConfigPath != null) {
loadedConfig = requireWithAdditionalExtension(defaultConfigPath);
} else {
let entry: Record<string, string> = {};
if (options.entry) {
entry = {
main: options.entry.map(x => path.resolve(process.cwd(), x))[0] // Fix me when entry supports array
};
} else {
const defaultEntryBase = path.resolve(process.cwd(), defaultEntry);
const defaultEntryPath =
findFileWithSupportedExtensions(defaultEntryBase) ||
defaultEntryBase + ".js"; // default entry is js
entry = {
main: defaultEntryPath
};
}
loadedConfig = {
entry
};
}
}
return loadedConfig;
}

// takes a basePath like `webpack.config`, return `webpack.config.{js,ts}` if
// exists. returns null if none of them exists
function findFileWithSupportedExtensions(basePath: string): string | null {
for (const extension of supportedExtensions) {
if (fs.existsSync(basePath + extension)) {
return basePath + extension;
}
}
return null;
}

let hasRegisteredTS = false;
function requireWithAdditionalExtension(resolvedPath: string) {
if (resolvedPath.endsWith("ts") && !hasRegisteredTS) {
hasRegisteredTS = true;
let tsNode: any;
try {
tsNode = require("ts-node");
} catch (e) {
throw new Error("`ts-node` is required to use TypeScript configuration.");
}
tsNode.register({ transpileOnly: true });
}
return require(resolvedPath);
}
1 change: 1 addition & 0 deletions packages/rspack-cli/tests/build/typescript/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Main typescript file");
12 changes: 12 additions & 0 deletions packages/rspack-cli/tests/build/typescript/rspack.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as path from "path";

const config = {
mode: "production",
entry: "./main.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "foo.bundle.js",
},
};

export = config;
5 changes: 5 additions & 0 deletions packages/rspack-cli/tests/build/typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"module": "commonjs"
}
}
26 changes: 26 additions & 0 deletions packages/rspack-cli/tests/build/typescript/typescript.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { run } from "../../utils/test-utils";
import { existsSync } from "fs";
import { resolve } from "path";

describe("webpack cli", () => {
it("should support default config in typescript", async () => {
const { exitCode, stderr, stdout } = await run(__dirname, []);

expect(stderr).toBeFalsy();
expect(stdout).toBeTruthy();
expect(exitCode).toBe(0);
expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy();
});

it("should support specifying config in typescript", async () => {
const { exitCode, stderr, stdout } = await run(__dirname, [
"-c",
"./rspack.config.ts"
]);

expect(stderr).toBeFalsy();
expect(stdout).toBeTruthy();
expect(exitCode).toBe(0);
expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy();
});
});
2 changes: 1 addition & 1 deletion packages/rspack-cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
"path": "../rspack-dev-server"
}
]
}
}

0 comments on commit c4c20d6

Please sign in to comment.