diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1f1543fa..b04d7ff9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,6 @@ "ghcr.io/devcontainers/features/node:1": {} }, "onCreateCommand": "cargo install cargo-watch cargo-about", - "postCreateCommand": "cd frontend && npm install", "customizations": { "vscode": { // NOTE: Keep this in sync with `.vscode/extensions.json` diff --git a/Cargo.toml b/Cargo.toml index 95bdafc0..e3af7945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu.git" } wgpu-types = "0.17" wgpu = "0.19" once_cell = "1.13" # Remove when `core::cell::LazyCell` () is stabilized in Rust 1.80 and we bump our MSRV -wasm-bindgen = "=0.2.92" # wasm-bindgen upgrades may break various things so we pin the version +wasm-bindgen = "=0.2.92" # NOTICE: ensure this stays in sync with the `wasm-bindgen-cli` version in `website/content/volunteer/guide/getting-started/_index.md`. We pin this version because wasm-bindgen upgrades may break various things. wasm-bindgen-futures = "0.4" js-sys = "=0.3.69" web-sys = "=0.3.69" diff --git a/frontend/package-installer.js b/frontend/package-installer.js new file mode 100644 index 00000000..79810310 --- /dev/null +++ b/frontend/package-installer.js @@ -0,0 +1,34 @@ +// This script automatically installs the npm packages listed in package-lock.json and runs before `npm start`. +// It skips the installation if this has already run and neither package.json nor package-lock.json has been modified since. + +import { execSync } from "child_process"; +import { existsSync, statSync, writeFileSync } from "fs"; + +const INSTALL_TIMESTAMP_FILE = "node_modules/.install-timestamp"; + +// Checks if the install is needed by comparing modification times +const isInstallNeeded = () => { + if (!existsSync(INSTALL_TIMESTAMP_FILE)) return true; + + const timestamp = statSync(INSTALL_TIMESTAMP_FILE).mtime; + return ["package.json", "package-lock.json"].some((file) => { + return existsSync(file) && statSync(file).mtime > timestamp; + }); +}; + +// Run `npm ci` if needed and update the install timestamp +if (isInstallNeeded()) { + try { + // Check if packages are up to date, doing so quickly by using `npm ci`, preferring local cached packages, and skipping the package audit and other checks + execSync("npm ci --prefer-offline --no-audit --no-fund", { stdio: "inherit" }); + // Touch the install timestamp file + writeFileSync(INSTALL_TIMESTAMP_FILE, ""); + } catch (error) { + // eslint-disable-next-line no-console + console.error("Failed to install npm packages. Please run `npm install` from the `/frontend` directory."); + process.exit(1); + } +} else { + // eslint-disable-next-line no-console + console.log("All npm packages are up-to-date."); +} diff --git a/frontend/package.json b/frontend/package.json index 1369f6c9..db934b6b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "browserslist": "> 1.5%, last 2 versions, not dead, not ie 11, not op_mini all, not ios_saf < 13", "type": "module", "scripts": { + "prestart": "node package-installer.js", "start": "npm run build-wasm && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run watch:wasm\" || (npm run print-building-help && exit 1)", "profiling": "npm run build-wasm-profiling && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run watch:wasm-profiling\" || (npm run print-building-help && exit 1)", "production": "npm run build-wasm-prod && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run watch:wasm\" || (npm run print-building-help && exit 1)", @@ -56,9 +57,6 @@ "vite": "^5.1.5", "vite-multiple-assets": "1.2.10" }, - "optionalDependencies": { - "wasm-pack": "0.12.1" - }, "homepage": "https://graphite.rs", "license": "Apache-2.0", "repository": { diff --git a/package.json b/package.json index 6b3ee365..87fde9fe 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "description": "A convenience package for calling the real package.json in ./frontend", "private": true, "scripts": { - "start": "cd frontend && npm start", - "serve": "cd frontend && npm start" + "start": "cd frontend && npm start" } } diff --git a/website/content/features.md b/website/content/features.md index 5aebe07c..e743f9b1 100644 --- a/website/content/features.md +++ b/website/content/features.md @@ -129,14 +129,14 @@ Always on the bleeding edge and built to last— Graphite is written on a robust Procedurally alterable vector data -
- - Imaginate (Stable Diffusion node/tool) -
New vector 2D renderer (with Vello)
+
+ + Imaginate (Stable Diffusion node/tool) +
GPU-accelerated raster rendering @@ -153,6 +153,10 @@ Always on the bleeding edge and built to last— Graphite is written on a robust Adaptive resolution system
+
+ + Graph data attribute spreadsheets +
Timeline with animation channels @@ -173,10 +177,6 @@ Always on the bleeding edge and built to last— Graphite is written on a robust Select mode (marquee masking)
-
- - Graph data attribute spreadsheet -
Stable document format @@ -267,7 +267,7 @@ Always on the bleeding edge and built to last— Graphite is written on a robust
- Node manager and marketplace + Asset libraries and marketplace
diff --git a/website/content/volunteer/guide/_index.md b/website/content/volunteer/guide/_index.md index ebb9a43e..cfaeaef2 100644 --- a/website/content/volunteer/guide/_index.md +++ b/website/content/volunteer/guide/_index.md @@ -8,4 +8,8 @@ aliases = ["/contribute"] book = true +++ -We're glad that you are interested in contributing to Graphite! We want to make it as easy and frictionless as possible for you to get started. Here are the basics. +Welcome, potential contributor! We're excited to have you join the Graphite project and it's our goal to make the process as smooth as possible. This guide will serve as your library of knowledge to help you get started contributing to the project. If you find any information missing or unclear, please let us know [through Discord](https://discord.graphite.rs) or submit a pull request to help document the process for future contributors. + +

+Flavor graphic depicting a library of knowledge in a digital realm +

diff --git a/website/content/volunteer/guide/getting-started/_index.md b/website/content/volunteer/guide/getting-started/_index.md index 921e7c76..7e8485f5 100644 --- a/website/content/volunteer/guide/getting-started/_index.md +++ b/website/content/volunteer/guide/getting-started/_index.md @@ -7,57 +7,70 @@ page_template = "book.html" order = 1 # Chapter number +++ -Graphite is built with Rust and web technologies. Install the latest LTS version of [Node.js](https://nodejs.org/) and stable release of [Rust](https://www.rust-lang.org/), as well as [Git](https://git-scm.com/). +To begin working with the Graphite codebase, you will need to set up the project to build and run on your local machine. Development usually involves running the dev server which watches for changes to frontend (web) and backend (Rust) code and automatically recompiles and reloads the Graphite editor in your browser. -## Installing +## Dependencies -Clone the project: +Graphite is built with Rust and web technologies, which means you will need to install: +- [Node.js](https://nodejs.org/) (the latest LTS version) +- [Rust](https://www.rust-lang.org/) (the latest stable release) +- [Git](https://git-scm.com/) (any recent version) -```sh -git clone https://github.com/GraphiteEditor/Graphite.git -``` - -On Debian-based (Ubuntu, Mint, etc.) Linux distributions, you may need to install the following packages: - -```sh -sudo apt install libgtk-3-dev libsoup2.4-dev libjavascriptcoregtk-4.0-dev libwebkit2gtk-4.0-dev -``` - -On Fedora-based (RHEL, CentOS, etc.) Linux distributions, you may need to install the following packages: - -```sh -sudo dnf install libsoup-devel gtk3-devel javascriptcoregtk4.0-devel webkit2gtk4.0-devel -``` - -Then install the required Node.js packages: - -```sh -cd frontend -npm install -``` - -You only need to explicitly install Node.js dependencies. Rust's cargo dependencies will be installed automatically on your first build. One dependency in the build chain, `wasm-pack`, will be installed automatically on your system when the Node.js packages are installing. (If you prefer to install this manually, get it from the [wasm-pack website](https://rustwasm.github.io/wasm-pack/), then install your npm dependencies with `npm install --omit=optional` instead.) - -One tool in the Rust ecosystem does need to be installed: +Next, install the dependencies required for development builds: ```sh cargo install cargo-watch +cargo install wasm-pack ``` -That's it! Now, to run the project while developing, just execute: +You'll likely get faster build times if you manually install this specific version of `wasm-bindgen-cli`. It is supposed to be installed automatically but a version mismatch causes it to reinstall every single recompilation. It may need to be manually updated periodically to match the version of the `wasm-bindgen` dependency in [`Cargo.toml`](https://github.com/GraphiteEditor/Graphite/blob/master/Cargo.toml): + +```sh +cargo install -f wasm-bindgen-cli@0.2.92 +``` + +On Linux, you may need to install this set of additional packages if you run into issues: + +```sh +# On Debian-based (Ubuntu, Mint, etc.) distributions: +sudo apt install libgtk-3-dev libsoup2.4-dev libjavascriptcoregtk-4.0-dev libwebkit2gtk-4.0-dev + +# On Fedora-based (RHEL, CentOS, etc.) distributions: +sudo dnf install gtk3-devel libsoup-devel javascriptcoregtk4.0-devel webkit2gtk4.0-devel +``` + +## Repository + +Clone the project to a convenient location: + +```sh +git clone https://github.com/GraphiteEditor/Graphite.git +cd Graphite +``` + +## Development builds + +From either the `/` (root) or `/frontend` directories, you can run the project by executing: ```sh npm start ``` -This spins up the dev server at with a file watcher that performs hot reloading of the web page. You should be able to start the server, edit and save web and Rust code, and rarely have to kill the server (by hitting CtrlC twice). You sometimes may need to reload the browser's web page if the hot reloading didn't behave perfectly. This method compiles Graphite code in debug mode which includes debug symbols for viewing function names in stack traces. But be aware, it runs slower and takes more memory. +This spins up the dev server at with a file watcher that performs hot reloading of the web page. You should be able to start the server, edit and save web and Rust code, and shut it down by double pressing CtrlC. You sometimes may need to reload the browser's page if hot reloading didn't behave right. + +This method compiles Graphite code in debug mode which includes debug symbols for viewing function names in stack traces. But be aware, it runs slower and the Wasm binary is much larger. Having your browser's developer tools open will also significantly impact performance in both debug and release builds, so it's best to close that when not in use. ## Production builds -You'll rarely ever need to do this, but to compile a production build with full optimizations: +You'll rarely need to compile your own production builds because our CI/CD system takes care of deployments. However, you can compile a production build with full optimizations by first installing the additional `cargo-about` dev dependency: ```sh cargo install cargo-about +``` + +And then running: + +```sh npm run build ``` diff --git a/website/sass/base.scss b/website/sass/base.scss index 53ded6b0..3cda21d0 100644 --- a/website/sass/base.scss +++ b/website/sass/base.scss @@ -507,12 +507,16 @@ ol { } code { - background: var(--color-fog); color: var(--color-black); + background: var(--color-fog); padding: 0 4px; overflow-wrap: anywhere; -webkit-hyphens: none; hyphens: none; + + a & { + color: var(--color-crimson); + } } pre {