├── .npmrc ├── src ├── sveltekit-vault │ ├── .obsidian │ │ ├── appearance.json │ │ ├── templates.json │ │ ├── app.json │ │ ├── hotkeys.json │ │ ├── core-plugins.json │ │ ├── graph.json │ │ └── workspace │ ├── templates │ │ ├── post.md │ │ └── book.md │ ├── _assets │ │ ├── atomic-habits.jpeg │ │ ├── refactoring-ui.jpg │ │ ├── dont-make-me-think.jpeg │ │ └── philosophy-of-software-design.jpeg │ ├── posts │ │ ├── postable-thought.md │ │ ├── formerly-privateish-thought.md │ │ └── large-hadron-collider.md │ └── books │ │ ├── atomic-habits.md │ │ ├── refactoring-ui.md │ │ ├── dont-make-me-think.md │ │ └── philosophy-of-software-design.md ├── routes │ ├── __layout.svelte │ ├── posts │ │ ├── index.ts │ │ ├── [slug].svelte │ │ └── index.svelte │ ├── books │ │ ├── index.ts │ │ ├── index.svelte │ │ └── [slug].svelte │ ├── index.ts │ └── index.svelte ├── app.html ├── lib │ ├── utils.ts │ └── components │ │ └── Header.svelte └── app.d.ts ├── static └── favicon.png ├── .gitignore ├── .prettierrc ├── README.md ├── tsconfig.json ├── .eslintrc.cjs ├── package.json └── svelte.config.js /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/appearance.json: -------------------------------------------------------------------------------- 1 | { 2 | "cssTheme": "Things" 3 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/templates.json: -------------------------------------------------------------------------------- 1 | { 2 | "folder": "templates" 3 | } -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franknoirot/obsidian-sveltekit-blog/HEAD/static/favicon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100 6 | } 7 | -------------------------------------------------------------------------------- /src/sveltekit-vault/templates/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{title}} 3 | published: {{date}}T{{time}} 4 | tags: 5 | - design 6 | --- -------------------------------------------------------------------------------- /src/sveltekit-vault/_assets/atomic-habits.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franknoirot/obsidian-sveltekit-blog/HEAD/src/sveltekit-vault/_assets/atomic-habits.jpeg -------------------------------------------------------------------------------- /src/sveltekit-vault/_assets/refactoring-ui.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franknoirot/obsidian-sveltekit-blog/HEAD/src/sveltekit-vault/_assets/refactoring-ui.jpg -------------------------------------------------------------------------------- /src/sveltekit-vault/_assets/dont-make-me-think.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franknoirot/obsidian-sveltekit-blog/HEAD/src/sveltekit-vault/_assets/dont-make-me-think.jpeg -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "legacyEditor": false, 3 | "livePreview": true, 4 | "attachmentFolderPath": "_assets", 5 | "alwaysUpdateLinks": true 6 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/_assets/philosophy-of-software-design.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franknoirot/obsidian-sveltekit-blog/HEAD/src/sveltekit-vault/_assets/philosophy-of-software-design.jpeg -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/hotkeys.json: -------------------------------------------------------------------------------- 1 | { 2 | "insert-template": [ 3 | { 4 | "modifiers": [ 5 | "Mod", 6 | "Shift" 7 | ], 8 | "key": "O" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/posts/postable-thought.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A postable thought 3 | published: 2022-04-29T14:30 4 | tags: 5 | - design 6 | --- 7 | Something genuinely brilliant to say to the wold. Finally, a great clear thought: 8 | 9 | *haberdasher.* 10 | 11 | Thank you. -------------------------------------------------------------------------------- /src/routes/__layout.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 |
7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /src/sveltekit-vault/templates/book.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{title}} 3 | author: Tal Briarwood 4 | originallyPublished: 2022 5 | publishDate: 2022 6 | format: digital | physical 7 | coverImg: example-image.jpeg 8 | --- 9 | 10 | ## citation 11 | 12 | 13 | ## big ideas 14 | 15 | 16 | ## review 17 | 18 | 19 | ## rough notes 20 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %svelte.head% 8 | 9 | 10 |
%svelte.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a string from camelCase to Title Case 3 | * @param camelCaseText 4 | * @returns {string} titleCaseText 5 | */ 6 | export function camelCaseToTitleCase(camelCaseText: string): string { 7 | const withSpaces = camelCaseText.replace(/([A-Z])/g, " $1"); 8 | return withSpaces.charAt(0).toUpperCase() + withSpaces.slice(1); 9 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/core-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "file-explorer", 3 | "global-search", 4 | "switcher", 5 | "graph", 6 | "backlink", 7 | "page-preview", 8 | "templates", 9 | "note-composer", 10 | "command-palette", 11 | "editor-status", 12 | "markdown-importer", 13 | "word-count", 14 | "open-with-default-app", 15 | "file-recovery" 16 | ] -------------------------------------------------------------------------------- /src/sveltekit-vault/posts/formerly-privateish-thought.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A formerly private(ish) thought 3 | published: 2022-06-10T00:40 4 | tags: 5 | - design 6 | --- 7 | Just a basic thought, not for sharing with the world on a website. But not a big deal if GitHub snoops through it, since I don't pay for it. 8 | 9 | Somehow, this is connected to [[atomic-habits|Atomic Habits]] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian + SvelteKit Demo Vault and Site 2 | 3 | This is a demo of using an [Obsidian](https://obsidian.md) vault as the source for a personal blog and book review website built with [SvelteKit](https://kit.svelte.dev). 4 | 5 | # create-svelte 6 | 7 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "lib": ["es2020", "DOM"], 9 | "moduleResolution": "node", 10 | "module": "es2020", 11 | "resolveJsonModule": true, 12 | "skipLibCheck": true, 13 | "sourceMap": true, 14 | "strict": true, 15 | "target": "es2020" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://kit.svelte.dev/docs/types#app 4 | // for information about these interfaces 5 | declare namespace App { 6 | // interface Locals {} 7 | // interface Platform {} 8 | // interface Session {} 9 | // interface Stuff {} 10 | } 11 | 12 | interface IBookLink { 13 | title: string, 14 | slug: string, 15 | coverImg: string, 16 | } 17 | 18 | interface IPostLink { 19 | title: string, 20 | slug: string, 21 | } -------------------------------------------------------------------------------- /src/routes/posts/index.ts: -------------------------------------------------------------------------------- 1 | export async function get() { 2 | const allPosts = import.meta.globEager(`../../sveltekit-vault/posts/*.md`); 3 | const posts : IPostLink[] = [] 4 | 5 | for (const path in allPosts) { 6 | const pathArr = path.split('/') 7 | 8 | posts.push({ 9 | slug: pathArr[pathArr.length - 1].slice(0, -3), 10 | title: allPosts[path].metadata.title, 11 | }) 12 | } 13 | 14 | 15 | return { 16 | body: { 17 | posts, 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], 5 | plugins: ['svelte3', '@typescript-eslint'], 6 | ignorePatterns: ['*.cjs'], 7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 8 | settings: { 9 | 'svelte3/typescript': () => require('typescript') 10 | }, 11 | parserOptions: { 12 | sourceType: 'module', 13 | ecmaVersion: 2020 14 | }, 15 | env: { 16 | browser: true, 17 | es2017: true, 18 | node: true 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/routes/books/index.ts: -------------------------------------------------------------------------------- 1 | export async function get() { 2 | const allBooks = import.meta.globEager(`/src/sveltekit-vault/books/*.md`) 3 | const books : IBookLink[] = [] 4 | 5 | for (const path in allBooks) { 6 | const pathArr = path.split('/') 7 | 8 | books.push({ 9 | slug: pathArr[pathArr.length - 1].slice(0, -3), 10 | title: allBooks[path].metadata.title, 11 | coverImg: allBooks[path].metadata.coverImg, 12 | }) 13 | } 14 | 15 | 16 | return { 17 | body: { 18 | books, 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/posts/large-hadron-collider.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A new, amazing use for the Large Hadron Collider 3 | published: 2022-04-40T14:30 4 | tags: 5 | - opinions 6 | --- 7 | You simply **aren't going to believe this.** I've finally cracked it. This is related to [[postable-thought|my previous written work]], but if that link isn't working on the website then I still have a preprocessing step to write. I also don't know how I'm supposed to inform the frontend that this link to [[philosophy-of-software-design|Philosophy of Software Design]] should resolve to a link leading to within the `/books` directory. -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/graph.json: -------------------------------------------------------------------------------- 1 | { 2 | "collapse-filter": true, 3 | "search": "", 4 | "showTags": false, 5 | "showAttachments": false, 6 | "hideUnresolved": false, 7 | "showOrphans": true, 8 | "collapse-color-groups": true, 9 | "colorGroups": [], 10 | "collapse-display": true, 11 | "showArrow": false, 12 | "textFadeMultiplier": 0, 13 | "nodeSizeMultiplier": 1, 14 | "lineSizeMultiplier": 1, 15 | "collapse-forces": true, 16 | "centerStrength": 0.518713248970312, 17 | "repelStrength": 10, 18 | "linkStrength": 1, 19 | "linkDistance": 250, 20 | "scale": 1, 21 | "close": false 22 | } -------------------------------------------------------------------------------- /src/routes/posts/[slug].svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 23 | 24 |
{ JSON.stringify(metadata, null, 2) }
25 | -------------------------------------------------------------------------------- /src/routes/posts/index.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |

Blog Posts

6 | {#each posts as post, i (post.slug)} 7 | { post.title } 8 | {/each} 9 | 10 | -------------------------------------------------------------------------------- /src/sveltekit-vault/books/atomic-habits.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Atomic Habits 3 | author: James Clear 4 | originallyPublished: 2018 5 | publishDate: 2018 6 | format: digital 7 | coverImg: atomic-habits.jpeg 8 | --- 9 | A pop psychology by James Clear about how to build effective habits through a number of strategies. 10 | 11 | ## citation 12 | Clear, James. _Atomic Habits: Tiny Changes, Remarkable Results : an Easy & Proven Way to Build Good Habits & Break Bad Ones_. , 2018. Print. 13 | 14 | ## big ideas 15 | 1. small changes in behavior can lead to a big change in outcome 16 | 2. habits are primarily expressions of identity, not willpower 17 | 18 | ## quotes and notes 19 | > Anything wise in these pages you should credit to the many experts who preceded me. Anything foolish, assume it is my error. 20 | - This is a nicely worded gesture of humility as an author. -------------------------------------------------------------------------------- /src/routes/index.ts: -------------------------------------------------------------------------------- 1 | export async function get() { 2 | const allBooks = import.meta.globEager(`../sveltekit-vault/books/*.md`); 3 | const allPosts = import.meta.globEager(`../sveltekit-vault/posts/*.md`); 4 | 5 | const books = preparePaths(allBooks) 6 | const posts = preparePaths(allPosts) 7 | 8 | return { 9 | body: { 10 | books, 11 | posts, 12 | } 13 | } 14 | } 15 | 16 | function preparePaths(collectionRecord: Record) { 17 | const collectionArray = [] 18 | for (const path in collectionRecord) { 19 | const pathArr = path.split('/') 20 | 21 | collectionArray.push({ 22 | slug: pathArr[pathArr.length - 1].slice(0, -3), 23 | title: collectionRecord[path].metadata.title, 24 | }) 25 | } 26 | 27 | return collectionArray 28 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/books/refactoring-ui.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Refactoring UI 3 | author: Wathan, Adam, and Steve Schoger 4 | originallyPublished: 2019 5 | publishDate: 2019 6 | format: digital 7 | coverImg: refactoring-ui.jpg 8 | --- 9 | A recent UX book by the creators of TailwindCSS. 10 | 11 | ## citation 12 | Wathan, Adam, and Steve Schoger. _Refactoring UI_. 1.0.2 ed., Adam Wathan & Steve Schoger, 2019. 13 | 14 | ## big ideas 15 | 1. Make a scale for yourself and stick to it. 16 | 2. Use HSL for color 17 | 18 | ## review 19 | I have a hunch that Tailwind is reaching its peak hype in the next year or two and will begin to be criticized afterward, but the work these two in really making UI design blunt and fast and effective can't really be understated right now. Though less jocular by a wide margin, I think it shares a lot in tone with [[dont-make-me-think|Don't Make Me Think]], in cutting past the grandeur to fixing UX problems. 20 | -------------------------------------------------------------------------------- /src/lib/components/Header.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 12 |
13 | 14 | -------------------------------------------------------------------------------- /src/routes/books/index.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |

Books

6 | {#each books as book, i (book.slug)} 7 | 8 | {book.title} 9 | { book.title } 10 | 11 | {/each} 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-sveltekit-blog", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview", 9 | "prepare": "svelte-kit sync", 10 | "check": "svelte-check --tsconfig ./tsconfig.json", 11 | "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", 12 | "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", 13 | "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." 14 | }, 15 | "devDependencies": { 16 | "@sveltejs/adapter-auto": "next", 17 | "@sveltejs/kit": "next", 18 | "@typescript-eslint/eslint-plugin": "^5.10.1", 19 | "@typescript-eslint/parser": "^5.10.1", 20 | "eslint": "^7.32.0", 21 | "eslint-config-prettier": "^8.3.0", 22 | "eslint-plugin-svelte3": "^3.2.1", 23 | "fdir": "^5.2.0", 24 | "mdsvex": "^0.10.5", 25 | "prettier": "^2.5.1", 26 | "prettier-plugin-svelte": "^2.5.0", 27 | "svelte": "^3.44.0", 28 | "svelte-check": "^2.2.6", 29 | "svelte-preprocess": "^4.10.1", 30 | "tslib": "^2.3.1", 31 | "typescript": "~4.6.2", 32 | "vite-plugin-static-copy": "^0.5.0" 33 | }, 34 | "type": "module" 35 | } 36 | -------------------------------------------------------------------------------- /src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |

A Demo Site for Obsidian + SvelteKit

6 |

This demo site uses Obsidian as the source for a SvelteKit site, resulting in a notetaking experience that blends fairly seamlessly into a publishing one!

7 |
8 |

Books

9 | {#each books as book, i (book.slug)} 10 | { book.title } 11 | {/each} 12 |
13 |
14 |

Posts

15 | {#each posts as post, i (post.slug)} 16 | { post.title } 17 | {/each} 18 |
19 | 20 | -------------------------------------------------------------------------------- /src/sveltekit-vault/books/dont-make-me-think.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Don't Make Me Think! 3 | author: Steve Krug 4 | originallyPublished: 2006 5 | publishDate: 2015 6 | format: digital 7 | coverImg: dont-make-me-think.jpeg 8 | --- 9 | 10 | ## citation 11 | Krug, Steve. _Don't Make Me Think!: A Common Sense Approach to Web Usability_. Berkeley, Calif: New Riders Pub, 2006. Print. 12 | 13 | ## big ideas 14 | 1. nobody reads your website, *at best* they skim it 15 | 2. we are inherently lost on the web, because there is no spatial reasoning. Most of you job is signage design. 16 | 17 | ## review 18 | A lot of gems of ideas in this one. Above all, I think it takes a grinder to the ego of software creatives, and reminds us that at the end of the day, people would love the chance to skip through your perfectly-tuned brand copy to get on with their busy lives. 19 | 20 | ## rough notes 21 | >What they actually do most of the time (if we’re lucky) is glance at each new page, scan some of the text, and click on the first link that catches their interest or vaguely resembles the thing they’re looking for. There are almost always large parts of the page that they don’t even look at. 22 | 23 | >One of the very few well-documented facts about Web use is that people tend to spend very little time reading most Web pages. Instead, we scan (or skim) them, looking for words or phrases that catch our eye. 24 | - I read them, which makes an interesting general point about chosen professions. In general, you care 10x more about the thing you make for a living than others. -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | import preprocess from 'svelte-preprocess'; 3 | import { mdsvex } from "mdsvex"; 4 | import { fdir } from 'fdir'; 5 | import { defineConfig } from 'vite'; 6 | import { viteStaticCopy } from 'vite-plugin-static-copy' 7 | 8 | /** @type {import('@sveltejs/kit').Config} */ 9 | const config = { 10 | paths: { 11 | }, 12 | 13 | // Consult https://github.com/sveltejs/svelte-preprocess 14 | // for more information about preprocessors 15 | extensions: ['.svelte', ".svelte.md", ".md", ".svx"], 16 | 17 | preprocess: [ 18 | preprocess(), 19 | mdsvex({ 20 | "extensions": [".svelte.md", ".md", ".svx"], 21 | 22 | "smartypants": { 23 | "dashes": "oldschool" 24 | }, 25 | 26 | "remarkPlugins": [], 27 | "rehypePlugins": [] 28 | }), 29 | { 30 | markup: ({ content, filename }) => { 31 | if (![".svelte.md", ".md", ".svx"].some(extension => filename.includes(extension))) return { code: content } 32 | 33 | const obsidianLinkRegex = /\[\[(.+?(\|.+?)?)\]\]([\W])/g 34 | const transformedContent = content.replace(obsidianLinkRegex, (_, p1, p2, p3) => { 35 | const slug = p1.includes("|") ? p1.slice(0, p1.indexOf("|")) : p1 36 | const filePathArr = new fdir().glob(`./**/${slug}.md`).withRelativePaths().crawl('./src/sveltekit-vault').sync(); 37 | const href = `/` + (filePathArr.length === 1) ? filePathArr[0].slice(0, -3) : slug 38 | 39 | const linkText = (p2) ? p2.slice(1) : p1 40 | 41 | const linkHtml = `${ linkText }` + p3 42 | return linkHtml 43 | }) 44 | 45 | return { 46 | code: transformedContent, 47 | } 48 | } 49 | } 50 | ], 51 | 52 | kit: { 53 | adapter: adapter(), 54 | vite: defineConfig({ 55 | plugins: [ 56 | viteStaticCopy({ 57 | targets: [ 58 | { src: './src/sveltekit-vault/_assets/*', dest: './static/assets/' }, 59 | ] 60 | }) 61 | ], 62 | // assetsInclude: ['./src/sveltekit-vault/_assets/*'], 63 | }) 64 | } 65 | }; 66 | 67 | export default config; 68 | -------------------------------------------------------------------------------- /src/routes/books/[slug].svelte: -------------------------------------------------------------------------------- 1 | 23 | 24 | 32 | 33 |
34 |
35 |

{metadata.title}

36 |
37 | {#each Object.entries(filteredMeta) as [key, value], i (key)} 38 |

{camelCaseToTitleCase(key)} {value}

39 | {/each} 40 |
41 |
42 |
43 | {metadata.title} 44 |
45 |
46 |
47 |
48 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /src/sveltekit-vault/.obsidian/workspace: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "id": "90d39e68d1bb0250", 4 | "type": "split", 5 | "children": [ 6 | { 7 | "id": "18aa837d8be32848", 8 | "type": "leaf", 9 | "state": { 10 | "type": "markdown", 11 | "state": { 12 | "file": "posts/formerly-privateish-thought.md", 13 | "mode": "source", 14 | "source": false 15 | } 16 | } 17 | } 18 | ], 19 | "direction": "vertical" 20 | }, 21 | "left": { 22 | "id": "726742b910def023", 23 | "type": "split", 24 | "children": [ 25 | { 26 | "id": "e0683daeafa0656c", 27 | "type": "tabs", 28 | "children": [ 29 | { 30 | "id": "e9beba7eab1a3b3e", 31 | "type": "leaf", 32 | "state": { 33 | "type": "file-explorer", 34 | "state": {} 35 | } 36 | }, 37 | { 38 | "id": "2bfb210a0a55df37", 39 | "type": "leaf", 40 | "state": { 41 | "type": "search", 42 | "state": { 43 | "query": "", 44 | "matchingCase": false, 45 | "explainSearch": false, 46 | "collapseAll": false, 47 | "extraContext": false, 48 | "sortOrder": "alphabetical" 49 | } 50 | } 51 | } 52 | ] 53 | } 54 | ], 55 | "direction": "horizontal", 56 | "width": 311.5036334991455 57 | }, 58 | "right": { 59 | "id": "7fac736af6b6f92e", 60 | "type": "split", 61 | "children": [ 62 | { 63 | "id": "a6bb8482fdb274c9", 64 | "type": "tabs", 65 | "children": [ 66 | { 67 | "id": "918fb1f1c53577f1", 68 | "type": "leaf", 69 | "state": { 70 | "type": "backlink", 71 | "state": { 72 | "file": "posts/formerly-privateish-thought.md", 73 | "collapseAll": false, 74 | "extraContext": false, 75 | "sortOrder": "alphabetical", 76 | "showSearch": false, 77 | "searchQuery": "", 78 | "backlinkCollapsed": false, 79 | "unlinkedCollapsed": true 80 | } 81 | } 82 | } 83 | ] 84 | } 85 | ], 86 | "direction": "horizontal", 87 | "width": 300, 88 | "collapsed": true 89 | }, 90 | "active": "18aa837d8be32848", 91 | "lastOpenFiles": [ 92 | "posts/formerly-privateish-thought.md", 93 | "books/atomic-habits.md", 94 | "posts/large-hadron-collider.md", 95 | "books/philosophy-of-software-design.md", 96 | "posts/postable-thought.md", 97 | "templates/post.md", 98 | "templates/book.md", 99 | "books/refactoring-ui.md", 100 | "books/dont-make-me-think.md", 101 | "_assets/philosophy-of-software-design.jpeg" 102 | ] 103 | } -------------------------------------------------------------------------------- /src/sveltekit-vault/books/philosophy-of-software-design.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A Philosophy of Software Design 3 | author: John K. Ousterhout 4 | originallyPublished: 2018 5 | publishDate: 2018 6 | format: digital 7 | coverImg: philosophy-of-software-design.jpeg 8 | --- 9 | ## citation 10 | Ousterhout, John K. _A Philosophy of Software Design_. , 2018. Digital Print. 11 | 12 | ## big ideas 13 | This book was so thoughtful that it even included Summary of Design Principles and Summary of Red Flags sections at the end: 14 | ### summary of design principles 15 | Here are the most important software design principles discussed in this book: 16 | 1. Complexity is incremental: you have to sweat the small stuff (see p.11). 17 | 2. Working code isn't enough (see p.14). 18 | 3. Make continual small investments to improve system design (see p.15). 19 | 4. Modules should be deep (see p.22). 20 | 5. Interfaces should be designed to make the most common usage as simple as possible (see p.27). 21 | 6. It's more important for a module to have a simple interface than a simple implementation (see pp.55, 71). 22 | 7. General-purpose modules are deeper (see p.39). 23 | 8. Separate general-purpose and special-purpose code (see p.62). 24 | 9. Different layers should have different abstractions (see p.45). 25 | 10. Pull complexity downward (see p.55). 26 | 11. Define errors (and special cases) out of existence (see p.79). 27 | 12. Design it twice (see p. 91). 28 | 13. Comments should describe things that are not obvious from the code (see p.101). 29 | 14. Software should be designed for ease of reading, not ease of writing (see p.149). 30 | 15. The increments of software development should be abstractions, not features (see p.154). 31 | 32 | ### summary of red flags 33 | Here are a few of the most important red flags discussed in this book. The presence of any of these symptoms in a system suggests that there is a problem with the system's design: 34 | 1. **Shallow Module:** the interface for a class or method isn't much simpler than its implementation (see pp.25, 110). 35 | 2. **Information Leakage:** a design decision is reflected in multiple modules (see p.31). 36 | 3. **Temporal Decompisition:** the code structure is based on the order in which operations are executed, not on information hiding (see p.32). 37 | 4. **Overexposure:** An API forces callers to be aware of rarely used features in order to use commonly used features (see p.36). 38 | 5. **Pass-Through Method:** a method does almost nothing except pass its arguments to another method with a similar signature (see p.46). 39 | 6. **Repetition:** a nontrivial piece of code is repeated over and over (see p.62). 40 | 7. **Special-General Mixture:** special-purpose code is not cleanly separated from general purpose code (see p.65). 41 | 8. **Conjoined Methods:** two methods have so many dependencies that its hard to understand the implementation of one without understanding the implementation of the other (see p.72). 42 | 9. **Comment Repeats Code:** all of the information in a comment is immediately obvious from the code next to the comment (see p.104). 43 | 10. **Implementation Documentation Contaminates Interface:** an interface comment describes implementation details not needed by users of the thing being documented (see p.114). 44 | 11. **Vague Name:** the name of a variable or method is so imprecise that it doesn't convey much useful information (see p.123). 45 | 12. **Hard to Pick Name:** it is difficult to come up with a precise and intuitive name for an entity (see p.125). 46 | 13. **Hard to Describe:** in order to be complete, the documentation for a variable or method must be long (see p.131). 47 | 14. **Nonobvious Code:** the behavior or meaning of a piece of code cannot be understood easily. (see p.148). --------------------------------------------------------------------------------