Skip to content

oneezy/monorepo

Repository files navigation

image

Turborepo + Sveltekit + Tailwind + Histoire (Demo)

oneezy

This is a monorepo starter powered by:

To Do

  • πŸ†• create "main" app for all other apps to live on the same level / better control of (group) layouts
  • πŸ†• fixed layouts / duplicate content
  • πŸ†• created $base links so stand-alone app links will work
  • πŸ†• bumped histoire to v0.11.7
  • πŸ†• better tailwind.config content paths
  • πŸ†• fix plop app to work w/ new layout structure
  • convert Histoire (svelte) to Histoire (sveltekit)
  • Turborepo
  • Sveltekit ^1.0.0-next.570
  • Tailwind ^3.1.8
  • PNPM
  • Husky
  • Commitlint
  • Symlink routes fixed! (sveltekit issue #6303)
  • Shared @packages/* between @apps/*
  • Remove all build folder w/ pnpm clean script
  • Open multiple apps on different ports w/ pnpm dev
  • Build multiple apps w/ pnpm build (turborepo build under hood)
  • Preview built apps w/ pnpm preview
  • Implement Changesets (link)
  • Setup Component Stories
    • Histoire
    • Vitebook (deprecated / no iframe)
    • Bookit (no iframe)
  • Commitlint Emojis
  • Setup Docker w/ Turborepo
  • Deploy dev, beta, and prod to real web host
  • CI Build Process
  • Create env variables shared in packages
  • Limit access to certain directories
  • Setup git submodules for opensource repos
  • Create @oneezy/componentsGitHub repo + NPM package for sharing components between projects
  • Automate Release Tags
  • Testing

Apps

websites and webapps live in the ./apps folder. They all live at the same level but the app routes are symlinked into the +app (main app) directory so they inherit Sveltekit's SPA routing system (Single Page Application).

  • +app (main app)
  • +stories (histoire stories)
  • site
  • docs

Packages

libraries, configs and components live in the ./packages folder.

  • components
    • where components and global css live
  • config
    • shared configs between all apps
  • dependencies
    • shared dependencies and devDependencies between alls apps
  • libs
    • useful libraries from npm and other 3rd party resources
  • metadata
    • base metadata shared between apps
  • utils
    • where utilities live

Setup

Prereqs

node v18.8.0  (or later)
pnpm v7       (or later)image.png

Installation

degit oneezy/monorepo my-app
pnpm i

+ start all apps
pnpm dev

+ start single app
pnpm dev --filter @apps/site

+ production build all apps
pnpm build

+ production preview all apps
pnpm preview

+ production preview single app
pnpm preview --filter @apps/dev

Add App

This monorepo makes use of symlinks to handle 2 separate scenarios. if you plan on using either you will need to follow the steps below for your app(s) to work properly. Learn more about symlinks by clicking here.

PROTIP: Quickly generate an app using plop !

pnpm plop app

symlink static assets
this monorepo only uses one folder for static assets located at ./apps/+app/static so you will need to symlink that static folder into every app you add to the apps/* folder to get static assets working (this may change in the future but this is how we're handling it at the moment).

This is automatically handled for you when you pnpm i anywhere.

symlink app routes
if you want to link entire apps together as routes you will need to symlink your ./apps/my-app/src/routes directory into the main ./apps/+app/src/routes directory.

This is automatically handled for you when you pnpm i anywhere.

Add Component

Components are the building blocks of your apps.

PROTIP: Quickly generate a component using plop !

pnpm plop component

or do it manually...

  1. create new component in ./packages/components/src directory

  2. export new component from ./packages/components/index.js file

  3. use component in an app ./apps/site/src/routes/index.svelte

<script>
  import { MyComponent } from '@packages/components';
</script>

<MyComponent />

Add Package

  1. create new folder in ./apps (i.e. docs)
  2. create new folder in ./packages (i.e. components)
  3. go to components folder and create package.json with proper namespace
{
  "name": "@packages/components",
  "version": "0.0.0",
  "type": "module",
  "main": "index.js"
}
  1. cd into the app you want to add the package to and use the pnpm add command
cd apps/docs
pnpm add @packages/components

pnpm adds the workspace at the bottom of your docs/package.json

"dependencies": {
  "@packages/components": "workspace:*"
}

Project Configuration

Modify the root package.json

Make sure to modify the contents in the project's root package json to fit your needs.

Package.json inheritance from @packages/dependencies

You can create base package.json's to inherit from each other.

i.e. packages/dependencies/package.shared.json

{
    "devDependencies": {
        "svrollbar": "^0.12.0",
        "svelte-accessible-accordion": "^2.1.0"
    },
    "dependencies": {
        "@packages/config": "workspace:*",
        "@packages/metadata": "workspace:*",
        "@packages/components": "workspace:*"
    }
}

And then add it to the app's package.json like...

  "name": "@apps/site",
  "inherits": [
    "@packages/dependencies/package.svelte.json",
    "@packages/dependencies/package.shared.json"
  ],

Running Multiple Dev Environments

If you want to run multiple dev enviornments in parallel, you will have to define different ports in each of your apps package.json npm scripts (i.e. -p 4000). Each apps port will need to be different.

"name": "@apps/docs",
"version": "0.0.0",
"scripts": {
  "dev": "vite dev --port 4000",
  "build": "vite build",
  "preview": "vite preview --port 4000"
},

Setting up Symlinks (if you're on Windows)

Prerequisites

Symlink Permissions

You have 1 of 3 options. If you try to create a symlink without one of these, you will see:

Failed to create symbolic link 'link' : Operation not permitted
🟦 Option 1: Run as Administrator

When you make a symlink this way, you'll always need to open up the terminal as an Administrator.

🟦 Option 2: Developer Mode

This is the easiest way but not the safest (security risk).

  1. Go to your start menu and search "Developer Settings".
  2. Turn Developer Mode On.
βœ… Option 3: Local Security Policy
  1. Go to your start menu and search "Local Security Policy".
  2. Double click on Create symbolic links
+ Security Settings > Local Policies > User Rights Assignment > Create symbolic links
  1. Click the Add User or Group button
  2. Type in your username and click the OK button
  3. Click the Apply button
  4. Restart your computer for the settings to take place

Choose a Path: Command Prompt, Git Bash or WSL

Command Prompt

  1. Open the Command Prompt
  2. Use cd to go into your project where you want to add the symlink
cd C:\Users\oneezy\Desktop\sveltekit-symlinks\src\routes
  1. Create a relative symlink (not absolute!) to a directory folder (not a file!)
mklink /D my-new-symlink ..\..\symlinked-docs
  1. And your finished!

Git Bash

Step 1. Setting System Environment Variables

🟦 Option 1: Exporting variable per session (tedious)

In your terminal you'll need to write the following command every time you restart git bash.

export MSYS=winsymlinks:nativestrict
βœ… Option 2: Create an entry for MSYS (once)
  1. Go to your start menu and search for "System Settings"
  2. Click the Environment Variables... button
  3. Go to System variables section and click the New button
  4. Enter in the New System Variable name and value and click the OK button.
Variable name:    MSYS
Variable value:   winsymlinks:nativestrict
  1. Click the OK button again to confirm.
  2. Congratulations! Now you have the power to create symlinks whenever you want!

Step 2. Enable Symlinks in Gitconfig

You may also need to enable symlinks in your .gitconfig user profile.

git config --global core.symlinks true

This will add the symlinks = true to C:\Users\username\.gitconfig

[core]
  symlinks = true

You may also need to manually add symlinks = true to the gitconfig inside C:\Program Files\Git\etc\gitconfig if it's not there already

[core]
  symlinks = true

Step 3. Create Symlink (Git Bash)

  1. Open up Git Bash
  2. Use cd to go into your project where you want to add the symlink
cd c/users/oneezy/desktop/sveltekit-symlinks/src/routes
  1. Create a relative symlink (not absolute!) to a directory folder (not a file!)
ln -s ../../../docs docs
  1. And your finished!

PROTIP: To see a list of your symlinks use the ls -l command

oneezy@oneezy MINGW64 ~/Desktop/sveltekit-symlinks/src/routes (main)
$ ls -l

rw-r--r-- 1 oneezy 197609 1354 Jun  1 13:00 index.svelte
+lrwxrwxrwx 1 oneezy 197609   20 Jun  1 20:45 docs -> ../../docs/

Deploying

This uses Sveltkits adapter-auto and is being deployed to Vercel but you may need to change it depending on how you want to deploy.

BUILD COMMAND

pnpm build --filter @apps/app

ROOD DIRECTORY

apps/+app

image

References

Monorepo

Docs Starters

Blog Starters

Tailwind UI

Svelte Themes

Full-Stack Sveltekit

Thanks Everyone for your contributions!