Skip to content

Commit

Permalink
Replace eslint and prettier with biome
Browse files Browse the repository at this point in the history
  • Loading branch information
willcrichton committed Jun 27, 2024
1 parent d0cdae7 commit d456838
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 100 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Depot works on Javascript workspaces that have been created by Depot, specifical
* For libraries, transpiles with [Typescript]
* For scripts and websites, bundles with [Vite]
* `depot test` - runs tests with [Vitest]
* `depot fmt` - formats source files with [Prettier]
* `depot fmt` - formats source files with [Biome]
* `depot doc` - generates documentation with [Typedoc]

A few benefits of using Depot:
Expand Down Expand Up @@ -93,6 +93,6 @@ Depot is used in a few of our projects:
[Typescript]: https://www.typescriptlang.org/
[Vite]: https://vitejs.dev/
[Vitest]: https://vitest.dev/
[Prettier]: https://prettier.io/
[Biome]: https://biomejs.dev/
[Typedoc]: https://typedoc.org/
[pnpm]: https://pnpm.io/
13 changes: 7 additions & 6 deletions crates/depot/src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct BuildArgs {
#[clap(short, long, action)]
pub watch: bool,

/// Fail if eslint finds a lint issue
/// Fail if biome finds a lint issue
#[clap(short, long, action)]
pub lint_fail: bool,
}
Expand Down Expand Up @@ -62,7 +62,7 @@ impl PackageCommand for BuildCommand {
Target::Lib => processes.push(self.copy_assets(pkg).boxed()),
}

processes.extend([self.tsc(pkg).boxed(), self.eslint(pkg).boxed()]);
processes.extend([self.tsc(pkg).boxed(), self.biome(pkg).boxed()]);

try_join_all(processes).await?;

Expand Down Expand Up @@ -105,15 +105,16 @@ impl BuildCommand {
.await
}

async fn eslint(&self, pkg: &Package) -> Result<()> {
let process = pkg.start_process("eslint", |cmd| {
async fn biome(&self, pkg: &Package) -> Result<()> {
let process = pkg.start_process("biome", |cmd| {
cmd.arg("check");
cmd.args(pkg.source_files());
cmd.arg("--color");
cmd.arg("--colors=force");
// TODO: watch mode
})?;

let status = process.wait().await?;
ensure!(!self.args.lint_fail || status.success(), "eslint failed");
ensure!(!self.args.lint_fail || status.success(), "biome failed");

Ok(())
}
Expand Down
9 changes: 5 additions & 4 deletions crates/depot/src/commands/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use anyhow::{Context, Result};

use crate::workspace::{package::Package, Command, CoreCommand, PackageCommand};

/// Fix eslint issues where possible
/// Fix biome issues where possible
#[derive(clap::Parser, Debug)]
pub struct FixArgs {
/// Additional arguments to pass to prettier
#[arg(last = true)]
pub eslint_args: Option<String>,
pub biome_args: Option<String>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -35,13 +35,14 @@ impl CoreCommand for FixCommand {
#[async_trait::async_trait]
impl PackageCommand for FixCommand {
async fn run_pkg(&self, pkg: &Package) -> Result<()> {
let extra = match &self.args.eslint_args {
let extra = match &self.args.biome_args {
Some(args) => shlex::split(args).context("Failed to parse prettier args")?,
None => Vec::new(),
};

let _ = pkg
.exec("eslint", |cmd| {
.exec("biome", |cmd| {
cmd.arg("check");
cmd.arg("--fix");
cmd.args(pkg.source_files());
cmd.args(extra);
Expand Down
7 changes: 5 additions & 2 deletions crates/depot/src/commands/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ impl PackageCommand for FmtCommand {
};

pkg
.exec("prettier", |cmd| {
cmd.arg(if self.args.check { "-c" } else { "-w" });
.exec("biome", |cmd| {
cmd.arg("format");
if !self.args.check {
cmd.arg("--write");
}
cmd.args(pkg.source_files());
cmd.args(extra);
})
Expand Down
118 changes: 34 additions & 84 deletions crates/depot/src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl NewCommand {
("pnpm-workspace.yaml".into(), PNPM_WORKSPACE.into()),
];
files.extend(self.make_tsconfig()?);
files.extend(self.make_eslint_config()?);
files.extend(Self::make_biome_config()?);
files.extend(self.make_typedoc_config()?);
files.extend(Self::make_prettier_config());
files.extend(Self::make_gitignore());
Expand Down Expand Up @@ -242,7 +242,9 @@ impl NewCommand {
// Allows special Vite things like importing files with ?raw
files.push((
"src/bindings/vite.d.ts".into(),
r#"/// <reference types="vite/client" />"#.into(),
r#"/// <reference types="vite/client" />
"#
.into(),
));
}
}
Expand All @@ -252,77 +254,28 @@ impl NewCommand {
Ok(files)
}

fn make_eslint_config(&self) -> Result<FileVec> {
let mut config = json!({
"env": {
"es2021": true,
fn make_biome_config() -> Result<FileVec> {
let config = json!({
"$schema": "https://biomejs.dev/schemas/1.8.2/schema.json",
"organizeImports": {
"enabled": true
},
"extends": ["eslint:recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 13,
"sourceType": "module",
"formatter": {
"enabled": true,
"indentStyle": "space"
},
"plugins": ["@typescript-eslint", "prettier", "eslint-plugin-unused-imports"],
"ignorePatterns": ["*.d.ts"],
"rules": {
"no-empty-pattern": "off",
"no-undef": "off",
"no-unused-vars": "off",
"no-cond-assign": "off",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"varsIgnorePattern": "^_",
"args": "after-used",
"argsIgnorePattern": "^_",
},
],
"no-constant-condition": ["error", { "checkLoops": false }],
"prettier/prettier": "error",
},
});

if !self.args.workspace && self.ws_opt.is_some() {
config = json!({
"extends": "../../.eslintrc.cjs"
});

let platform_config = match self.args.platform {
Platform::Browser => json!({
"env": {"browser": true},
}),
Platform::Node => json!({
"env": {"node": true},
}),
};

json_merge(&mut config, platform_config);
}

if self.args.react {
let react_config = json!({
"plugins": ["react"],
"linter": {
"enabled": true,
"rules": {
"react/prop-types": "off",
"react/no-unescaped-entities": "off",
},
"settings": {
"react": {
"version": "detect",
},
"recommended": true,
"correctness": {"noUnusedImports": "warn"},
"style": {"noNonNullAssertion": "off", "useConst": "off"}
}
});

json_merge(&mut config, react_config);
}
}
});

let config_str = serde_json::to_string_pretty(&config)?;
let src = format!("module.exports = {config_str}");
Ok(vec![(".eslintrc.cjs".into(), src.into())])
Ok(vec![("biome.json".into(), config_str.into())])
}

#[allow(clippy::too_many_lines)]
Expand Down Expand Up @@ -539,7 +492,7 @@ export default defineConfig(({{ mode }}) => ({{

fn install_ws_dependencies(&self, root: &Path, is_workspace: bool) -> Result<()> {
#[rustfmt::skip]
let mut ws_dependencies: Vec<&str> = vec![
let ws_dependencies: Vec<&str> = vec![
// Building
"vite",

Expand All @@ -550,32 +503,29 @@ export default defineConfig(({{ mode }}) => ({{
"typescript",
"@types/node",

// Linting
"eslint@8",
"@typescript-eslint/eslint-plugin@7",
"@typescript-eslint/parser@7",
"eslint-plugin-prettier@4",
"eslint-plugin-unused-imports@3",

// Formatting
"prettier@2",
"@trivago/prettier-plugin-sort-imports@4",
// Linting and formatting
"@biomejs/biome",

// Documentation generation
"typedoc"
];

if self.args.react {
ws_dependencies.extend(["eslint-plugin-react", "eslint-plugin-react-hooks"]);
}

self.run_pnpm(|pnpm| {
pnpm.args(["add", "--save-dev"]).args(&ws_dependencies);
if is_workspace {
pnpm.arg("--workspace-root");
}
pnpm.current_dir(root);
})
})?;

// Temporary fix for installing native modules on M-series Macs.
// --force ensures that the arm64 package is installed for Biome.
self.run_pnpm(|pnpm| {
pnpm.args(["install", "--force"]);
pnpm.current_dir(root);
})?;

Ok(())
}

fn make_index_html(js_entry_point: &str, css_entry_point: &str) -> String {
Expand Down Expand Up @@ -747,7 +697,7 @@ export default defineConfig(({{ mode }}) => ({{
),
]);
files.extend(self.make_tsconfig()?);
files.extend(self.make_eslint_config()?);
files.extend(Self::make_biome_config()?);
files.extend(self.make_vite_config(src_path));

if self.ws_opt.is_none() {
Expand Down
1 change: 1 addition & 0 deletions crates/depot/src/workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ impl WorkspaceInner {

let mut cmd = tokio::process::Command::new(script_path);
cmd.current_dir(&self.root);
cmd.env("NODE_PATH", self.root.join("node_modules"));

configure(&mut cmd);

Expand Down
2 changes: 1 addition & 1 deletion crates/depot/tests/tests/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use depot_test_utils::{project, workspace_single_lib};

#[test]
fn basic() {
let p = project();
let p = project().persist();
p.file("src/lib.ts", "let x = 1 + 2;");
p.depot("fmt");
assert_eq!(p.read("src/lib.ts"), "let x = 1 + 2;\n");
Expand Down
2 changes: 1 addition & 1 deletion crates/depot/tests/tests/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ use depot_test_utils::project;
#[test]
fn formatting() {
let p = project();
p.depot("fmt -- --check");
p.depot("fmt --check");
}

0 comments on commit d456838

Please sign in to comment.