concrete-utopia / utopia
- суббота, 19 июня 2021 г. в 00:35:47
Design ❤️ Code
Utopia is an integrated design and development environment for React. It uses React code as the source of truth, and lets you make real time changes to components by editing it and using a suite of design tools. It's early software, but you can try it today, look at an example project, or read about it on our blog!
Utopia is browser-based. To run it locally, clone the repo, and then set up the server and webpack by following these instructions.
brew install gmp
first. On new M1 Macbooks please follow these steps to install brew and run the server the first time.direnv
installed, you'll need to run nix-shell
before any of the start
commands, and switching to nix will be a bit slower.We welcome contributions. Utopia is a big project, but we're here to help, and are happy to pair up with you. The easiest way is to file an issue, or reach out on Discord. Please read our contributing doc to get started
There are a few different options for running Utopia below, but for all of them you'll head to localhost:8000. Importantly, /project gets you to the editor.
start
and in a second terminal, for typescript compile errors
watch-tsc
Run everything in fast mode, performance is fast, react will throw minified errors:
start-performance
and in a second terminal, for typescript compile errors
watch-tsc
it's the same as start but webpack is in hot mode (under the hood it runs npm run move-fast-and-break-things-hot instead of npm run move-fast-and-break-things). I've been using this for the last 4-5 days or so. hot mode still works if you are working on for example the inspector design. the canvas is pretty brittle to hot updates, every 4th update made my canvas turn white but for the purposes of the inspector tweaking it was fine
start-hot-only-ui-work
(each series of commands assumes that you're starting from the root directory of the project)
Shell 1:
nix-shell
redis-server
Shell 2:
nix-shell
watch-server
If this ever fails with truncated tar archive
, it's a cabal failure. The fix appears to be to delete ~/.cabal/packages
Shell 3:
nix-shell
watch-tsc
Shell 4:
nix-shell
watch-editor-cowboy
Shell 5:
nix-shell
watch-tsc
Shell 6:
nix-shell
watch-editor-performance
Alternatively you can run npm run webpack-production
. Occasionally you'll need to run npm install
from the /editor
directory before webpack.
Shell 7:
nix-shell
watch-website
build-vscode-with-extension
watch-vscode-dev
When a series of environment variables are set (see Branches.hs
), the editor supports the ability to get a bundle of editor code from S3 that was created from a PR, and load that instead of the code currently held locally. Which means that changes can be tested without spinning up multiple environments.
To use this if the URL currently is https://utopia.pizza/p/e976df60-phase-rutabaga/
, the branch name would be added on in a query parameter like so: https://utopia.pizza/p/e976df60-phase-rutabaga/?branch_name=my-test-branch
.
Limitations:
There are some extra steps to build server files, steps 11-14 are also needed when there are dependency changes for the server.
arch
first to make sure your terminal is good, this should show i386
in the Rosetta Terminalarch -x86_64
before pasting the install scriptarch -x86_64 /usr/local/bin/brew install gmp
direnv
and run the start-website-server
to build the server files hereStartup Processes Completed
exit terminal with cmd+qstart
script in the utopia folder.If you notice that 1 or more CPU cores are running 100% because of node
processes, it is probably webpack-dev-server having trouble with fsevents
on MacOS. To fix it, run npm install fsevents
in the utopia/editor
directory. see https://github.com/webpack/webpack/issues/701#issuecomment-216082726
You'll need four things running concurrently:
editor/npm run webpack
editor/npx tsc --watch
Website/npm start
server/cabal new-run --disable-optimization --disable-profiling --disable-documentation --disable-library-coverage --disable-benchmarks utopia-web -- +RTS -N
Since a lot of this requires using nix-shell
everywhere, you can just use direnv to make that a lot simpler. Not only will this automatically use a nix shell whenever you cd
into the project folder, but it also adds caching to vastly speed up the opening of that shell. You can install direnv by using brew:
brew install direnv
To actually run direnv you need to hook it into your shell by following the instructions here.
Then to configure it, in your $HOME directory add a file .direnvrc
with the following contents (copied from https://github.com/direnv/direnv/wiki/Nix#using-a-global-use_nix-with-garbage-collection-prevention):
use_nix() {
local path="$(nix-instantiate --find-file nixpkgs)"
if [ -f "${path}/.version-suffix" ]; then
local version="$(< $path/.version-suffix)"
elif [ -f "${path}/.git" ]; then
local version="$(< $(< ${path}/.git/HEAD))"
fi
local cache=".direnv/cache-${version:-unknown}"
local update_drv=0
if [[ ! -e "$cache" ]] || \
[[ "$HOME/.direnvrc" -nt "$cache" ]] || \
[[ .envrc -nt "$cache" ]] || \
[[ default.nix -nt "$cache" ]] || \
[[ shell.nix -nt "$cache" ]];
then
[ -d .direnv ] || mkdir .direnv
nix-shell --show-trace --pure "$@" --run "\"$direnv\" dump bash" > "$cache"
update_drv=1
else
log_status using cached derivation
fi
local term_backup=$TERM path_backup=$PATH
if [ -n ${TMPDIR+x} ]; then
local tmp_backup=$TMPDIR
fi
eval "$(< $cache)"
export PATH=$PATH:$path_backup TERM=$term_backup TMPDIR=$tmp_backup
if [ -n ${tmp_backup+x} ]; then
export TMPDIR=${tmp_backup}
else
unset TMPDIR
fi
# `nix-shell --pure` sets invalid ssl certificate paths
if [ "${SSL_CERT_FILE:-}" = /no-cert-file.crt ]; then
unset SSL_CERT_FILE
fi
if [ "${NIX_SSL_CERT_FILE:-}" = /no-cert-file.crt ]; then
unset NIX_SSL_CERT_FILE
fi
# This part is based on https://discourse.nixos.org/t/what-is-the-best-dev-workflow-around-nix-shell/418/4
if [ "$out" ] && (( $update_drv )); then
local drv_link=".direnv/drv"
local drv="$(nix show-derivation $out | grep -E -o -m1 '/nix/store/.*.drv')"
local stripped_pwd=${PWD/\//}
local escaped_pwd=${stripped_pwd//-/--}
local escaped_pwd=${escaped_pwd//\//-}
ln -fs "$drv" "$drv_link"
ln -fs "$PWD/$drv_link" "/nix/var/nix/gcroots/per-user/$LOGNAME/$escaped_pwd"
log_status renewed cache and derivation link
fi
if [[ $# = 0 ]]; then
watch_file default.nix
watch_file shell.nix
fi
}
And add a .envrc
file to the root folder of the project with the following contents:
use nix
(This file is deliberately contained in the .gitignore
because it is supposed to be personal to you - it allows you to add custom environment variables that will always be in scope whenever you're in this directory)
Please update your .zshrc (or .bashrc) to hook it into the shell, for example for zsh add this line:
eval "$(direnv hook zsh)"
After this step open a new shell window and enter the utopia directory. Direnv should be activated as soon as you enter, you can use the start
and start-performance
scripts without manually running nix-shell.
One-off test run:
npm run test
Continuous mode:
npm run test-watch
On macOS, when trying to watch, you might run into an error message about number of open files. In that case, install watchman:
brew install watchman
To enable format-on-save, you should install the VSCode plugin esbenp.prettier-vscode
, and dbaeumer.vscode-eslint
and then in your workspace settings, enable format on save, and tell prettier to use the eslint integration mode:
"eslint.workingDirectories": ["./editor", "./utopia-api"],
"editor.formatOnSave": true,
"prettier.useEditorConfig": false,
"prettier.requireConfig": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
Select prettier as the default formatter in your settings; VSCode may prompt you to do so. The last four line items, starting with [typescript]
reflect this. You should restart VSCode after this.
All pushes to the master
branch will immediately trigger this workflow that runs the tests and then triggers a deploy to our Staging environment.
To deploy to the Production environment, somebody needs to manually trigger our tag-release.yml
workflow, giving either a specific commit hash or branch name (defaulting to master
), and optionally a tag name (the default behaviour is to increment the patch version). This can be triggered via the "Run Workflow" button here
Note: in the "Use workflow from" dropdown you have to select "Branch: master" - this is specifying which workflow to run, not which branch to cut the release from.