Skip to content

Commit

Permalink
Add support for Vike, remove Prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
willcrichton committed Jun 27, 2024
1 parent 673eddf commit ffb7ed9
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 49 deletions.
9 changes: 0 additions & 9 deletions crates/depot/src/commands/configs/.prettierrc.cjs

This file was deleted.

189 changes: 150 additions & 39 deletions crates/depot/src/commands/new.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::items_after_statements, clippy::too_many_lines)]

use anyhow::{ensure, Result};
use indexmap::{indexmap, IndexMap};
use package_json_schema as pj;
Expand Down Expand Up @@ -55,7 +57,6 @@ test("add", () => expect(add(2, 2)).toBe(4));
const CSS: &str = r#"@import "normalize.css/normalize.css";
"#;

const PRETTIER_CONFIG: &str = include_str!("configs/.prettierrc.cjs");
const PNPM_WORKSPACE: &str = include_str!("configs/pnpm-workspace.yaml");
const VITEST_SETUP: &str = include_str!("configs/setup.ts");

Expand All @@ -81,6 +82,10 @@ pub struct NewArgs {
#[arg(long, action)]
pub react: bool,

/// Add Vike as a project dependency
#[arg(long, action)]
pub vike: bool,

/// Add Sass as a project dependency
#[arg(long, action)]
pub sass: bool,
Expand Down Expand Up @@ -115,6 +120,39 @@ fn json_merge(a: &mut Value, b: Value) {
};
}

#[test]
fn test_json_merge() {
let mut a = json!({
"a": 0,
"b": {
"c": [1],
"d": 2
}
});
json_merge(
&mut a,
json!({
"e": 3,
"b": {
"c": [4],
"f": 5
}
}),
);
assert_eq!(
a,
json!({
"a": 0,
"b": {
"c": [1, 4],
"d": 2,
"f": 5
},
"e": 3
})
);
}

type FileVec = Vec<(PathBuf, Cow<'static, str>)>;

impl NewCommand {
Expand Down Expand Up @@ -151,7 +189,6 @@ impl NewCommand {
files.extend(self.make_tsconfig()?);
files.extend(self.make_biome_config()?);
files.extend(self.make_typedoc_config()?);
files.extend(Self::make_prettier_config());
files.extend(Self::make_gitignore());

for (rel_path, contents) in files {
Expand Down Expand Up @@ -300,8 +337,7 @@ impl NewCommand {
Ok(vec![("biome.json".into(), config_str.into())])
}

#[allow(clippy::too_many_lines)]
fn make_vite_config(&self, entry_point: &str) -> FileVec {
fn make_vite_config(&self, entry_point: Option<&str>) -> FileVec {
let NewArgs {
platform, target, ..
} = self.args;
Expand All @@ -323,6 +359,9 @@ impl NewCommand {
if self.args.react {
imports.push(("react", "@vitejs/plugin-react"));
}
if self.args.vike {
imports.push(("vike", "vike/plugin"));
}
imports.push(("{ defineConfig }", "vite"));

if platform.is_node() {
Expand All @@ -332,26 +371,32 @@ impl NewCommand {
let mut config: Vec<(&str, Cow<'static, str>)> = Vec::new();

match target {
Target::Site => config.push(("base", "\"./\"".into())),
Target::Site => {
if !self.args.vike {
config.push(("base", "\"./\"".into()));
}
}
Target::Script => {
imports.push(("{ resolve }", "path"));
let build_config = match platform {
Platform::Browser => {
let name = self.args.name.as_global_var();
format!(
r#"lib: {{
entry: resolve(__dirname, "src/{entry_point}"),
entry: resolve(__dirname, "src/{}"),
name: "{name}",
formats: ["iife"],
}},"#
}},"#,
entry_point.unwrap()
)
}
Platform::Node => format!(
r#"lib: {{
entry: resolve(__dirname, "src/{entry_point}"),
entry: resolve(__dirname, "src/{}"),
formats: ["cjs"],
}},
minify: false,"#
minify: false,"#,
entry_point.unwrap()
),
};

Expand Down Expand Up @@ -384,8 +429,15 @@ minify: false,"#
.into(),
));

let mut plugins = Vec::new();
if self.args.react {
config.push(("plugins", "[react()]".into()));
plugins.push("react()");
}
if self.args.vike {
plugins.push("vike({ prerender: true })");
}
if !plugins.is_empty() {
config.push(("plugins", format!("[{}]", plugins.join(", ")).into()));
}

// TODO: Revisit deps.inline once this issue is closed:
Expand Down Expand Up @@ -491,10 +543,6 @@ export default defineConfig(({{ mode }}) => ({{
vec![(".gitignore".into(), gitignore.into())]
}

fn make_prettier_config() -> FileVec {
vec![(".prettierrc.cjs".into(), PRETTIER_CONFIG.into())]
}

fn run_pnpm(&self, f: impl Fn(&mut Command)) -> Result<()> {
let mut cmd = Command::new(self.global_config.pnpm_path());
f(&mut cmd);
Expand Down Expand Up @@ -630,23 +678,30 @@ export default defineConfig(({{ mode }}) => ({{
]);
}

if self.args.vike {
ensure!(
target.is_site(),
"--vike can only be used with --target site"
);

dev_dependencies.push("vike");

if self.args.react {
dev_dependencies.push("vike-react");
}
}

if self.args.sass {
dev_dependencies.push("sass");
}

let (src_path, src_contents) = match target {
let entry_point = match target {
Target::Site => {
ensure!(
platform.is_browser(),
"Must have platform=browser when target=site"
);

let (js_path, js_contents) = if self.args.react {
("index.tsx", REACT_INDEX)
} else {
("index.ts", BASIC_INDEX)
};

dev_dependencies.push("normalize.css");

let css_path = if self.args.sass {
Expand All @@ -655,15 +710,72 @@ export default defineConfig(({{ mode }}) => ({{
"index.css"
};

files.push((
"index.html".into(),
Self::make_index_html(js_path, css_path).into(),
));
if self.args.vike {
ensure!(self.args.react, "Currently must use --react with --vike");
const CONFIG_SRC: &str = r#"import vikeReact from "vike-react/config";
import type { Config } from "vike/types";
import { Layout } from "./Layout";
utils::create_dir(root.join("styles"))?;
files.push((format!("styles/{css_path}").into(), CSS.into()));
export let config: Config = {
Layout,
extends: vikeReact,
lang: "en-US",
};
"#;
files.push(("src/+config.ts".into(), CONFIG_SRC.into()));

const LAYOUT_SRC: &str = r#"import React from "react";
export let Layout: React.FC<React.PropsWithChildren> = ({ children }) => (
<div id="root">{children}</div>
);
"#;
files.push(("src/Layout.tsx".into(), LAYOUT_SRC.into()));

(js_path, js_contents)
let head_src = format!(
r#"import React from "react";
import "./{css_path}";
export let Head = () => (
<>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</>
);
"#
);
files.push(("src/+Head.tsx".into(), head_src.into()));
files.push((format!("src/{css_path}").into(), CSS.into()));

const INDEX_SRC: &str = r#"import React from "react";
export default () => {
return <h1>Hello, world!</h1>;
};
"#;
files.push(("src/index/+Page.tsx".into(), INDEX_SRC.into()));

const TITLE_SRC: &str = r#"export let title = "Example Site";
"#;
files.push(("src/index/+title.tsx".into(), TITLE_SRC.into()));
} else {
let (js_path, js_contents) = if self.args.react {
("index.tsx", REACT_INDEX)
} else {
("index.ts", BASIC_INDEX)
};

files.push((
"index.html".into(),
Self::make_index_html(js_path, css_path).into(),
));

utils::create_dir(root.join("styles"))?;
files.push((format!("styles/{css_path}").into(), CSS.into()));
files.push((format!("src/{js_path}").into(), js_contents.into()));
}

None
}
Target::Script => {
if platform.is_node() {
Expand All @@ -677,7 +789,9 @@ export default defineConfig(({{ mode }}) => ({{
} else {
"main.ts"
};
(filename, MAIN)
files.push((format!("src/{filename}").into(), MAIN.into()));

Some(filename)
}
Target::Lib => {
manifest.main = Some(String::from("dist/lib.js"));
Expand All @@ -704,27 +818,24 @@ export default defineConfig(({{ mode }}) => ({{
}

let filename = if self.args.react { "lib.tsx" } else { "lib.ts" };
files.push((format!("src/{filename}").into(), LIB.into()));

(filename, LIB)
Some(filename)
}
};

manifest.other = Some(other);

files.extend([
(Path::new("src").join(src_path), src_contents.into()),
(
"package.json".into(),
serde_json::to_string_pretty(&manifest)?.into(),
),
]);
files.push((
"package.json".into(),
serde_json::to_string_pretty(&manifest)?.into(),
));
files.extend(self.make_tsconfig()?);
files.extend(self.make_biome_config()?);
files.extend(self.make_vite_config(src_path));
files.extend(self.make_vite_config(entry_point));

if self.ws_opt.is_none() {
files.extend(Self::make_gitignore());
files.extend(Self::make_prettier_config());
}

for (rel_path, contents) in files {
Expand Down
8 changes: 7 additions & 1 deletion crates/depot/tests/tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn basic_lib_browser() {

#[test]
fn basic_lib_browser_react() {
let p = custom_project_for("lib", "browser", "--react");
let p = custom_project_for("lib", "browser", "--react").persist();
p.depot("build --lint-fail");
assert!(p.exists("dist/lib.js"));
assert!(p.exists("dist/lib.d.ts"));
Expand Down Expand Up @@ -129,3 +129,9 @@ fn react_import() {
p.file("src/lib.tsx", r#"import ReactDOM from "react-dom/client";"#);
p.depot("build");
}

#[test]
fn vike() {
let p = custom_project_for("site", "browser", "--react --vike");
p.depot("build --lint-fail");
}

0 comments on commit ffb7ed9

Please sign in to comment.