├── .eslintrc.js ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Enhancement.md │ └── Question.md ├── .gitignore ├── .nvmrc ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── cli └── create-new-post.js ├── content ├── __about │ ├── resume-en.md │ └── resume-ko.md ├── assets │ ├── christmas-wreath.png │ ├── christmas_hat.png │ ├── favicon.png │ ├── flamingo.png │ ├── hat2.png │ ├── profile.png │ └── spring-icon.png └── blog │ ├── essay │ ├── 2019의-발표들-회고.md │ ├── 2020-my-good-code.md │ ├── 2021-turnover.md │ ├── add-new-tool-at-team.md │ ├── images │ │ ├── 2019_presentation.png │ │ ├── 2019_retro_0.png │ │ ├── 2019_retro_1.png │ │ ├── 2019_retro_2.png │ │ ├── 2019_retro_3.png │ │ ├── 2019_retro_4.png │ │ ├── 2019_retro_5.png │ │ ├── 2020_retro │ │ │ └── thumbnail.png │ │ ├── 2021_retro │ │ │ ├── commit_log.jpg │ │ │ ├── kimcoding.jpg │ │ │ └── thumbnail.jpg │ │ ├── 2021_turnover │ │ │ ├── lifecycle_notion.png │ │ │ ├── tech_notion.png │ │ │ ├── thumbnail.png │ │ │ ├── timeline_notion.png │ │ │ ├── turnover_notion.png │ │ │ └── vacation_notion.png │ │ ├── 2022_retro │ │ │ └── thumbnail.jpg │ │ ├── 2023_retro │ │ │ ├── blender-donut.jpeg │ │ │ ├── blender-room-720.mov │ │ │ ├── blender-room-720.png │ │ │ ├── craft-design.png │ │ │ ├── craft-thumbnail.jpg │ │ │ ├── tds-desktop-doc.png │ │ │ └── thumbnail.png │ │ ├── add-new-tool-at-team │ │ │ └── thumbnail.png │ │ ├── carbon.png │ │ ├── growth │ │ │ └── thumbnail.png │ │ ├── image-20181231-0.png │ │ ├── image-20181231-1.png │ │ ├── image-20181231-2.png │ │ ├── image-20181231-3.png │ │ ├── image-20181231-4.png │ │ ├── immutable-wedding-epilogue │ │ │ ├── check_animation.gif │ │ │ ├── check_icon_figma.png │ │ │ ├── figma_design_board.png │ │ │ ├── figma_design_borad_old.png │ │ │ ├── heart_animation.gif │ │ │ ├── pagination_animation.gif │ │ │ ├── slack_task.jpg │ │ │ ├── thumbnail.jpg │ │ │ └── vedio_heart_effect.gif │ │ ├── native_dictionary.png │ │ ├── non-major-developers-are-no-different.png │ │ ├── simple_software.jpg │ │ ├── slide_0.jpg │ │ ├── slide_1.jpg │ │ ├── slide_2.jpg │ │ ├── slide_3.jpg │ │ ├── slide_4.jpg │ │ ├── the-secret-to-netflix-growth │ │ │ └── thumbnail.jpg │ │ ├── thumbnail-good-code.png │ │ └── what-i-learn-150 │ │ │ ├── 00.png │ │ │ ├── 01.png │ │ │ ├── 02.png │ │ │ ├── 03.png │ │ │ ├── 04.png │ │ │ ├── 05.jpg │ │ │ ├── 06.jpeg │ │ │ ├── first_title.png │ │ │ ├── my-github.png │ │ │ └── question.png │ ├── immutable-wedding-epilogue.md │ ├── no-silver-bullet.md │ ├── non-major-developers-are-no-different.md │ ├── retro2018.md │ ├── retro2019.md │ ├── retro2020.md │ ├── retro2021.md │ ├── retro2022.md │ ├── retro2023.md │ ├── simple-software.md │ ├── the-secret-to-netflix-growth.md │ └── what-i-learn150-1.md │ ├── etc │ ├── googling.md │ ├── images │ │ ├── googling │ │ │ ├── 00.jpg │ │ │ ├── 01.png │ │ │ ├── 02.png │ │ │ ├── 03.png │ │ │ ├── 04.png │ │ │ ├── 05.png │ │ │ ├── 06.png │ │ │ ├── 07.png │ │ │ ├── 08.png │ │ │ ├── 09.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ └── 16.png │ │ ├── image-0.png │ │ ├── image-1.png │ │ ├── image-2.png │ │ ├── image-3.png │ │ └── image-4.png │ └── official-docs.md │ ├── k8s │ ├── images │ │ ├── image_0.png │ │ ├── image_1.png │ │ ├── image_10.png │ │ ├── image_11.png │ │ ├── image_12.png │ │ ├── image_13.png │ │ ├── image_14.png │ │ ├── image_15.png │ │ ├── image_2.png │ │ ├── image_3.png │ │ ├── image_4.png │ │ ├── image_5.png │ │ ├── image_6.png │ │ ├── image_7.png │ │ ├── image_8.png │ │ ├── image_9.png │ │ └── thumbnail.jpeg │ └── k8s-simply-visually-explained.md │ ├── pattern │ ├── images │ │ ├── monorepo │ │ │ ├── babel-example.png │ │ │ ├── github-secret.png │ │ │ ├── import-error.png │ │ │ ├── lerna.png │ │ │ ├── package-name.png │ │ │ └── thumbnail.png │ │ ├── redux_saga_flow.png │ │ ├── saga_event.png │ │ ├── saga_event_rollback.png │ │ ├── saga_orchestration.png │ │ ├── saga_orchestration_rollback.png │ │ ├── sample_service.png │ │ ├── sample_service_sequence.png │ │ └── thumbnail.png │ ├── mono-repo-config.md │ └── saga-pattern-with-redux-saga.md │ ├── react │ ├── design-system-beyond-code.md │ ├── design-system-decision-record.md │ ├── form-handling.md │ ├── images │ │ ├── analyze.png │ │ ├── bundle-result.png │ │ ├── client-bundle.png │ │ ├── design-system-beyond-code │ │ │ ├── modal_popover_guide.png │ │ │ ├── orbit_model_color.png │ │ │ ├── rogers-diffusion-of-innovation-curve.png │ │ │ └── thumbnail.png │ │ ├── design-system-decision-record │ │ │ ├── leftSlot.png │ │ │ ├── mulit_select_search.png │ │ │ ├── notion_page.png │ │ │ ├── notion_page_not_use.png │ │ │ ├── portalContainer.png │ │ │ ├── references.png │ │ │ ├── select_example.png │ │ │ ├── select_trigger.jpg │ │ │ ├── select_trigger.png │ │ │ ├── state.png │ │ │ ├── thumbnail.png │ │ │ ├── timepicker.png │ │ │ └── timepicker_new_option.png │ │ ├── form-handling │ │ │ ├── complex-form.png │ │ │ ├── controlled_uncontrolled_rerender.gif │ │ │ ├── input-state-update.png │ │ │ ├── simple-login.png │ │ │ └── thumbnail.png │ │ ├── jsx-new-transform │ │ │ ├── react-17.png │ │ │ ├── react-reference-error.png │ │ │ ├── thumbnail.jpg │ │ │ └── thumbnail.png │ │ ├── make-select │ │ │ ├── 1pw_info.png │ │ │ ├── headlessui.dev_react_combobox.png │ │ │ ├── headlessui.dev_react_listbox (1).png │ │ │ ├── headlessui.dev_react_listbox.png │ │ │ ├── hmm.gif │ │ │ ├── multi_select.png │ │ │ ├── select_autofill.gif │ │ │ ├── select_autofill.mp4 │ │ │ ├── select_autofill.png │ │ │ ├── select_keyboard.gif │ │ │ ├── select_keyboard.mp4 │ │ │ └── thumbnail.jpg │ │ ├── node-modules-splitting │ │ │ ├── after_bundle_output.png │ │ │ ├── before_bundle_output.png │ │ │ └── thumbnail.png │ │ ├── org-network.png │ │ ├── org_to_user_no_split.gif │ │ ├── org_to_user_split.gif │ │ ├── react-lazy.png │ │ ├── react-loadable-issue.png │ │ ├── scoped-context │ │ │ ├── dialog-alertdialog.jpg │ │ │ └── thumbnail.jpg │ │ ├── ssr-area.png │ │ ├── ssr-first.png │ │ ├── ssr-full-content.png │ │ ├── test1.gif │ │ ├── test2.gif │ │ ├── thumbnail.png │ │ ├── user--cache.png │ │ ├── user-ssr-data-fetch.png │ │ ├── user-ssr-no-cache.png │ │ └── user-ssr-no-data-fetch.png │ ├── import-react-from-react.md │ ├── make-select.md │ ├── scoped-context.md │ ├── ssr-0-intro.md │ ├── ssr-1-codesplitting.md │ ├── ssr-2-ssr---basic.md │ ├── ssr-3-ssr-data-fetch.md │ └── ssr-4-ux-ssr.md │ ├── tool │ ├── rollup │ │ ├── images │ │ │ └── rollupjs-config │ │ │ │ ├── cjs-error.png │ │ │ │ ├── include_card.png │ │ │ │ ├── no_card.png │ │ │ │ └── thumbnail.png │ │ └── rollupjs-config.md │ └── webpack │ │ ├── images │ │ ├── node-modules-splitting │ │ │ ├── after_bundle_output.png │ │ │ ├── before_bundle_output.png │ │ │ └── thumbnail.png │ │ └── whats-diff-in-webpack5 │ │ │ └── thumbnail.png │ │ ├── node-modules-splitting.md │ │ └── whats-different-in-webpack5.md │ └── web │ ├── about-navigator.md │ ├── browser-rendering-performance.md │ ├── browser-rendering-process.md │ ├── cookie-recipes.md │ ├── css-in-js-whats-the-defference.md │ ├── images │ ├── apple_touch_tag.png │ ├── browser-rendering-performance │ │ ├── activate.png │ │ ├── commit.png │ │ ├── composite_after_flow.jpeg │ │ ├── composite_after_paint.png │ │ ├── composite_layer_timeline.png │ │ ├── composite_only.png │ │ ├── composition.gif │ │ ├── composition_forest.png │ │ ├── css_to_style_sheet.png │ │ ├── display.png │ │ ├── draw.png │ │ ├── enhance_result.png │ │ ├── implicit-compositing.gif │ │ ├── layer_memory.png │ │ ├── layer_promotion_result.png │ │ ├── layout.png │ │ ├── layout_cost.gif │ │ ├── non-fast-scroll-region-all.png │ │ ├── non-fast-scroll-region.png │ │ ├── non_composition_raster.gif │ │ ├── paint_invalidation.png │ │ ├── parsing.png │ │ ├── property_tree.png │ │ ├── raster.png │ │ ├── reflow.png │ │ ├── repaint.png │ │ ├── repaint_layer_timeline.png │ │ ├── style.png │ │ ├── style_calc.png │ │ ├── thumbnail.png │ │ ├── thumbnail2.png │ │ ├── tilling.png │ │ └── 메인플로우.png │ ├── charset-1.png │ ├── charset-2.png │ ├── cookie │ │ ├── first-vs-third.png │ │ ├── thumbnail.png │ │ └── twitter.png │ ├── css-in-js │ │ ├── cssom-result.png │ │ ├── emotion-benchmark-result-1.png │ │ ├── emotion-benchmark-result.png │ │ ├── emotion-to-cssvar.png │ │ ├── linaria-dynamic-style-poster.png │ │ ├── linaria-dynamic-style.mp4 │ │ ├── linaria-sc-performance.png │ │ ├── stitches-atomic-class.png │ │ ├── stitches-css-inject.png │ │ ├── styled-components-critical-css-result.png │ │ ├── styled-components-dynamic-style-poster.png │ │ ├── styled-components-dynamic-style.mp4 │ │ ├── thumbnail.png │ │ ├── thumbnail2.png │ │ └── what-is-css-in-js.png │ ├── description_example.png │ ├── facebook-large.png │ ├── facebook-small.png │ ├── favicon_example.png │ ├── fifth.png │ ├── first.png │ ├── fourth.png │ ├── lang.png │ ├── navigator │ │ ├── navigator1.gif │ │ ├── navigator2.png │ │ ├── navigator3.png │ │ ├── navigator4.png │ │ ├── navigator5.png │ │ ├── navigator6-1.png │ │ ├── navigator6.png │ │ ├── navigator7.png │ │ ├── navigator8.png │ │ ├── navigator9.png │ │ └── thumbnail.png │ ├── og-image.png │ ├── search_result.png │ ├── second.png │ ├── service-worker │ │ ├── background-sync-example1.png │ │ ├── background-sync-example2.png │ │ ├── background-sync.png │ │ ├── interaction-with-cache.png │ │ ├── precache-build.png │ │ ├── precache-manifest.png │ │ ├── push-notification.png │ │ ├── swUrl-build.png │ │ └── thumbnail.png │ ├── sixth.png │ ├── tailwind │ │ ├── bootstrap_example.png │ │ ├── card_example.png │ │ ├── responsive_tailwind.gif │ │ ├── search_example.png │ │ ├── search_result.png │ │ ├── thumbnail.png │ │ └── tw_macro_issue.png │ ├── third.png │ ├── thumbnail.png │ ├── thumbnail2.png │ ├── thumbnail_example.png │ ├── thumbnail_tag_example.png │ ├── title_example.png │ ├── tree-shaking-module-system │ │ ├── circular_reference.png │ │ ├── cjs_binding.png │ │ ├── dead-code-elimination-vs-tree-shaking.png │ │ ├── esm_binding.png │ │ ├── esm_binding_update.png │ │ ├── global_share.png │ │ ├── module_record.png │ │ ├── node_tree.png │ │ └── thumbnail.jpg │ ├── twitter-empty-card.png │ ├── twitter-large.png │ ├── twitter-small.png │ ├── with-async.png │ ├── with-defer.png │ ├── without-defer-async-body.png │ ├── without-defer-async-head.png │ └── you-dont-know-polyfill │ │ ├── sokra_comment.png │ │ ├── test-node-result.png │ │ └── thumbnail.png │ ├── index-html-1.md │ ├── index-html-2.md │ ├── service-worker.md │ ├── tailwindcss-w-twin-macro-emotion.md │ ├── tree-shaking-module-system.md │ └── you-dont-know-polyfill.md ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-meta-config.js ├── gatsby-node.js ├── package-lock.json ├── package.json ├── src ├── components │ ├── bio │ │ ├── index.jsx │ │ └── index.scss │ ├── category │ │ ├── index.jsx │ │ ├── index.scss │ │ └── item │ │ │ └── index.jsx │ ├── contents │ │ └── index.jsx │ ├── disqus │ │ └── index.jsx │ ├── elements │ │ ├── hr │ │ │ ├── index.jsx │ │ │ └── index.scss │ │ └── index.js │ ├── footer │ │ ├── index.jsx │ │ └── index.scss │ ├── head │ │ └── index.jsx │ ├── header │ │ ├── index.jsx │ │ └── index.scss │ ├── post-container │ │ ├── index.jsx │ │ └── index.scss │ ├── post-date │ │ ├── index.jsx │ │ └── index.scss │ ├── post-navigator │ │ ├── index.jsx │ │ └── index.scss │ ├── post-title │ │ └── index.jsx │ ├── social-share │ │ ├── facebook-icon │ │ │ ├── index.jsx │ │ │ └── index.scss │ │ ├── github-icon │ │ │ ├── index.jsx │ │ │ └── index.scss │ │ ├── index.jsx │ │ ├── index.scss │ │ └── twitter-icon │ │ │ ├── index.jsx │ │ │ └── index.scss │ ├── sponsor-button │ │ ├── index.jsx │ │ └── index.scss │ ├── theme-switch │ │ ├── index.jsx │ │ └── index.scss │ ├── thumbnail-container │ │ ├── index.jsx │ │ └── index.scss │ ├── thumbnail-item │ │ ├── index.jsx │ │ └── index.scss │ ├── top │ │ ├── index.jsx │ │ └── index.scss │ └── utterances │ │ └── index.jsx ├── constants │ ├── enum.js │ ├── index.js │ ├── lang.js │ ├── meta.js │ └── window.js ├── html.js ├── layout │ ├── SnowFlake.jsx │ ├── index.jsx │ └── index.scss ├── pages │ ├── 404.js │ ├── about.js │ └── index.js ├── styles │ ├── code.scss │ ├── dark-theme.scss │ ├── light-theme.scss │ ├── post.scss │ ├── resume.scss │ ├── snow-flake.scss │ └── variables.scss ├── templates │ └── blog-post.js └── utils │ ├── dom.js │ ├── event-manager.js │ ├── scroll.js │ ├── share.js │ ├── storage │ ├── browser.js │ ├── core.js │ ├── index.js │ ├── localStorage.js │ └── sessionStorage.js │ ├── typography.js │ └── visible.js └── static ├── ads.txt ├── favicon.ico ├── images ├── quote-black.png └── quote-white.png ├── resume_thumbnail.jpg └── robots.txt /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | }, 6 | plugins: ['react'], 7 | globals: { 8 | graphql: false, 9 | }, 10 | parserOptions: { 11 | ecmaVersion: 2017, 12 | sourceType: 'module', 13 | ecmaFeatures: { 14 | experimentalObjectRestSpread: true, 15 | jsx: true, 16 | }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: SoYoung210 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug report 3 | about: Report to bug or error! 4 | --- 5 | 6 | ## Description 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🌈 Enhancement 3 | about: Things you might want to try to improve or add to in this template. 4 | --- 5 | 6 | ## Description 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ❓ Question 3 | about: May I help you? 4 | --- 5 | 6 | ## Description 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variables file 55 | .env 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.22.1 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "semi": false, 4 | "singleQuote": true, 5 | "useTabs": false 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": false 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Gatsbyjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## SOSOLOG 2 | 3 | Powered by [Gatsby-starter-bee](https://github.com/JaeYeopHan/gatsby-starter-bee) 4 | -------------------------------------------------------------------------------- /cli/create-new-post.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs-extra') 3 | const dateFns = require('date-fns') 4 | const _ = require('lodash') 5 | const rr = require('recursive-readdir') 6 | const matter = require('gray-matter') 7 | const inquirer = require('inquirer') 8 | const log = require('signale') 9 | const cwd = process.cwd() 10 | 11 | const CONTENTS_DIR = '/content/blog' 12 | const TARGET_DIR = `${cwd}${CONTENTS_DIR}` 13 | const IGNORE_DIR = 'images' 14 | const UTF_8 = 'utf8' 15 | const DATE_FORMAT = 'YYYY-MM-DD HH:MM:SS' 16 | 17 | const ignoreFunc = (file, stats) => 18 | stats.isDirectory() && path.basename(file) == IGNORE_DIR 19 | 20 | const getCategories = async () => { 21 | const markdownFiles = await rr(TARGET_DIR, [ignoreFunc]) 22 | 23 | return _.uniq( 24 | markdownFiles 25 | .map(file => fs.readFileSync(file, UTF_8)) 26 | .map(str => matter(str).data.category) 27 | .filter(val => !!val) 28 | .map(str => str.trim().toLowerCase()) 29 | ) 30 | } 31 | 32 | const getFileName = title => 33 | title 34 | .split(' ') 35 | .join('-') 36 | .toLowerCase() 37 | 38 | const refineContents = rawContents => 39 | matter 40 | .stringify('', rawContents) 41 | .split("'") 42 | .join('') 43 | 44 | const fetchCategory = async () => { 45 | let category 46 | const customCategoryOption = '[[ CREATE NEW CATEGORY ]]' 47 | const categories = await getCategories() 48 | const categoryChoices = [ 49 | ...categories, 50 | new inquirer.Separator(), 51 | customCategoryOption, 52 | ] 53 | const { selectedCategory } = await inquirer.prompt([ 54 | { 55 | type: 'list', 56 | name: 'selectedCategory', 57 | message: 'Select a category', 58 | choices: categoryChoices, 59 | }, 60 | ]) 61 | 62 | if (selectedCategory === customCategoryOption) { 63 | const { customizedCategory } = await inquirer.prompt([ 64 | { 65 | type: 'input', 66 | name: 'customizedCategory', 67 | message: 'Enter the customized category', 68 | validate: val => { 69 | if (val.includes("'")) { 70 | return 'Cannot use single quote' 71 | } 72 | 73 | if (categories.includes(val)) { 74 | return `Already exist category name:: ${val}` 75 | } 76 | 77 | return true 78 | }, 79 | }, 80 | ]) 81 | category = customizedCategory 82 | } else { 83 | category = selectedCategory 84 | } 85 | 86 | if (!category) { 87 | throw Error('Unknown Error: Cannot find category!') 88 | } 89 | 90 | return category 91 | } 92 | 93 | const fetchTitle = async category => { 94 | const { title } = await inquirer.prompt([ 95 | { 96 | type: 'input', 97 | name: 'title', 98 | message: 'Enter the title', 99 | default: () => 'New post title', 100 | validate: async val => { 101 | if (val.includes("'")) { 102 | return 'Cannot use single quote' 103 | } 104 | 105 | const fileName = getFileName(val) 106 | const dest = `${TARGET_DIR}/${category}/${fileName}.md` 107 | const destFileExists = await fs.pathExists(dest) 108 | 109 | if (destFileExists) { 110 | return `Already exist file name:: ${fileName}.md` 111 | } 112 | 113 | return true 114 | }, 115 | }, 116 | ]) 117 | 118 | return title 119 | } 120 | 121 | module.exports = (async function() { 122 | const date = dateFns.format(new Date(), DATE_FORMAT) 123 | 124 | log.info('Create new post:: ', date) 125 | log.start('Start to process!\n') 126 | 127 | const category = await fetchCategory() 128 | const destDir = `${TARGET_DIR}/${category}` 129 | const destDirExists = await fs.pathExists(destDir) 130 | 131 | if (!destDirExists) { 132 | await fs.ensureDir(destDir) 133 | } 134 | 135 | const title = await fetchTitle(category) 136 | const fileName = getFileName(title) 137 | const contents = refineContents({ title, date, category }) 138 | 139 | fs.writeFile(`${destDir}/${fileName}.md`, contents, err => { 140 | if (err) { 141 | log.error('Unknown Error: Cannot write file!') 142 | return 143 | } 144 | console.log('') 145 | 146 | log.success('Success to create new post!') 147 | log.note(`/${category}/${fileName}.md\n${contents}`) 148 | }) 149 | })() 150 | -------------------------------------------------------------------------------- /content/assets/christmas-wreath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/christmas-wreath.png -------------------------------------------------------------------------------- /content/assets/christmas_hat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/christmas_hat.png -------------------------------------------------------------------------------- /content/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/favicon.png -------------------------------------------------------------------------------- /content/assets/flamingo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/flamingo.png -------------------------------------------------------------------------------- /content/assets/hat2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/hat2.png -------------------------------------------------------------------------------- /content/assets/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/profile.png -------------------------------------------------------------------------------- /content/assets/spring-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/assets/spring-icon.png -------------------------------------------------------------------------------- /content/blog/essay/add-new-tool-at-team.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '팀에 새로운 도구를 도입하고 싶다.' 3 | date: 2020-08-09 00:12:32 4 | category: essay 5 | thumbnail: './images/add-new-tool-at-team/thumbnail.png' 6 | --- 7 | 8 | ![image](./images/add-new-tool-at-team/thumbnail.png) 9 | 10 | 개발 생태계는 빠르게 변화하고 있고, 10년 이상 '트렌드'로 자리 잡던 도구와 방식이 한순간에 레거시가 되기도 한다. 개발자는 늘 새로운 것에 끌리기 마련이고 회사에서 새 프로젝트를 기존과 다른 방식으로 진행해보고 싶다는 생각은 누구나 한 번쯤 가져봤을 것이다. 새로운 것에 대한 도입은 팀원들과 협의가 필요하고, 이 과정이 순조롭게 진행될 수도 있고 긴 논의가 필요할 수도 있다. 11 | 12 | 이 글은 누구 한쪽의 편을 들기 위한 글도 아니고 최신 트렌드의 도구를 도입해야 한다는 글도 아니다. 팀의 프로젝트를 만들어가는 개발자가 새로운 것을 도입하는 데 겪을 수 있는 약간의 갈등과 그 갈등의 의미에 대해 생각해보며 작성한 글이다. 13 | 14 | ## 먼저, 나의 주장을 돌아보자 15 | 16 | 팀에 새로운 도구 도입을 주장하기 전, 내 주장이 정말 우리 팀의 고통을 해결하기 위한 것인지 되돌아볼 필요가 있다. 혹시라도 단순히 새로운 도구가 궁금한 것이라면 이 도구에 대한 이야기는 '도입에 대한 논의'가 아닌 '공유' 정도에 머물러도 괜찮다. 문제 해결을 위한 수단이 아니라 호기심에 끌리는 것이었다면 아직 팀에 도입을 주장하기엔 위험하지 않을까? 17 | 18 | ## 생각이 다르기 때문에 한 팀이다 19 | 20 | 호기심 해결이 아닌 문제 해결을 위한 주장이라는 확신을 얻고, "A를 도입하면 현재 우리가 겪고 있는 문제1, 2, 3을 해결할 수 있고 Test를 작성하기도 쉬워지고 그 외에 여러 장점이 있습니다."라고 소개한다. 21 | 22 | **팀이 크면 클수록, 모두가 즉시 이 문장에 대해 공감하지 못할 확률이 높다.** 23 | 24 | 당연한 말이지만, 사람마다 생각하는 바가 다르기 때문이다. 누군가는 나의 주장처럼 'A로 얻을 수 있는 장점'에 초점을 맞출 수도 있지만, 누군가는 'A에 대한 학습비용 대비 얻는 장점이 크지 않다.'라고 생각하거나 'A를 도입하면 생길 수 있는 장점이 있지만, 단점 1, 2가 생기는 문제'에 대해 의문을 제기할 수 있다. 25 | 26 | 나는 관심을 가져온 구조 혹은 라이브러리이고 오랜 시간 프로덕트 도입을 고민해왔지만, 이는 나 혼자 했던 고민이다. 당연히 러닝커브 대비 장점을 고려해야 하고, 새로운 것을 도입했을 때의 단점도 예민하게 생각해봐야 한다. 27 | 28 | > 이는 매우 당연한 과정이고 잘 논의하여 하나의 타협점을 찾아가는 팀이 좋은 팀이라고 생각한다. 29 | 30 | 100% 완벽한 도구는 없다. 내가 주장하는 도구는 이 단점과 러닝커브 대비 우리 팀의 문제를 해결할 수 있고 장기적 관점에서 도움이 될 것이라는 확신이 있어야 한다. 31 | 32 | ## 어떤 방법이 필요할까 33 | 34 | 새로운 것에는 시간이 필요하다. 페어 코딩이 필요할 수도 있고, 잘 설명된 문서나 발표자료 같은 것들이 필요할 수도 있다. 내 의견을 좀 더 어필하고 싶다면 가장 효과적인 전략이 무엇일지 고민하는 시간도 필요하다. 35 | 36 | **맹목적으로 반대하는 사람은 없다.** 도구가 익숙하지 않거나, 익숙하게 만들 만큼 가치 있다는 것에 공감하지 못하거나, 그냥 어려울 수 있다. 이미 기존 방법으로 문제를 잘 해결하고 있다고 믿고 있다면, 내가 제안하는 도구는 '새롭지만 러닝커브'일 수 있다. 그 어떤 이유에서라도 그 이유에 '공감'해야 하고 상대방을 동료로서 이해하며 '설득'해야 한다. 37 | 38 | > 이런 '설득'과정들을 통해서 '어느 정도 알고 있다'라고 생각한 내 지식과 생각에 빈틈이 없었는지 확인해볼 수 있다. 39 | 40 | 공감도 하고 설득도 해봤는데 잘 받아들여지지 않는다면 어떻게 해야할까? 내 의견이 타당했는지 한번 돌아보고 그럼에도 바뀌지 않는다면 이제 **아군**이 필요할 때이다. 41 | 42 | ``` 43 | 모든 걸 한 번에 바꾸려 했다가는 반란이 일어날 것이다. 44 | 반란이 일어나면 어렵게 얻은 신뢰를 잃고 모든 노력이 수포가 된다. 45 | 감당할 수 있는 변화의 속도는 팀에 따라 다르다. 46 | 모두에게 '완벽한 변화'를 강요하지 마라. '아군'을 모집해서 주장의 타당성을 인정받는 게 중요하다." 47 | 48 | - 심플 소프트웨어 Chapter 18~19 내용 中- 49 | ``` 50 | 51 | 내 의견에 찬성한다고 해서 '아군'이고 그렇지 않다고 해서 '적군'이라는 것이 아니다. 모두의 동의를 얻으려는 방법을 고수하다 보면 내가 얻고자 했던 '개선'에 초점을 맞추는 본질이 쉽게 흐려질 수 있다. 아군을 얻고, 그 아군이 나의 주장을 지지해주고 그 과정을 통해 내가 커버할 수 없는 부분을 아군이 도와주는 형태가 바람직한 상황이다. 물론 이 과정에서 실제 내 의견이 타당하지 않다고 결론 날 수도 있다. 52 | 53 | > 내 의견이 꼭 받아들여져야 한다는 고집은 내려두고 '본질'에 집중하는 것이 제일 중요하다. 54 | 55 | ## 결과에 대한 회고 56 | 57 | 팀에 새로운 것에 관해 주장하고 도입하는 과정이 끝났다면 기술과 프로세스에 대한 회고가 필요하다. 58 | 59 | ### 기술적 회고 60 | 61 | 모든 의사결정은 돌아보면 후회되는 부분이 생길 수 있다. 당장 되돌아보면 그때의 결정이 최선일 수 있지만, 지나고 나면 그렇지 않을 수 있다. 예를 들어, 상태를 별도로 관리하는 것을 예전에는 'View와 Data를 분리하고 비즈니스 로직을 안전하게 설계하는 것'이라고 생각했지만, 지나서 생각해보면 'Single source of truth' 컨셉과 맞지 않는다는 생각이 들 수 있다. 62 | 63 | 새로운 경험과 환경을 마주하면서 생각은 확장되고 관점은 변한다. 미래의 내가 과거의 결정들을 어떻게 생각하는지 한 번씩 되돌아보는 경험이 또 다른 성장이 될 수 있다고 생각한다. 64 | 치열한 논의를 통해 도입했던 도구나 방식이 미래에 돌아봤을 때 적절하지 않다고 생각된다면 그 내용을 팀에 공유하는 것으로 '함께 성장'을 이룰 수 있지 않을까? 65 | 66 | ### 프로세스 회고 67 | 68 | 반대하는 팀원의 의견을 듣고 조율하는 과정에서 내가 선택한 전략이 최선이었는지, '더 좋은 것'에 대한 추구가 아닌 '고집'은 아니었는지 되돌아보자. 팀이 성장하고 문제를 더 나은 방법으로 해결하는 것도 중요하지만 그것보다 중요한 것은 팀원 간에 신뢰를 잃지 않는 것이라고 생각한다. 69 | 70 | ## 마무리 71 | 72 | 팀 차원에서 새로운 것을 도입하기는 쉽지 않은 일이다. 사람마다 중요하게 생각하는 가치는 다르고 이 **'다름'은 '틀림'이 아니다.** 팀의 방향에 대해 논의하고 새로운 것에 대해 합의하는 과정에서 '같이 성장'할 수 있다고 생각한다. 73 | -------------------------------------------------------------------------------- /content/blog/essay/images/2019_presentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_presentation.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_0.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_1.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_2.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_3.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_4.png -------------------------------------------------------------------------------- /content/blog/essay/images/2019_retro_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2019_retro_5.png -------------------------------------------------------------------------------- /content/blog/essay/images/2020_retro/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2020_retro/thumbnail.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_retro/commit_log.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_retro/commit_log.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/2021_retro/kimcoding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_retro/kimcoding.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/2021_retro/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_retro/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/lifecycle_notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/lifecycle_notion.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/tech_notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/tech_notion.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/thumbnail.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/timeline_notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/timeline_notion.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/turnover_notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/turnover_notion.png -------------------------------------------------------------------------------- /content/blog/essay/images/2021_turnover/vacation_notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2021_turnover/vacation_notion.png -------------------------------------------------------------------------------- /content/blog/essay/images/2022_retro/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2022_retro/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/blender-donut.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/blender-donut.jpeg -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/blender-room-720.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/blender-room-720.mov -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/blender-room-720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/blender-room-720.png -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/craft-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/craft-design.png -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/craft-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/craft-thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/tds-desktop-doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/tds-desktop-doc.png -------------------------------------------------------------------------------- /content/blog/essay/images/2023_retro/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/2023_retro/thumbnail.png -------------------------------------------------------------------------------- /content/blog/essay/images/add-new-tool-at-team/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/add-new-tool-at-team/thumbnail.png -------------------------------------------------------------------------------- /content/blog/essay/images/carbon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/carbon.png -------------------------------------------------------------------------------- /content/blog/essay/images/growth/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/growth/thumbnail.png -------------------------------------------------------------------------------- /content/blog/essay/images/image-20181231-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/image-20181231-0.png -------------------------------------------------------------------------------- /content/blog/essay/images/image-20181231-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/image-20181231-1.png -------------------------------------------------------------------------------- /content/blog/essay/images/image-20181231-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/image-20181231-2.png -------------------------------------------------------------------------------- /content/blog/essay/images/image-20181231-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/image-20181231-3.png -------------------------------------------------------------------------------- /content/blog/essay/images/image-20181231-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/image-20181231-4.png -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/check_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/check_animation.gif -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/check_icon_figma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/check_icon_figma.png -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/figma_design_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/figma_design_board.png -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/figma_design_borad_old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/figma_design_borad_old.png -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/heart_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/heart_animation.gif -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/pagination_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/pagination_animation.gif -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/slack_task.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/slack_task.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/immutable-wedding-epilogue/vedio_heart_effect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/immutable-wedding-epilogue/vedio_heart_effect.gif -------------------------------------------------------------------------------- /content/blog/essay/images/native_dictionary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/native_dictionary.png -------------------------------------------------------------------------------- /content/blog/essay/images/non-major-developers-are-no-different.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/non-major-developers-are-no-different.png -------------------------------------------------------------------------------- /content/blog/essay/images/simple_software.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/simple_software.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/slide_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/slide_0.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/slide_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/slide_1.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/slide_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/slide_2.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/slide_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/slide_3.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/slide_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/slide_4.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/the-secret-to-netflix-growth/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/the-secret-to-netflix-growth/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/thumbnail-good-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/thumbnail-good-code.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/00.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/01.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/02.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/03.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/04.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/05.jpg -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/06.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/06.jpeg -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/first_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/first_title.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/my-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/my-github.png -------------------------------------------------------------------------------- /content/blog/essay/images/what-i-learn-150/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/essay/images/what-i-learn-150/question.png -------------------------------------------------------------------------------- /content/blog/essay/non-major-developers-are-no-different.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 비전공자 개발자도 다르지 않아요 3 | date: 2020-12-12 20:12:32 4 | category: essay 5 | thumbnail: './images/non-major-developers-are-no-different.png' 6 | --- 7 | 8 | ![image](./images/non-major-developers-are-no-different.png) 9 | 10 | ⚠️ 이 글은 철저히 개인적 관점에서 작성했으며, 특정 단체나 개인을 타깃으로 하는 글이 아닙니다. 짧은 경험에서 적은 글이기 때문에 보시는 분에 따라 불편하신 부분이 있더라도 너른 양해 부탁드립니다. 11 | 12 | ## 들어가며 13 | 14 | 이 글은 개발을 시작할 때 '비전공자여서' 가질 수 있을 막연한 두려움이나 오해에 관한 개인적 생각을 적은 글이다. 본문에서 언급하게 될 CS지식은 모든 개발자 커리어에서 가져가야 할 부분이다. 이 글에서 말하고자 하는 부분은 CS 지식이 중요하지 않다는 것이 아니라, **이 지식을 배우는 시점과 접근 방법**에 관한 내용이다. 15 | 16 | 개발 공부를 시작하는 단계에서 "저는 비전공자인데, 무엇부터 하면 좋을까요?" 등의 질문을 심심찮게 많이 볼 수 있고, 교육 프로그램 등에서도 "비전공자를 위한 개발자 교육과정"과 같은 타이틀을 내거는 경우가 많다. 혹은, 채용공고에서 "컴퓨터 공학 관련 전공"이 자격요건에 명시된 경우도 있다. 17 | 18 | 전공, 비전공을 나누는 문장은 다음과 같은 전제를 내포하고 있다. 19 | 20 | - 전공자만 알 수 있는 영역을 알아야만 개발자가 될 수 있다. 21 | - 전공자와 비전공자는 같은 개발 지식을 받아들이는데 차이가 있을 것이다. 22 | 23 | ## 오해 1. 전공자만 알 수 있는 영역을 알아야만 한다 24 | 25 | 우선 용어에 대한 정의가 필요하다. `전공자만 알 수 있는 영역` 이 무엇일까? 문장을 쓴 사람의 의도를 정확히 파악할 수는 없겠지만, 짐작해보자면 '운영체제, 네트워크, 자료구조'와 같은 컴퓨터공학 전공 수업 지식을 일컫는 말이 아닐까 싶다. 26 | 27 | 위에서 언급한 CS지식이 개발자에게 중요하지 않다는 것이 아니다. 오히려 짧은 경력에서 되돌아봤을 때, '그때 수업을 좀더 열심히 들을걸..'하는 후회가 될 정도로 중요한 지식이다. 28 | 29 | ### 필요한 지식은 때에 따라 다르다 30 | 31 | 개발 영역마다 다를 수 있지만, 컴퓨터 공학 커리큘럼에서 배우는 전공 지식을 **모두 활용해야만 개발을 시작할 수 있는 것은 아니다.** 시작하는 단계에서는 변수나 함수의 의미에 대해서 이해하고, 내가 작성하는 코드에 대한 고민하고 여러 가지 문제를 해결하는 것에 집중하는 것이 좀 더 의미 있을 수 있다. 32 | 33 | 당장 내가 만나는 문제들을 해결하는 데 사용 되지 않는 지식은 창고 속 오래된 물건처럼 차츰 그 존재와 내용이 희미해질 것이다. 34 | 35 |
36 |

37 | 지식이 왜, 언제, 어떻게 쓰이는지 아는 것이 중요하다고 생각한다. ‘필요할 것 같아서’가 아니라, 이 상황을 해결하는 데에 부족했던 지식을 채우기 위해 공부하는 것이 나에겐 공부 동기가 되었다. 38 |

39 |
40 | 41 | 42 | https://so-so.dev/essay/no-silver-bullet/ 43 | 44 | 45 |
46 |
47 | 48 | 문제를 해결하는 과정에서, 혹은 주위 환경을 통해 직간접적으로 접하게 되는 상황들에서 특정 지식이 필요하다면 그때 배워도 늦지 않다. 무엇이 필요할지 모르니 모든 것을 창고에 넣어 두는 지식보다는 내가 맞닥뜨린 상황을 해결하면서 얻게 되는 지식이 강렬하게 바로 '내 것'이 될 것이다. 49 | 50 | 가령, 성능 개선을 하기 위해 Waterfall차트를 살펴보고 Response Header를 살펴보면서 만날 수 있는 단어들에 대해 이해하고 싶어 네트워크 지식을 찾아볼 때 배우는 것도 늦지 않으며, 그 순간에 배우는 지식이 온전히 내 것이 될 확률이 높다고 생각한다. 51 | 52 | ### 필요한 지식은 분야마다 다르다 53 | 54 | 개발에는 '개발'이라는 한 단어로 묶기에는 많은 분야가 있다. 55 | 56 | 알고리즘을 예로 들자면, 내가 목표하는 분야나 서비스가 알고리즘을 바로 활용하는 분야라면 이 지식은 바로 내 것이 되어야 하지만, 그렇지 않다면 다른 지식을 먼저 공부해도 괜찮다고 생각한다. 분야마다 **시작할 때 알고리즘 지식 필요 여부** 는 다를 수 있다는 뜻이다. 57 | 58 | 취업을 목표로 할 때에는 조금 다른 이야기가 되겠지만(회사마다 알고리즘 테스트를 보는 경우도 있으니) 개발 공부를 시작할 때 반드시 알고리즘을 알아야만 시작할 수 있다고 생각하지 않는다. 59 | 60 | > 물론 알고리즘을 풀다 보면 '코드 작성'과는 조금 친숙해질 수도 있겠다. 하지만 알고리즘 문제보다는 다양한 사이드 프로젝트를 해보면서 얻을 수 있는 '친숙함'이 더 크다고 생각한다. 61 | 62 | 알고리즘을 예시로 들었지만, 모든 지식을 공부한 다음 분야를 정하는 것이 아니라 내가 목표하는 방향에서 필요한 로드맵을 스스로 설계하는 과정이 필요하다고 생각한다. 63 | 64 | ## 오해 2. 전공자와 비전공자는 이해 속도에 차이가 있을 것이다 65 | 66 | 여러 기술 강의에서 "비전공자를 대상으로"하는 이유에 이런 생각이 있지 않을까 싶다. 아무래도 비전공자가 접하기 어려운 용어인 `변수`나 `함수`의 개념에 대해 이해하기 어려워할 것이며, 모든 흐름을 '천천히' 설명해주어야 한다고 생각하는 것 같다. 67 | 68 | 결론적으로 위 말은 틀린 말도, 맞는 말도 아니다. 무엇을 이해하는 속도는 사람마다 다르다. 전공자나 비전공자 모두 개발에서 필요한 개념을 처음 접하게 되는 순간이 있고, 이를 이해하는 속도는 **사람마다 다르다.** 69 | 70 | 전공자라고 해서 누구나 특정 용에 대해 어려운 용어를 사용하며 설명하는 것을 바로 이해하는 것은 아니며, 비전공자라고 해서 한없이 풀어서 설명해야만 이해할 수 있는것이 아니다. 개개인이 가지고 있는 **경험이나 성향에 따라 다를 수 있는 부분이 전공/비전공 프레임으로 나뉘는 것이 많이 아쉽다.** 71 | 72 | ## 오해 3. 비전공자 출신 개발자는 대단하다(?) 73 | 74 | 유투브나 블로그 등에서 "비전공자 **출신**이 어떻게 개발자가 되었는지"에 관해 설명하는 컨텐츠를 많이 찾아볼 수 있다. 75 | 76 | ![native_dictionary](./images/native_dictionary.png) 77 | 78 | 아무렇지 않게 사용하는 '출신'이라는 단어의 원래 뜻은 다소 폭력적이다. '비전공자'가 '신분'이 될 수 있을까? 개발과 아무 관련 없는 분야에서 경험을 쌓다가 개발자 커리어를 시작하는 단계에서의 막막함이나 경험을 담는 것이 목적일 수 있지만, 아무렇지 않게 사용하는 이 단어가 차별 프레임에 일조하고 있는 것은 아닌지 돌아볼 필요가 있다. 79 | 80 | 비전공에서 개발자가 된 분들의 노력을 비하하거나 대단하지 않다는 것이 아니다. 그 노력들은 매우 대단하고 가치있는 일들이지만 새롭게 개발자를 시작하는 분들이 이 단어로 막연한 두려움을 가질 필요는 없다는 뜻이다. 81 | 82 | **비전공자이기 때문에 못 하는 일과 전공자이기 때문에 처음부터 잘하는 일은 없다.** 83 | 84 | ## 마무리 85 | 86 | 이 글은 모든사람의 상황을 대변하지 못하며, 그저 주변에서 볼 수 있었던 몇 가지 상황에 관한 짧은 단상이고 **두려움** 에 대한 토막글이다. 시작할 때 가질 수 있는 막연한 두려움이 무력감이 된다면 발목에 모래주머니를 차고 시작하는 것과 다르지 않을 것이다. 87 | 88 | 다시 한번 이 글의 인트로를 첨부하며 글을 마친다. 89 | 90 | 이 글은 개발을 시작할 때 '비전공자여서' 가질 수 있을 막연한 두려움이나 오해에 관한 개인적 생각을 적은 글이다. 본문에서 언급하게 될 'CS지식'은 모든 개발자 커리어에서 가져가야 할 부분이다. 이 글에서 다루고자 하는 부분은 CS 지식이 중요하지 않다는 것이 아니라, 이 지식을 배우는 시점과 접근 방법에 대한 부분이다. 91 | -------------------------------------------------------------------------------- /content/blog/essay/retro2020.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Deploy 2020 3 | date: 2020-12-30 17:12:76 4 | category: essay 5 | thumbnail: './images/2020_retro/thumbnail.png' 6 | --- 7 | 8 | ![image-0](./images/2020_retro/thumbnail.png) 9 | 10 | 어김없이 회고 시즌이 돌아왔다. 작년에도 '시간이 참 빠르게 지나갔구나'라고 생각한 것 같은데, 올해가 더 그런 것 같다. 11 | 12 | 되돌아보고, 기록하고, 언젠가 이맘때의 나를 다시 보기 위해 회고 글을 작성한다. 13 | 14 | 나의 2020년은 어땠을까? 15 | 16 | - 아는 것보다 모르는 것이 많아졌다. 17 | - [Banksalad Product Language](https://blog.banksalad.com/tech/banksalad-product-language-ios/)(이하 BPL, 설명: Banksalad에서 사용하는 Design System)을 운영하며 많은 경험을 했고, 고민도 생겼다. 18 | - 개발자로서 내 역할에 대한 고민이 많았다. 19 | - FEConf 운영진으로 컨퍼런스를 개최했다. 20 | 21 | 2018년 12월, 처음 커리어를 시작해 이제 3년 차 개발자다. 어떤 사람의 경험을 나타내는 데에 있어 '연차'라는 지표는 극히 일부분만을 표현할 수 있지만, 그럼에도 매년 쌓여 가는 연차가 두렵다. 숫자는 눈에 보이지만 성장 속도는 눈에 보이지 않으니 내가 '3년 차 개발자'에 맞는 실력을 갖추고 있는지에 대한 두려움이 생기는 것 같다. 22 | 23 | 학생 때를 되돌아보면 3년차 개발자가 되었을 시점에는 막연하게 '무엇이든 빠르게 만들 수 있는 슈퍼 개발자'가 될 것 같다고 생각한 것 같다. 이제는 이런 추상적인 목표 말고, 매년 어떤 개발자가 되고 싶은지 다시 생각 해보려 한다. 24 | 25 | ## 모르는 것이 많아졌다. 26 | 27 | 작년 이맘때를 생각해보면, 이제 막 개발자로 시작해서 다양한 경험을 하며 경험이 늘어난다는 것에 뿌듯했던 것 같다. 내 앞의 모르는 것들을 배워 나가고 있었지만, 그때는 당장 마주해야 하는 문제들 위주로 격파해나가고 있었기 때문에 '내가 모르는 것'이 무엇인지 잘 몰랐다. 28 | 29 | 과거에 '이 정도면 괜찮지' 했던 것들이 다르게 보이기 시작했고, 과거에 생각했던 기준들은 많은 무지에서 세워졌음을 깨달았다. 30 | 31 | '그 기준'을 세울 때보다 많은 것들을 공부했고 경험했으니 어찌 보면 당연한 일이다. 다만, 그때는 기준이 바뀔 수 있다는 것을 경험해본 적이 없어서 내 의견에 너무 자신만만했던 것 같아 조금 부끄럽다. 32 | 33 | 내년에는 이런 키워드들에 대해 더 공부해보고 싶다. 34 | 35 | - 좋은 컴포넌트와 설계 36 | - Form Control 37 | - 접근성 38 | - Animation 39 | - Infra Structure 40 | - GraphQL(w. Relay) 41 | 42 | ## BPL 43 | 44 | Banksalad Product Language(이하 BPL)을 운영하고 있다. 올 해 진행했던 프로젝트 중 가장 많이 배웠고, 가장 많이 후회하며 가장 사랑하는 프로젝트이다. 45 | 46 | 가장 많이 후회한다고 적은 이유는, 좀 더 잘하고 싶어서다. 팀원들과 여러 좌충우돌을 겪으며 디자인 시스템을 만들어나가고 있는데, 처음에 했던 아쉬운 결정으로 아직도 예전 규칙에 대한 마이그레이션을 진행 중이다. 처음부터 잘하는 것은 힘들었겠지만, 돌이켜 생각해보면 많은 아쉬움이 남는다. 47 | 48 | **'좋지 않은 결정보다 나쁜 것은 느린 결정이고 느린 결정보다 나쁜 것은 번복되는 결정이다'** 49 | 50 | 세 가지 결정을 모두 내렸다. 구체적인 내용은 기회가 된다면 별도의 글에서 다룰 예정이라 간단하게만 말하자면, '규모가 커질 때 중요하게 여겨질 것들'에 대해 간과하고 있었던 기간이 길었다. 51 | 52 | 매 순간 좋은 결정을 내리기는 어렵겠지만, 어떤 결정을 내릴 때는 '모두가 사용하는 패키지의 중요성'과 '장기적인 모습'을 생각하며 밀도 높은 고민을 하려고 한다. 이런 고민을 함께해줄 동료들이 있어 다행이고, 감사하다. 53 | 54 | 기술적인 결정들 외에도, 라이브러리 운영에서 세심하게 신경 써야 하는 부분들의 중요성에 대해 몸소 느낄 수 있었다. 내 옆자리 동료, 우리 팀이 이 도구로 행복할까를 고민하는 일은 평소 하던 개발과 다른 차원의 시야를 요구했다. Breaking Release, 하위 호환성, Contributor에게 친절한 환경, DX(Developer Experience, 개발자 경험) 등의 키워드에 대해 처음 고민해 봤다. 55 | 56 | 기술적으로는 패키지 레벨의 컴포넌트가 지켜야 하는 규칙, 전역 컴포넌트 설계, 인터랙션 등을 경험 해보면서 프론트엔드 개발자로서 폭을 약간 넓힐 수 있었던 것 같다. 57 | 58 | ## 내 역할에 대한 고민 59 | 60 | 작년에는 어떻게 하면 내가 더 잘할 수 있을까에 대해 주로 고민했었다. 올해는 많은 시간 내가 무엇을 해야 할까 고민했다. 단순히 task가 아니라, 현재 있는 팀에서 필요한 일이나 역할 중 내가 잘 할 수 있는 부분이 무엇일까에 가깝다. 새로운 일과 더불어 내가 했던 일에 대해서도 다시 생각해보는 시간을 가졌었다. 61 | 62 | **"좋은 것(Good)은 지속하고, 나쁜 것(Bad) 것은 주저 없이 멈추는 것을 제안하는 역할"을 하고** 싶다. 여기서 적은 좋은 것은 지속하고 나쁜 것을 멈추는 것을 나 뿐만 아니라 팀원들과도 공유하고 싶다. 내년에는 팀원들과 티타임이나 상호 피드백을 주고받는 시간을 많이 가져 보고 싶다. 63 | 64 | 올해의 Good, Bad는 코드 리뷰를 예로 들 수 있겠다. 나는 코드 리뷰 과정에서 다른 관점으로 이리저리 생각하느라 리뷰 핑퐁이 늦어지거나 다소 철학적인 리뷰도 했었던 것 같다. 내 나름 리뷰에 많은 공을 들이다 보니 '일정 상 어렵다'라는 얘기가 서운했던 적도 있었고 그 순간들이 모여 부담이 됐다. 65 | 66 | 지금 생각해보니 '부담'은 불필요하게 스스로 만든 괴물이었고, '많은 리뷰'는 성장이었다. 코드리뷰에서 Good과 Bad를 뽑아보자면 이렇게 정리할 수 있을 것 같다. 67 | 68 | - Good: 다른 관점에서의 의견을 말하는 것에 주저하지 않기. 그 의견이 나의 무지 때문이었다면 배울 수 있는 기회가 될 것이고 아니라면 우리 모두에게 한번 더 고민하는 시간이 될것이다. 문제를 다른 시각으로 바라봤을 때 얻을 수 있는 것들이 있다고 생각한다. 69 | - Bad: '내가 공들였기 때문에' 속상해하기. [상자 밖에 있는 사람](http://www.yes24.com/Product/Goods/11520753)의 문장을 빌리자면, 나는 상자 안에 있었던 것 같다. 같은 행동을 하더라도, 상자 안에서('나'를 중심으로 생각하는 것) 하는 것을 멈추려 한다. 70 | 71 | ## FEConf2020 at Home 72 | 73 | 개발 커뮤니티가 실천하는 공유로 많은 지식과 도움을 받았기 때문에 어떤 형태로든 커뮤니티의 발전과 운영에 도움이 되고 싶어 2018년부터 FEConf에 참여하고 있다. 처음엔 자원 봉사자로, 그 다음은 발표자료, 올 해는 운영진으로 참여했다. 74 | 75 | [FEConf2020](https://2020.feconf.kr/)을 준비하면서, 긍정적인 에너지를 가진 분들과 함께 해서 즐거웠고 커뮤니티 운영의 고충도 느끼면서 많은 사람이 개발 생태계를 위해 내가 생각한 것보다 더 많이 노력하고 있다는 생각에 감사한 마음도 들었다. 함께 해주신 운영진분들과 좋은 발표를 준비해주신 연사자분들, 그리고 행사에 관심가져 주신 모든 참가자분들께 진심으로 감사드린다. 76 | 77 | 내년에는 꼭 코로나 종식으로 오프라인 행사가 가능해졌으면 좋겠다. 78 | 79 | ## 2021년의 나는 어떤 사람이 되고 싶은가? 80 | 81 | 옆자리 좋은 동료가 되고 싶다. 내가 지향하는 '좋은 동료'의 모습에는 서비스를 만들어가는 사람으로서 신뢰받으며 더 나은 서비스에 기여하고, 많은 기술적인 지식과 경험으로 동료들의 문제를 직접 해결해 줄 수 있는 모습, 그리고 서로의 고민을 나눌 수 있는 모습들이 포함된다. 82 | 83 | 여러 가지 목표가 있지만, 그중에서 적고 싶은 것은 Infra에 관한 공부이다. 내가 만든 웹 서비스가 배포되어 유저에게 전달되기 까지 필요한 요소들을 이해하고 직접 들여다볼 수 있는 개발자가 되고 싶다. 작년에도 비슷한 다짐을 한 것 같은데, 아직은 대략적인 흐름을 조금 이해했다 정도인 것 같다. 84 | 85 | > 회고 글에 짧게나마 '이해했다'라고 적기까지 [@JungWinter](https://github.com/JungWinter) 님께 많은 도움을 받았습니다. 감사합니다. 86 | 87 | 2021년의 회고를 쓸 때 담길 이야기가 궁금하다. 그 이야기를 만들어 가는 것은 나 자신이니 후회 없는 이야기를 쓰고 싶다. 88 | -------------------------------------------------------------------------------- /content/blog/essay/simple-software.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '[서평] 심플 소프트웨어' 3 | date: 2019-11-19 20:11:22 4 | category: essay 5 | thumbnail: './images/simple_software.jpg' 6 | --- 7 | 8 | ![image-thumbnail](./images/simple_software.jpg) 9 | 10 | 길벗 리뷰어로 선정되어 심플 소프트웨어 책을 받아보았다. 책 소개대로, 코드는 단 한줄도 등장하지 않는다. 저자의 경험에서 나오는 많은 생각들과 경험이 녹아있는 책이다. 나의 과거와 현재, 그리고 나의 미래를 상상하며 노트북 없이 밑줄을 그어가며 읽은 책이다. 11 | 좋았던 부분이 너무 많아 어떻게 서평을 써내려갈지 정말 많이 고민했다. 결국 각 Part별로 좋았던 부분을 적고 내 감상평을 추가하기로 했다. 12 | 13 | ## Chapter 2 올바른 자세 14 | '올바른 방법'은 보통 '발생할 수 있는 모든 상황에 대응하는 방법'을 의미한다. 15 | **올바른 방법을 모른다** 16 | 조금 더 공부하면 해결할 수 있을지도 모른다, 하지만 한계를 단정짓고 적당히 '이정도면 괜찮지'의 기준으로 코드를 작성해선 안된다. 나의 타협은 동료에게는 이해할 수 없는 context이고 이는 협업을 타협하는 방향이다. 17 | 18 | **너무 힘들다** 19 | 그럴 수도 있다. 나도 실제로 그런 마음이 들때도 있었다. 하지만 중요한 점은, 그래서 타협해도 되는 코드를 남겨도 된다는 것이 아니라, 일정이 부족하면 확보해야하며 올바르게 진행해야 한다. 나는 슈퍼개발자가 아니므로 올바른 방향에 힘이 드는것은 당연하다. 그래도 타협은 안된다. 20 | 21 | ## Chapter 4. 두 문장으로 요약한 소프트웨어 설계 22 | * 구현에 드는 수고보다 유지보수에 드는 수고를 줄이는 게 중요하다. 23 | * 유지보수에 드는 수고는 시스템의 복잡성에 비례한다. 24 | 25 | ## Chapter 8. 복잡성은 감옥이다. 26 | 실제로 그렇다. 나는 1인개발자가 아니기때문에 당연히 휴가에서는 자유롭고 싶다. 내 옆에 나와 함께하는 팀원이 있고 나도 다른 사람에게는 팀원이다. 내 코드는 내 소유가 아니다. 그러므로 누구든 쉽게 파악하고 수정할 수 있도록 작성되어야 한다. 이 단순한 원칙을 종종 잊는다. 27 | 28 | ## Chapter 12. 둘은 너무 많다 29 | 설계 작업을 진행할 때 따르는 규칙이 있는데, 이를 `둘은 너무 많다.` 라고 부른다. 30 | ``` 31 | 어느 수준까지 포괄해야하는지 부터 알아야 한다. 32 | 특정 목적에 부합하는 포괄적 솔루션을 설계한다. 33 | ``` 34 | 여러종류 포맷을 커버하기 위해 비슷한 로직을 처리해야하는 경우, **그 즉시 아무것도 복사하지 않고** 상위 클래스나 유틸리티 라이브러리를 만들어야 한다는 것이다. 35 | 36 | 이 규칙이 매우 와닿았는데, 결국 웹프론트에서 일어나는 일련의 작업들은 데이터를 view에 맞게 가공해서 보여주는 작업이 많기 때문에 조금씩 겹치는 로직들이 많기 때문이다. 37 | 이럴 경우 공통적으로 처리할 수 있는 util함수를 만드는데에 있어, **이 함수는 어디서든, 범용적으로 설계될 수 있도록** 가능한 많이 생각해야 한다고 생각한다. 38 | 39 | ### 리팩토링 40 | ``` 41 | 하나로 통합해야 하는 구현체가 많을 때는 한번에 통합하는 구현체를 두개로 제한하는 것부터 시작한다. 42 | ``` 43 | 리팩토링의 시작은 거창하지 않아야 한다는데에 동의한다. 리팩토링을 할때, ‘어디서부터 해야하는지, 현상파악 후 고치는데’까지 너무 막막했던 경험이 있다. 작은 단위의 함수부터 ‘작더라도 주기적’으로 진행해보자라는 마음을 갖는것이 **지속가능한 리팩토링**이라는 관점에 매우 동의한다. 44 | 45 | ## Chapter 15. 버그의 원인 46 | ``` 47 | 무슨 용도인지 적혀있지 않은 버튼이 수백만 개 붙어있는 상자는 바르게 사용할 방법이 없다. 48 | ``` 49 | 버그의 원인이 ‘복잡성’에서 온다고 말하고 있다. 사실 이 맥락에는 어느정도 동의하는 부분인데(버그에는 단순 휴먼에러부터, 예측할 수 없는 다른원인까지.. 원인은 많다고 생각한다.) 최소한 복잡성이 낮을수록 디버깅이 쉬울것은 자명하다고 생각한다. 50 | 51 | 나에게 단순한 것은 어쩌면 `내가 짜서`일 가능성도 높고, 동료가 읽는 상황을 염두해둬야 좋은 코드가 된다고 생각한다. 52 | > 개인적인 경험으로는 최근 ‘깔끔해보이는 코드 vs 읽기 쉽지만 조금 중복이 있는코드’에서 고민한적이 있는데, 물론 우선은 내가 코딩실력이 부족해서이겠지만.. 의식적으로 ‘읽기쉽지만 조금 중복이 있는 코드’를 선택해야한다고 생각했다. 53 | > 나는 생각보다 ‘깔끔해보이는 코드’에 잘 매료된다. 54 | 55 | 이 Chapter의 마지막은 쉬워보이지만 잘 간과하는 두 문장이었다. 56 | 1. 코드가 단순할수록 버그가 줄어들 것이다. 57 | 2. 프로그램의 모든 것이 **단순해지도록** 늘 노력하라. 58 | 59 | ## Chapter 18~19. 생산성 60 | 생산성에 관한 이야기였다. 사실, ‘개발자의 생산성 측정’은 누구나 궁금해할법한 화제라고 생각해서 더 눈길이 갔다. 61 | 62 | 책을 읽으면서 팀내에 새로운 기술이나 구조를 도입하는 과정이 그려졌는데, 팀원들을 설득해나가는 과정이 사실적이면서 구체적이어서 좋았다. 63 | ``` 64 | 나의 편이 되어줄 아군 팀원을 모아야 하고, 65 | 그 기반에는 신뢰가 있어야 하며 변화에 '완벽'을 기하지 말것. 66 | ``` 67 | 모두 좋은 동료만 있는 조직일지라도, 계속 흘러가는 조직에서 변화는 점진적이어야 받아들이는데 지치지 않으며 그 방향이 지속가능하다고 생각한다. 68 | > ‘아군’ 이라는 어감이 다소 세게보일 수 있지만, 내 뜻에 동의하는 동료와 의견을 공고히 해나가는 과정이라고 받아들여졌다. 69 | 70 | 그리고, 또 이 Chapter에서 흥미로웠던 문장은 **리팩토링 작업을 통해 개발자 생산성이 어떻게 개선되었는지 보여주는 그래프를 만들겠다고 함부로 약속하지말라.** 였다. 71 | 어려운 부분에 대한 ‘공표’보다는 ‘지속적 제안’으로 팀 문화가 리팩토링에 젖어들도록 해야한다. 72 | > 책에서는 ‘이 기능을 좀더 쉽게 작성하려면 리팩토링을 해야해요.’ 라는 제안ㅇ르 시작으로 가능할때마다 리팩토링을 제안하는것을 권고하고 있다. 73 | 74 | 이후 ‘생산성을 어떻게 측정할까?’대목은 사실 와닿지 않았다. 조직에 대한 개선이나 방향은 좋았지만 생산성 측정의 HowTo를 얻을 수는 없었다. 어려운 분야이기도 하고, 조직마다, 그리고 각 조직의 서비스마다 다를테니 이는 어쩔 수 없는 부분인것 같기도 하다. 75 | 76 | ## Chapter 20. 소프트웨어 회사에서 코드 복잡성을 다루는 방법 77 | 코드에서 감정적으로(이 대목을 많이 강조했다.) 짜증나거나 두려운 부분을 찾고, 그 문제들을 나열한 다음 우선순위에 맞게 헤쳐나가는 것을 말하고 있다. 78 | 79 | 얼마 전 구조변경에 대한 [발표](https://speakerdeck.com/soyoung210/heonjibjulge-saejibdao-riaegteu-peurojegteu-gujojojeong)를 한적이 있어, 더욱 재밌었던것 같다. 80 | 81 | ## Chapter 35. ‘아니요’의 힘 82 | 협업에서 가장 중요한 점은 협업이라고 생각했고, 그 관점에서 ‘soft하게 말하기’에 정말 많은 노력을 기울였던 적이 있다. 지금 생각해보면 과한 수사어구는 맥락을 흐리게 되고, 상대방이 생각했을 때의 ‘애매한 부정’은 가치판단에 어려움을 줄 수 있다. 83 | ‘협업’이 중요하기 때문에, 나는 부정적 의견일지라도 확실하게 전달할 필요가 있다는데에 매우 공감한다. 84 | 85 | 하지만, 이 책에도 나오듯 위의 말이 곧 ‘무례하세요’라는 말은 절대 아니다. 86 | 당연히 나의 동료들은 틀린제안만 하지 않으며 거절해야하는 제안일지라도 좋은부분과 그렇지 않은 부분을 구별해서 피드백을 주어야 한다. 설령 전부 나쁠지라도, 그 문제에 대해 고민을 했을 동료의 시간을 생각하며 그에 대한 감사를 표하는것은 협업에서 당연히 지켜야 할 예의이다. 87 | 88 | ## Chapter 36. 프로그래머가 개떡 같은 이유 89 | 꽤 자극적인 제목이지만 ‘공부를 꾸준히 합시다’에 관한 글이라고 보면 될것 같다. 그 세부적인 내용은 아직 내가 느끼지 못한 다소 교과서적인 이야기처럼 들렸으나, 여기서 기억해두고 싶은 부분은 이 대목이다. 90 | ``` 91 | 누구나에게 항상 더 배울게 있다는 생각, 92 | 지식과 실습이 기술을 익히는 열쇠라는 생각, 93 | 무언가 모른다는걸 알고 그것을 익히기 위해 지식과 실습을 기울여야 한다는 생각 94 | ``` 95 | 96 | ## 총평 97 | 곰곰히 생각해보며 가볍게 읽기 좋은 책이다. 다만 모든 근본적인 것에 관한 책이 그렇듯, 의식적인 학습이 필요하다. 98 | 그냥 지나치기에는 아쉬운 내용들(생산성, 복잡성, ‘아니요’의 힘 등..)이 많다. 99 | 전반적으로 좋은 내용이었지만, 중간에 등장했던 보안 등의 이야기는 ‘왜 여기에 나왔지..’ 100 | 싶은 부분이었다. 101 | -------------------------------------------------------------------------------- /content/blog/etc/images/googling/00.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/00.jpg -------------------------------------------------------------------------------- /content/blog/etc/images/googling/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/01.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/02.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/03.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/04.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/05.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/06.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/07.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/08.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/09.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/10.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/11.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/12.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/13.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/14.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/15.png -------------------------------------------------------------------------------- /content/blog/etc/images/googling/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/googling/16.png -------------------------------------------------------------------------------- /content/blog/etc/images/image-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/image-0.png -------------------------------------------------------------------------------- /content/blog/etc/images/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/image-1.png -------------------------------------------------------------------------------- /content/blog/etc/images/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/image-2.png -------------------------------------------------------------------------------- /content/blog/etc/images/image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/image-3.png -------------------------------------------------------------------------------- /content/blog/etc/images/image-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/etc/images/image-4.png -------------------------------------------------------------------------------- /content/blog/etc/official-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 공식문서에서 시작하기 3 | date: 2019-03-04 00:07:08 4 | category: etc 5 | thumbnail: './images/image-0.png' 6 | --- 7 | 8 | ![image-thumbnail](./images/image-0.png) 9 | 10 | **주의 : 공식문서를 읽지 않았다는 Blame 취지가 아닌, 생각보다 공식문서에 많은것이 담겨있다 라는 취지의 글입니다. (이소영이 생각하는 공식문서에 대해 이야기합니다.)** 11 | 12 | ## Why ? 13 | 14 | `공식문서` 를 잘 읽어보자 라는 말은 어쩌면 교과서 적이라고 할 수도 있다. 15 | 16 | > 적당히 구글링하면 stackoverflow가 친절한 해결책을 알려주는데..! 17 | > 하지만, 우선 잘 정리된 공식문서던 아니던, 공통적으로 **어떤 기능을 제공하는지 가장 빠르게 파악** 할 수 있다. 18 | 19 | - 나에게 필요한 기능 파악 20 | - 이 기능을 실제 코드로 어떻게 구현하는가에 대한 학습 21 | 22 | ## Let’s Read! 23 | 24 | 지금까지 사용했던 라이브러리 중 공식문서 덕을 본 것도 있고, 썩 도움을 받지 못했던 것도 있다. 25 | 26 | ### React 27 | 28 | ![image-react](./images/image-1.png) 29 | 30 | [React – A JavaScript library for building user interfaces](https://reactjs.org/) 31 | 우선, React 의 공식문서는 정말 읽기 편하다. 32 | 기본적인 개념에 대해서 소개하고, 초보자를 위한 튜토리얼부터 Advanced 사용성까지 고려하여 문서에 담아냈다. 33 | 34 | ![image-react2](./images/image-3.png) 35 | 36 | [State and Lifecycle – React](https://reactjs.org/docs/state-and-lifecycle.html) 37 | 처음 React를 배울 때 LifeCycle과 state, props에 대해 정말 많이 헷갈렸는데, 결국 이해된다고 생각하기 시작한 시점은 공식문서를 읽고난 다음부터가 아니었나 라는 생각이 든다. 🤔 38 | 39 | 사실, `리액트` 라는 키워드로 검색했을 때도 잘 번역된 한글문서가 많지만, 결국 저자에 의해 재해석되어 편집된 글이다. 40 | 리액트를 만든 사람이 어떤 것을 강조하고 싶었고, 사용자를 고려했을 때 어떤 오류가 있을 것 같다고 생각했는지 결국 직접 들어보고 싶지 않은가? 41 | **그렇다면 공식문서다.** 42 | 43 | 제작자 입장에서는 여러가지가 고려되어 있다. 44 | 45 | - component LifeCycle 과 State를 어떻게 묶어서 설명하면 좋을지. 46 | - 왜 state를 mutable하게 수정하는 것을 하면 안되는지 47 | - **제작자가 제안하는** 방법은 무엇인지 48 | - 기초를 익히기 위해서는 어떤 튜토리얼을 제공해야 하는지 49 | 50 | 등이 모두 고려된 문서가 reactjs.org 의 문서이다. 51 | 52 | > 결론 : React 공식문서는 잘 정리된 공식문서라고 생각합니다. 53 | 54 | ### Ant Design 55 | 56 | ![image-antd](./images/image-2.png) 57 | 58 | https://ant.design/ 59 | 앤트 디자인의 문서는 **정말 친절하다.** 60 | 61 | > 사실, 구글링해서 나오는 Example이 공식문서에 있는 case를 따라가지 못한다. 62 | > 비교할 수 없는 양과 퀄리티. 🤔 63 | 64 | 예를 들어, `Table` 이라는 컴포넌트(앤트디자인에서 제공하는 Table View) 를 사용한다고 했을 때, 생각할 수 있는 여러가지 디자인에 대해서 무려 예제코드!! 를 제공한다. 65 | 66 | 구현하고자 하는 기능에 대해서 비슷한 디자인 example을 찾은 후 약간의 custom만 하면 되는 형태이다. 67 | 이런 점이 무려 공식문서만 보면 해결된다. 68 | 69 | ### nodegit 70 | 71 | ![image-nodegit](./images/image-4.png) 72 | 73 | [API Docs](https://www.nodegit.org/api/) 74 | 앞선 두 가지 케이스는 정말 잘 정돈된 문서이고, 내 입장에서 좀 불친절했던 docs는 `nodegit` 이었다. 75 | 76 | > 결국 이렇게 저렇게 해결할수 없는 문제가 있어, 해당 레포에 issue rasing 하고 다른 라이브러리를 택했다. 77 | 78 | #### 좋았던 점 79 | 80 | 모든 공식문서가 그렇겠지만, 결국 공식문서를 본다 라는 것은 어떤 기능을 제공하는지 파악하기 위함이다. 81 | API Docs를 처음 보았을 때, 이 api가 `async` 인지 `sync` 인지까지 명시한 이 문서는 어떤 면에서는 꽤 친절하다고도 할 수 있겠다. 82 | 83 | #### 아쉬웠던 점. 84 | 85 | usage에 대한 언급이 없다. 86 | 87 | 가령, [CloneOptions](https://www.nodegit.org/api/clone_options/#checkoutBranch) 에서 checkout-branch API 를 살펴본다고 했을 때, 실질적인 사용코드를 제공하지 않아서 추상적으로 느껴졌다. 88 | 들어가는 Parameters 만 보고 해당 사용을 유추해야 하고, 이 과정에서 잘못사용하면 버그가 발생할 확률이 높다. 89 | 90 | 그리고, 버그가 발생했을 때 해결하는 과정 또한 오래걸린다. 91 | 92 | ## 🚕 정리 93 | 94 | 작성하다보니 약간 `어떤 공식문서가 좋아요` 의 뉘앙스가 된것을 지울수는 없지만, 95 | 말하고자 했던 핵심은 **내가 쓰는 라이브러리에 대한 기본적 파악을 공식문서에서 부터 출발** 해야 한다는 것이었다. 96 | 97 | 다른 방법으로 문제를 해결하게 되더라도, 공식문서에서 제공하는 기본적인 내용을 숙지한 상태에서 리서치가 이루어져야 한다. 98 | 99 | > 기본적이 정보로 해결할 수 없었던 부분에 대해 질문한다면, 질문하는 횟수나 시간이 현저하게 줄어들 것 같다고 생각한다. 100 | -------------------------------------------------------------------------------- /content/blog/k8s/images/image_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_0.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_1.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_10.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_11.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_12.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_13.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_14.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_15.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_2.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_3.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_4.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_5.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_6.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_7.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_8.png -------------------------------------------------------------------------------- /content/blog/k8s/images/image_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/image_9.png -------------------------------------------------------------------------------- /content/blog/k8s/images/thumbnail.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/k8s/images/thumbnail.jpeg -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/babel-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/babel-example.png -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/github-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/github-secret.png -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/import-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/import-error.png -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/lerna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/lerna.png -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/package-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/package-name.png -------------------------------------------------------------------------------- /content/blog/pattern/images/monorepo/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/monorepo/thumbnail.png -------------------------------------------------------------------------------- /content/blog/pattern/images/redux_saga_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/redux_saga_flow.png -------------------------------------------------------------------------------- /content/blog/pattern/images/saga_event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/saga_event.png -------------------------------------------------------------------------------- /content/blog/pattern/images/saga_event_rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/saga_event_rollback.png -------------------------------------------------------------------------------- /content/blog/pattern/images/saga_orchestration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/saga_orchestration.png -------------------------------------------------------------------------------- /content/blog/pattern/images/saga_orchestration_rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/saga_orchestration_rollback.png -------------------------------------------------------------------------------- /content/blog/pattern/images/sample_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/sample_service.png -------------------------------------------------------------------------------- /content/blog/pattern/images/sample_service_sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/sample_service_sequence.png -------------------------------------------------------------------------------- /content/blog/pattern/images/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/pattern/images/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/analyze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/analyze.png -------------------------------------------------------------------------------- /content/blog/react/images/bundle-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/bundle-result.png -------------------------------------------------------------------------------- /content/blog/react/images/client-bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/client-bundle.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-beyond-code/modal_popover_guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-beyond-code/modal_popover_guide.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-beyond-code/orbit_model_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-beyond-code/orbit_model_color.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-beyond-code/rogers-diffusion-of-innovation-curve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-beyond-code/rogers-diffusion-of-innovation-curve.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-beyond-code/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-beyond-code/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/leftSlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/leftSlot.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/mulit_select_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/mulit_select_search.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/notion_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/notion_page.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/notion_page_not_use.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/notion_page_not_use.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/portalContainer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/portalContainer.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/references.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/references.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/select_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/select_example.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/select_trigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/select_trigger.jpg -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/select_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/select_trigger.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/state.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/timepicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/timepicker.png -------------------------------------------------------------------------------- /content/blog/react/images/design-system-decision-record/timepicker_new_option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/design-system-decision-record/timepicker_new_option.png -------------------------------------------------------------------------------- /content/blog/react/images/form-handling/complex-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/form-handling/complex-form.png -------------------------------------------------------------------------------- /content/blog/react/images/form-handling/controlled_uncontrolled_rerender.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/form-handling/controlled_uncontrolled_rerender.gif -------------------------------------------------------------------------------- /content/blog/react/images/form-handling/input-state-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/form-handling/input-state-update.png -------------------------------------------------------------------------------- /content/blog/react/images/form-handling/simple-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/form-handling/simple-login.png -------------------------------------------------------------------------------- /content/blog/react/images/form-handling/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/form-handling/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/jsx-new-transform/react-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/jsx-new-transform/react-17.png -------------------------------------------------------------------------------- /content/blog/react/images/jsx-new-transform/react-reference-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/jsx-new-transform/react-reference-error.png -------------------------------------------------------------------------------- /content/blog/react/images/jsx-new-transform/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/jsx-new-transform/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/react/images/jsx-new-transform/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/jsx-new-transform/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/1pw_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/1pw_info.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/headlessui.dev_react_combobox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/headlessui.dev_react_combobox.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/headlessui.dev_react_listbox (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/headlessui.dev_react_listbox (1).png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/headlessui.dev_react_listbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/headlessui.dev_react_listbox.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/hmm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/hmm.gif -------------------------------------------------------------------------------- /content/blog/react/images/make-select/multi_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/multi_select.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/select_autofill.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/select_autofill.gif -------------------------------------------------------------------------------- /content/blog/react/images/make-select/select_autofill.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/select_autofill.mp4 -------------------------------------------------------------------------------- /content/blog/react/images/make-select/select_autofill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/select_autofill.png -------------------------------------------------------------------------------- /content/blog/react/images/make-select/select_keyboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/select_keyboard.gif -------------------------------------------------------------------------------- /content/blog/react/images/make-select/select_keyboard.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/select_keyboard.mp4 -------------------------------------------------------------------------------- /content/blog/react/images/make-select/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/make-select/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/react/images/node-modules-splitting/after_bundle_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/node-modules-splitting/after_bundle_output.png -------------------------------------------------------------------------------- /content/blog/react/images/node-modules-splitting/before_bundle_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/node-modules-splitting/before_bundle_output.png -------------------------------------------------------------------------------- /content/blog/react/images/node-modules-splitting/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/node-modules-splitting/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/org-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/org-network.png -------------------------------------------------------------------------------- /content/blog/react/images/org_to_user_no_split.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/org_to_user_no_split.gif -------------------------------------------------------------------------------- /content/blog/react/images/org_to_user_split.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/org_to_user_split.gif -------------------------------------------------------------------------------- /content/blog/react/images/react-lazy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/react-lazy.png -------------------------------------------------------------------------------- /content/blog/react/images/react-loadable-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/react-loadable-issue.png -------------------------------------------------------------------------------- /content/blog/react/images/scoped-context/dialog-alertdialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/scoped-context/dialog-alertdialog.jpg -------------------------------------------------------------------------------- /content/blog/react/images/scoped-context/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/scoped-context/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/react/images/ssr-area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/ssr-area.png -------------------------------------------------------------------------------- /content/blog/react/images/ssr-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/ssr-first.png -------------------------------------------------------------------------------- /content/blog/react/images/ssr-full-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/ssr-full-content.png -------------------------------------------------------------------------------- /content/blog/react/images/test1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/test1.gif -------------------------------------------------------------------------------- /content/blog/react/images/test2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/test2.gif -------------------------------------------------------------------------------- /content/blog/react/images/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/thumbnail.png -------------------------------------------------------------------------------- /content/blog/react/images/user--cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/user--cache.png -------------------------------------------------------------------------------- /content/blog/react/images/user-ssr-data-fetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/user-ssr-data-fetch.png -------------------------------------------------------------------------------- /content/blog/react/images/user-ssr-no-cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/user-ssr-no-cache.png -------------------------------------------------------------------------------- /content/blog/react/images/user-ssr-no-data-fetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/react/images/user-ssr-no-data-fetch.png -------------------------------------------------------------------------------- /content/blog/react/ssr-0-intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '[SSR] 0. 들어가면서' 3 | date: 2019-11-17 16:00:09 4 | category: react 5 | thumbnail: './images/thumbnail.png' 6 | --- 7 | 8 | ![image-thumbnail](./images/thumbnail.png) 9 | 10 | 이 튜토리얼은 React에 ServerSideRendering, 그리고 Code Splitting을 적용하는 과정을 소개합니다. 11 | 12 | > 모든 코드는 [GitHub](https://github.com/soYoung210/react-ssr-code-splitting) 에 있으니 **각 단계별 branch에서 코드를 살펴보세요!** 13 | 14 | React에 SSR을 도입한다면, [Next.js](https://nextjs.org/)도 좋은 선택일 수 있습니다. 하지만, 이 글은 프레임워크가 아닌 순수하게 React에 CodeSplitting과 SSR을 얹어가는 과정을 다룹니다. 15 | 16 | 이 시리즈는 다음 버전을 기반으로 작성되었습니다. 17 | 18 | ```json 19 | { 20 | "typescript": "3.6.2", 21 | "@loadable/component": "5.10.3", 22 | "@loadable/server": "5.10.3", 23 | "react": "16.8.6", 24 | "react-router-config": "5.1.1", 25 | "react-router-dom": "5.0.1", 26 | "redux": "4.0.4", 27 | "redux-observable": "1.1.0" 28 | } 29 | ``` 30 | 31 | ## Table of Contents 32 | 33 | ### [1. Code Splitting](https://so-so.dev/react/ssr-1-codesplitting/) 34 | 35 | - 라이브러리 선택 36 | - Template HTML설정 37 | - Config설정 38 | - View코드 작성 39 | - 몇 가지 생각 40 | 41 | ### [2. SSR - Basic](https://so-so.dev/react/ssr-2-ssr---basic/) 42 | 43 | - 구조 정리 44 | - server에서 Rendering 45 | - 확인 46 | 47 | ### [3. SSR - Data Fetch](https://so-so.dev/react/ssr-3-ssr-data-fetch/) 48 | 49 | - react-router-config로의 변경 50 | - server/app.tsx 수정 51 | - Client에 초기 store값 전달 52 | - Server에서 받아온 데이터를 이용해서 Store초기화 하기 53 | 54 | ### [4. UX관점에서의 SSR](https://so-so.dev/react/ssr-4-ux-ssr/) 55 | 56 | - 사용자 관점 57 | - 단점만 있는 것은 아니다. 58 | - 이 튜토리얼을 끝마치며 59 | -------------------------------------------------------------------------------- /content/blog/react/ssr-4-ux-ssr.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '[SSR] 4. UX관점에서의 SSR' 3 | date: 2019-12-13 22:12:74 4 | category: react 5 | thumbnail: './images/thumbnail.png' 6 | --- 7 | 8 | ![image-thumbnail](./images/thumbnail.png) 9 | 10 | SSR을 이용해서 두 가지 상황을 구현해보았습니다. 두 번째 글이 첫 번째보다 조금 어려웠다고 생각되는데요, 과연 어려운만큼 좋은 UX를 구현한것일까요? 11 | 12 | 제 대답은 `그렇지 않다.` 입니다. 13 | 14 | ## 사용자 관점 15 | 16 | ### Server에서 Data Fetch 17 | 18 | [3. SSR - Data Fetch](https://so-so.dev/react/ssr-3-ssr-data-fetch/)의 방법으로 요청했을 때 어떤 일이 벌어지는지 그림으로 살펴봅시다. 19 | 20 | ![user-ssr-data-fetch](./images/user-ssr-data-fetch.png) 21 | 사용자의 요청이 express에게 전달되고, api fetch후 contents를 그린 html을 Client에게 내려주기 전까지 **사용자는 흰 화면만 보게 됩니다.** 22 | 23 | api call이 오래 걸릴 경우 사용자가 흰 화면을 보는 시간은 그만큼 길어지게 됩니다. 이는 좋은 UX라고 보기 어렵습니다. 24 | 25 | > 컨텐츠가 담겨진 html자체를 캐싱처리 할 경우 이 속도가 빨라져 실제로 UX에 긍정적인 영향을 끼칠 가능성이 높습니다. 26 | > 하지만, 이번 튜토리얼에서는 관련 내용에 대해서는 다루지 않습니다. 27 | 28 | ### Server에서 빠르게 전달 29 | 30 | [2. SSR - Basic](https://so-so.dev/react/ssr-2-ssr---basic/)의 방법으로 변경해봅니다. 31 | server에서는 api호출을 수행하지 않고 client의 `Loader` 혹은 `header`영역만 그려서 빠르게 전달해줍니다. 이후 로직 처리는 client에 위임합니다. 32 | 33 | ![user-ssr-no-data-fetch](./images/user-ssr-no-data-fetch.png) 34 | 35 | 사용자는 빠르게 contents를 볼 수 있게 되었습니다. 그림에는 큰 글씨의 `Loading`으로 표현했지만, 스켈레톤 UI등을 활용하면 조금 더 나은 UX로 나아갈 수 있습니다. 36 | 37 | ### Server에서 Data Fetch - WebView 38 | 39 | 그리고, 웹뷰 상황에서 더 장점을 가집니다. 40 | 41 | ![user—no-cache](./images/user-ssr-no-cache.png) 42 | 43 | server에서 api요청을 처리하는 방법으로 구현할 시에는, Client에서 받는 것은 완성된 html이므로 캐싱이 적용되지 않습니다. 44 | 45 | ### Server에서 빠르게 전달 - WebView 46 | 47 | ![user—cache](./images/user--cache.png) 48 | 49 | 두 번째 방식으로 진행 시 client rendering에 필요한 일부 bundle을 받아오는 작업이 캐싱될 수 있습니다. 당연히, express에서 bundle을 받는것보다 빠르게 진행될 수 있습니다. 50 | 51 | ## 단점만 있는 것은 아니다 52 | 53 | 하지만, 마냥 단점만 있는것은 아닙니다. 위 상항을 다르게 이야기 해보면, Client에서는 **늘 express의 상황에만 의존하게 된다는 것입니다.** 한번, `Low tier 디바이스`의 상황을 가정해봅시다. 54 | 55 | **_Full Contents를 내려받는 방식_** 56 | 57 | 모든 요청과 api call이 express에서 이루어지므로, 유저가 컨텐츠를 받는 속도에서 변수는 오직 `네트워크 환경`과 express의 스펙입니다.(서버의 CPU등) 58 | express의 CPU보다 좋지 않은 CPU를 가진 디바이스에서는 기존의 방식보다 빠르게 컨텐츠가 로드 될 수 있습니다. 59 | 60 | **_SSR + CSR_** 61 | 62 | 컨텐츠를 내려 받는 속도에서 중요한 요소는 유저가 연결된 네트워크 환경과 디바이스 스펙입니다. 63 | 저사양의 디바이스에서는 두 가지 요소 모두 좋지 않으니 컨텐츠 로딩 속도가 매우 느립니다. 이 경우 express에서 모든 컨텐츠를 내려받는것이 좋습니다. 64 | 65 | ## 이 튜토리얼을 끝마치며 66 | 67 | SSR 튜토리얼이 끝났습니다. 68 | 프레임워크 없이 SSR을 적용하는 과정에서 많은 버그와 어려운 점을 만났는데, 같은 어려움을 겪고 계실 분들께 도움이 되었으면 좋겠습니다. 69 | 70 | 본 튜토리얼에 사용된 코드는 [여기](https://github.com/SoYoung210/react-ssr-code-splitting)에서 보실 수 있습니다. 71 | 피드백은 댓글이나 깃헙 이슈로 남겨주시면 감사하겠습니다.🙂 72 | -------------------------------------------------------------------------------- /content/blog/tool/rollup/images/rollupjs-config/cjs-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/rollup/images/rollupjs-config/cjs-error.png -------------------------------------------------------------------------------- /content/blog/tool/rollup/images/rollupjs-config/include_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/rollup/images/rollupjs-config/include_card.png -------------------------------------------------------------------------------- /content/blog/tool/rollup/images/rollupjs-config/no_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/rollup/images/rollupjs-config/no_card.png -------------------------------------------------------------------------------- /content/blog/tool/rollup/images/rollupjs-config/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/rollup/images/rollupjs-config/thumbnail.png -------------------------------------------------------------------------------- /content/blog/tool/webpack/images/node-modules-splitting/after_bundle_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/webpack/images/node-modules-splitting/after_bundle_output.png -------------------------------------------------------------------------------- /content/blog/tool/webpack/images/node-modules-splitting/before_bundle_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/webpack/images/node-modules-splitting/before_bundle_output.png -------------------------------------------------------------------------------- /content/blog/tool/webpack/images/node-modules-splitting/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/webpack/images/node-modules-splitting/thumbnail.png -------------------------------------------------------------------------------- /content/blog/tool/webpack/images/whats-diff-in-webpack5/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/tool/webpack/images/whats-diff-in-webpack5/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/apple_touch_tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/apple_touch_tag.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/activate.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/commit.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composite_after_flow.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composite_after_flow.jpeg -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composite_after_paint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composite_after_paint.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composite_layer_timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composite_layer_timeline.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composite_only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composite_only.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composition.gif -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/composition_forest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/composition_forest.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/css_to_style_sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/css_to_style_sheet.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/display.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/draw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/draw.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/enhance_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/enhance_result.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/implicit-compositing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/implicit-compositing.gif -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/layer_memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/layer_memory.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/layer_promotion_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/layer_promotion_result.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/layout.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/layout_cost.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/layout_cost.gif -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/non-fast-scroll-region-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/non-fast-scroll-region-all.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/non-fast-scroll-region.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/non-fast-scroll-region.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/non_composition_raster.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/non_composition_raster.gif -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/paint_invalidation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/paint_invalidation.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/parsing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/parsing.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/property_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/property_tree.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/raster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/raster.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/reflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/reflow.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/repaint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/repaint.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/repaint_layer_timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/repaint_layer_timeline.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/style.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/style_calc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/style_calc.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/thumbnail2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/thumbnail2.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/tilling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/tilling.png -------------------------------------------------------------------------------- /content/blog/web/images/browser-rendering-performance/메인플로우.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/browser-rendering-performance/메인플로우.png -------------------------------------------------------------------------------- /content/blog/web/images/charset-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/charset-1.png -------------------------------------------------------------------------------- /content/blog/web/images/charset-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/charset-2.png -------------------------------------------------------------------------------- /content/blog/web/images/cookie/first-vs-third.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/cookie/first-vs-third.png -------------------------------------------------------------------------------- /content/blog/web/images/cookie/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/cookie/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/cookie/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/cookie/twitter.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/cssom-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/cssom-result.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/emotion-benchmark-result-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/emotion-benchmark-result-1.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/emotion-benchmark-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/emotion-benchmark-result.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/emotion-to-cssvar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/emotion-to-cssvar.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/linaria-dynamic-style-poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/linaria-dynamic-style-poster.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/linaria-dynamic-style.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/linaria-dynamic-style.mp4 -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/linaria-sc-performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/linaria-sc-performance.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/stitches-atomic-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/stitches-atomic-class.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/stitches-css-inject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/stitches-css-inject.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/styled-components-critical-css-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/styled-components-critical-css-result.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/styled-components-dynamic-style-poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/styled-components-dynamic-style-poster.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/styled-components-dynamic-style.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/styled-components-dynamic-style.mp4 -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/thumbnail2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/thumbnail2.png -------------------------------------------------------------------------------- /content/blog/web/images/css-in-js/what-is-css-in-js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/css-in-js/what-is-css-in-js.png -------------------------------------------------------------------------------- /content/blog/web/images/description_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/description_example.png -------------------------------------------------------------------------------- /content/blog/web/images/facebook-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/facebook-large.png -------------------------------------------------------------------------------- /content/blog/web/images/facebook-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/facebook-small.png -------------------------------------------------------------------------------- /content/blog/web/images/favicon_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/favicon_example.png -------------------------------------------------------------------------------- /content/blog/web/images/fifth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/fifth.png -------------------------------------------------------------------------------- /content/blog/web/images/first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/first.png -------------------------------------------------------------------------------- /content/blog/web/images/fourth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/fourth.png -------------------------------------------------------------------------------- /content/blog/web/images/lang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/lang.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator1.gif -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator2.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator3.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator4.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator5.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator6-1.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator6.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator7.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator8.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/navigator9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/navigator9.png -------------------------------------------------------------------------------- /content/blog/web/images/navigator/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/navigator/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/og-image.png -------------------------------------------------------------------------------- /content/blog/web/images/search_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/search_result.png -------------------------------------------------------------------------------- /content/blog/web/images/second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/second.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/background-sync-example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/background-sync-example1.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/background-sync-example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/background-sync-example2.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/background-sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/background-sync.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/interaction-with-cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/interaction-with-cache.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/precache-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/precache-build.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/precache-manifest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/precache-manifest.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/push-notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/push-notification.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/swUrl-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/swUrl-build.png -------------------------------------------------------------------------------- /content/blog/web/images/service-worker/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/service-worker/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/sixth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/sixth.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/bootstrap_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/bootstrap_example.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/card_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/card_example.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/responsive_tailwind.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/responsive_tailwind.gif -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/search_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/search_example.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/search_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/search_result.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/tailwind/tw_macro_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tailwind/tw_macro_issue.png -------------------------------------------------------------------------------- /content/blog/web/images/third.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/third.png -------------------------------------------------------------------------------- /content/blog/web/images/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/thumbnail.png -------------------------------------------------------------------------------- /content/blog/web/images/thumbnail2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/thumbnail2.png -------------------------------------------------------------------------------- /content/blog/web/images/thumbnail_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/thumbnail_example.png -------------------------------------------------------------------------------- /content/blog/web/images/thumbnail_tag_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/thumbnail_tag_example.png -------------------------------------------------------------------------------- /content/blog/web/images/title_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/title_example.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/circular_reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/circular_reference.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/cjs_binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/cjs_binding.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/dead-code-elimination-vs-tree-shaking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/dead-code-elimination-vs-tree-shaking.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/esm_binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/esm_binding.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/esm_binding_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/esm_binding_update.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/global_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/global_share.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/module_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/module_record.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/node_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/node_tree.png -------------------------------------------------------------------------------- /content/blog/web/images/tree-shaking-module-system/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/tree-shaking-module-system/thumbnail.jpg -------------------------------------------------------------------------------- /content/blog/web/images/twitter-empty-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/twitter-empty-card.png -------------------------------------------------------------------------------- /content/blog/web/images/twitter-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/twitter-large.png -------------------------------------------------------------------------------- /content/blog/web/images/twitter-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/twitter-small.png -------------------------------------------------------------------------------- /content/blog/web/images/with-async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/with-async.png -------------------------------------------------------------------------------- /content/blog/web/images/with-defer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/with-defer.png -------------------------------------------------------------------------------- /content/blog/web/images/without-defer-async-body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/without-defer-async-body.png -------------------------------------------------------------------------------- /content/blog/web/images/without-defer-async-head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/without-defer-async-head.png -------------------------------------------------------------------------------- /content/blog/web/images/you-dont-know-polyfill/sokra_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/you-dont-know-polyfill/sokra_comment.png -------------------------------------------------------------------------------- /content/blog/web/images/you-dont-know-polyfill/test-node-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/you-dont-know-polyfill/test-node-result.png -------------------------------------------------------------------------------- /content/blog/web/images/you-dont-know-polyfill/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/content/blog/web/images/you-dont-know-polyfill/thumbnail.png -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | // custom typefaces 2 | require('typeface-noto-sans-kr') 3 | require('typeface-catamaran') 4 | 5 | // polyfill 6 | require('intersection-observer') 7 | 8 | const metaConfig = require('./gatsby-meta-config') 9 | 10 | exports.onInitialClientRender = () => { 11 | if (metaConfig.share.facebookAppId) { 12 | window.fbAsyncInit = function() { 13 | FB.init({ 14 | appId: metaConfig.share.facebookAppId, 15 | xfbml: true, 16 | version: 'v3.2', 17 | }) 18 | FB.AppEvents.logPageView() 19 | } 20 | ;(function(d, s, id) { 21 | var js, 22 | fjs = d.getElementsByTagName(s)[0] 23 | if (d.getElementById(id)) { 24 | return 25 | } 26 | js = d.createElement(s) 27 | js.id = id 28 | js.src = 'https://connect.facebook.net/en_US/sdk.js' 29 | fjs.parentNode.insertBefore(js, fjs) 30 | })(document, 'script', 'facebook-jssdk') 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | const metaConfig = require('./gatsby-meta-config') 2 | 3 | module.exports = { 4 | siteMetadata: metaConfig, 5 | plugins: [{ 6 | resolve: `gatsby-source-filesystem`, 7 | options: { 8 | path: `${__dirname}/content/blog`, 9 | name: `blog`, 10 | }, 11 | }, 12 | { 13 | resolve: `gatsby-source-filesystem`, 14 | options: { 15 | path: `${__dirname}/content/__about`, 16 | name: `about`, 17 | }, 18 | }, 19 | { 20 | resolve: `gatsby-source-filesystem`, 21 | options: { 22 | path: `${__dirname}/content/assets`, 23 | name: `assets`, 24 | }, 25 | }, 26 | { 27 | resolve: `gatsby-transformer-remark`, 28 | options: { 29 | plugins: [{ 30 | resolve: `gatsby-remark-images`, 31 | options: { 32 | maxWidth: 1200, 33 | linkImagesToOriginal: false, 34 | }, 35 | }, 36 | { 37 | resolve: `gatsby-remark-images-medium-zoom`, 38 | options: { 39 | margin: 36, 40 | scrollOffset: 0, 41 | }, 42 | }, 43 | { 44 | resolve: `gatsby-remark-responsive-iframe`, 45 | options: { 46 | wrapperStyle: `margin-bottom: 1.0725rem`, 47 | }, 48 | }, 49 | { 50 | resolve: `gatsby-remark-prismjs`, 51 | options: { 52 | inlineCodeMarker: '%', 53 | }, 54 | }, 55 | `gatsby-remark-copy-linked-files`, 56 | `gatsby-remark-smartypants`, 57 | `gatsby-remark-autolink-headers`, 58 | `gatsby-remark-emoji`, 59 | ], 60 | }, 61 | }, 62 | { 63 | resolve: `gatsby-plugin-gtag`, 64 | options: { 65 | trackingId: metaConfig.ga, 66 | // Puts tracking script in the head instead of the body 67 | head: false, 68 | // enable ip anonymization 69 | anonymize: true, 70 | }, 71 | }, 72 | { 73 | resolve: `gatsby-plugin-manifest`, 74 | options: { 75 | name: metaConfig.title, 76 | short_name: metaConfig.title, 77 | start_url: `/`, 78 | background_color: `#ffffff`, 79 | theme_color: `#663399`, 80 | display: `minimal-ui`, 81 | icon: metaConfig.icon, 82 | }, 83 | }, 84 | { 85 | resolve: `gatsby-plugin-typography`, 86 | options: { 87 | pathToConfigModule: `src/utils/typography`, 88 | }, 89 | }, 90 | `gatsby-transformer-sharp`, 91 | `gatsby-plugin-sharp`, 92 | `gatsby-plugin-feed`, 93 | `gatsby-plugin-offline`, 94 | `gatsby-plugin-react-helmet`, 95 | `gatsby-plugin-sass`, 96 | `gatsby-plugin-lodash`, 97 | `gatsby-plugin-sitemap`, 98 | ], 99 | } -------------------------------------------------------------------------------- /gatsby-meta-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: `SOSOLOG`, 3 | description: `Blog posted about ...`, 4 | author: `SO_YOUNG`, 5 | introduction: `📝 소소하게 끄적이는 개발로그`, 6 | siteUrl: `https://so-so.dev`, // Your blog site url 7 | social: { 8 | twitter: `soyoung__ee`, // Your Twitter account 9 | github: `SoYoung210`, // Your GitHub account 10 | medium: '', 11 | facebook: '', 12 | }, 13 | icon: `content/assets/favicon.png`, // Add your favicon 14 | resume: { 15 | title: 'About soso', 16 | description: 'docs: Update RESUME.md for introducing myself', 17 | thumbnail: 'https://so-so.dev/resume_thumbnail.jpg', 18 | }, 19 | keywords: [`blog`, `frontend`, `react`, `developer`], 20 | comment: { 21 | disqusShortName: '', // Your disqus-short-name. check disqus.com. 22 | utterances: 'SoYoung210/SOSO', // Your repository for archive comment 23 | }, 24 | configs: { 25 | countOfInitialPost: 10, // Config your initial count of post 26 | }, 27 | sponsor: { 28 | buyMeACoffeeId: 'soso', 29 | }, 30 | share: { 31 | facebookAppId: '', // Add facebookAppId for using facebook share feature v3.2 32 | }, 33 | ga: 'G-9XN9K5GTY1', // Add your google analytics tranking ID 34 | } 35 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | const path = require(`path`) 2 | const { 3 | createFilePath 4 | } = require(`gatsby-source-filesystem`) 5 | 6 | exports.createPages = ({ 7 | graphql, 8 | actions 9 | }) => { 10 | const { 11 | createPage 12 | } = actions 13 | 14 | const blogPostTemplate = path.resolve(`./src/templates/blog-post.js`) 15 | 16 | return graphql( 17 | ` 18 | { 19 | allMarkdownRemark( 20 | sort: { fields: [frontmatter___date], order: DESC } 21 | limit: 1000 22 | ) { 23 | edges { 24 | node { 25 | fields { 26 | slug 27 | } 28 | frontmatter { 29 | title 30 | category 31 | } 32 | } 33 | } 34 | } 35 | } 36 | ` 37 | ).then(result => { 38 | if (result.errors) { 39 | throw result.errors 40 | } 41 | 42 | // Create blog posts pages. 43 | const posts = result.data.allMarkdownRemark.edges.filter( 44 | ({ 45 | node 46 | }) => !!node.frontmatter.category 47 | ) 48 | 49 | posts.forEach((post, index) => { 50 | const previous = index === posts.length - 1 ? null : posts[index + 1].node 51 | const next = index === 0 ? null : posts[index - 1].node 52 | 53 | createPage({ 54 | path: post.node.fields.slug, 55 | component: blogPostTemplate, 56 | context: { 57 | slug: post.node.fields.slug, 58 | previous, 59 | next, 60 | }, 61 | }) 62 | }) 63 | }) 64 | } 65 | 66 | exports.onCreateNode = ({ 67 | node, 68 | actions, 69 | getNode 70 | }) => { 71 | const { 72 | createNodeField 73 | } = actions 74 | 75 | if (node.internal.type === `MarkdownRemark`) { 76 | const value = createFilePath({ 77 | node, 78 | getNode 79 | }) 80 | 81 | console.log(value) 82 | 83 | createNodeField({ 84 | name: `slug`, 85 | node, 86 | value, 87 | }) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SOSOLOG", 3 | "private": true, 4 | "version": "0.1.0", 5 | "author": "ethdud1@gmail.com>", 6 | "bugs": { 7 | "url": "https://github.com/SoYoung210/SOSO.git/issues" 8 | }, 9 | "dependencies": { 10 | "gatsby": "^2.13.64", 11 | "gatsby-image": "^2.2.8", 12 | "gatsby-plugin-favicon": "^3.1.6", 13 | "gatsby-plugin-feed": "^2.3.26", 14 | "gatsby-plugin-google-analytics": "^2.0.17", 15 | "gatsby-plugin-gtag": "^1.0.13", 16 | "gatsby-plugin-lodash": "^3.0.5", 17 | "gatsby-plugin-manifest": "^2.2.5", 18 | "gatsby-plugin-offline": "^2.0.25", 19 | "gatsby-plugin-react-helmet": "^3.0.10", 20 | "gatsby-plugin-sass": "^2.1.8", 21 | "gatsby-plugin-sharp": "^2.2.11", 22 | "gatsby-plugin-sitemap": "^2.2.6", 23 | "gatsby-plugin-typography": "^2.3.2", 24 | "gatsby-remark-autolink-headers": "^2.0.16", 25 | "gatsby-remark-copy-linked-files": "^2.0.11", 26 | "gatsby-remark-emoji": "0.0.2", 27 | "gatsby-remark-images": "^3.0.10", 28 | "gatsby-remark-images-medium-zoom": "^1.2.1", 29 | "gatsby-remark-prismjs": "^3.3.30", 30 | "gatsby-remark-responsive-iframe": "^2.2.4", 31 | "gatsby-remark-smartypants": "^2.0.9", 32 | "gatsby-source-filesystem": "^2.1.9", 33 | "gatsby-transformer-remark": "^2.6.14", 34 | "gatsby-transformer-sharp": "^2.2.6", 35 | "intersection-observer": "^0.5.1", 36 | "lodash": "^4.17.15", 37 | "node-sass": "^4.12.0", 38 | "prismjs": "^1.17.1", 39 | "react": "^16.8.1", 40 | "react-disqus-comments": "^1.4.0", 41 | "react-dom": "^16.8.1", 42 | "react-helmet": "^5.2.0", 43 | "react-switch": "^5.0.0", 44 | "react-typography": "^0.16.19", 45 | "smooth-scroll": "^16.1.0", 46 | "typeface-catamaran": "0.0.54", 47 | "typeface-merriweather": "0.0.72", 48 | "typeface-montserrat": "0.0.54", 49 | "typeface-noto-sans-kr": "0.0.63", 50 | "typography": "^0.16.17", 51 | "typography-theme-github": "^0.16.18" 52 | }, 53 | "devDependencies": { 54 | "date-fns": "^1.30.1", 55 | "eslint": "^5.14.1", 56 | "eslint-plugin-react": "^7.11.1", 57 | "fs-extra": "^7.0.1", 58 | "gray-matter": "^4.0.2", 59 | "inquirer": "^6.2.2", 60 | "lighthousebot": "git+https://github.com/GoogleChromeLabs/lighthousebot.git", 61 | "prettier": "^1.14.2", 62 | "recursive-readdir": "^2.2.2", 63 | "signale": "^1.3.0" 64 | }, 65 | "keywords": [ 66 | "gatsby" 67 | ], 68 | "license": "MIT", 69 | "main": "n/a", 70 | "repository": { 71 | "type": "git", 72 | "url": "git+https://github.com/SoYoung210/SOSO.git" 73 | }, 74 | "scripts": { 75 | "post": "node ./cli/create-new-post.js", 76 | "dev": "gatsby develop", 77 | "lint": "eslint --ext .js,.jsx --ignore-pattern public .", 78 | "format": "prettier --trailing-comma es5 --no-semi --single-quote --write 'src/**/*.js' 'src/**/*.md'", 79 | "develop": "gatsby develop", 80 | "start": "npm run develop", 81 | "build": "gatsby build", 82 | "lh": "lighthousebot", 83 | "fix-semi": "eslint --quiet --ignore-pattern node_modules --ignore-pattern public --parser babel-eslint --no-eslintrc --rule '{\"semi\": [2, \"never\"], \"no-extra-semi\": [2]}' --fix gatsby-node.js" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/components/bio/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StaticQuery, graphql, Link } from 'gatsby' 3 | import Image from 'gatsby-image' 4 | 5 | import './index.scss' 6 | 7 | export const Bio = () => ( 8 | { 11 | const { author, social, introduction } = data.site.siteMetadata 12 | 13 | return ( 14 |
15 |
16 |
17 | {author} 25 |
26 | 👋 27 | 28 | @{author} 29 | 30 |
{introduction}
31 |

32 | {social.github && ( 33 | GitHub 34 | )} 35 | {social.medium && ( 36 | Medium 37 | )} 38 | {social.twitter && ( 39 | 40 | X (Twitter) 41 | 42 | )} 43 | {social.facebook && ( 44 | 45 | Facebook 46 | 47 | )} 48 |

49 |
50 |
51 |
52 |
53 | ) 54 | }} 55 | /> 56 | ) 57 | 58 | const bioQuery = graphql` 59 | query BioQuery { 60 | avatar: file(absolutePath: { regex: "/profile.png/" }) { 61 | childImageSharp { 62 | fixed(width: 72, height: 72) { 63 | ...GatsbyImageSharpFixed 64 | } 65 | } 66 | } 67 | site { 68 | siteMetadata { 69 | author 70 | introduction 71 | social { 72 | twitter 73 | github 74 | medium 75 | facebook 76 | } 77 | } 78 | } 79 | } 80 | ` 81 | 82 | export default Bio 83 | -------------------------------------------------------------------------------- /src/components/bio/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .bio { 4 | margin-bottom: 24px; 5 | 6 | .author-description { 7 | display: flex; 8 | position: relative; 9 | 10 | // &::before { 11 | // position: absolute; 12 | // z-index: 999; 13 | // background: url('../../../content/assets/christmas_hat.png'); 14 | // display: inline-block; 15 | // width: 55px; 16 | // background-size: contain; 17 | // height: 55px; 18 | // content: ""; 19 | // transform: rotate(-34deg); 20 | // top: -11px; 21 | // left: -25px; 22 | // } 23 | } 24 | 25 | .author-image { 26 | margin-right: 12px; 27 | margin-bottom: 0; 28 | min-width: 72px; 29 | } 30 | 31 | .author-name-prefix { 32 | font-size: 90%; 33 | margin-right: 4px; 34 | } 35 | 36 | .author-name-content { 37 | display: inline-block; 38 | font-size: 95%; 39 | padding: 2px 6px; 40 | font-weight: bolder; 41 | border-radius: 8px; 42 | transform-origin: center; 43 | animation: flutter 2s infinite linear; 44 | } 45 | 46 | .author-introduction { 47 | margin-top: 4px; 48 | font-size: 80%; 49 | line-height: 1.4; 50 | } 51 | 52 | .author-socials { 53 | margin-top: 4px; 54 | } 55 | 56 | a { 57 | margin-right: 8px; 58 | font-size: 80%; 59 | 60 | &.visited { 61 | text-decoration: none; 62 | } 63 | } 64 | } 65 | 66 | @-webkit-keyframes flutter { 67 | 0% { 68 | transform: rotate(0deg); 69 | } 70 | 71 | 35% { 72 | transform: rotate(0deg); 73 | } 74 | 75 | 40% { 76 | transform: rotate(-5deg); 77 | } 78 | 79 | 60% { 80 | transform: rotate(5deg); 81 | } 82 | 83 | 65% { 84 | transform: rotate(0deg); 85 | } 86 | 87 | 100% { 88 | transform: rotate(0deg); 89 | } 90 | } 91 | 92 | @keyframes flutter { 93 | 0% { 94 | transform: rotate(0deg); 95 | } 96 | 97 | 35% { 98 | transform: rotate(0deg); 99 | } 100 | 101 | 40% { 102 | transform: rotate(-5deg); 103 | } 104 | 105 | 60% { 106 | transform: rotate(5deg); 107 | } 108 | 109 | 65% { 110 | transform: rotate(0deg); 111 | } 112 | 113 | 100% { 114 | transform: rotate(0deg); 115 | } 116 | } -------------------------------------------------------------------------------- /src/components/category/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { Item } from './item' 4 | import { rhythm } from '../../utils/typography' 5 | 6 | import './index.scss' 7 | 8 | export const Category = ({ categories, category, selectCategory }) => { 9 | return ( 10 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/components/category/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .category-container { 4 | position: sticky; 5 | position: -webkit-sticky; 6 | top: 0; 7 | line-height: 0; 8 | white-space: nowrap; 9 | overflow-x: scroll; 10 | -ms-overflow-style: none; // IE 10+ 11 | overflow: -moz-scrollbars-none; // Firefox 12 | z-index: 1; 13 | padding: 6px 20px; 14 | 15 | .item { 16 | display: inline-block; 17 | margin: 0.25rem 6px 0.25rem 0; 18 | border-radius: 15px; 19 | white-space: normal; 20 | box-sizing: border-box; 21 | cursor: pointer; 22 | 23 | div { 24 | display: block; 25 | padding: 14px 16px 16px 16px; 26 | font-size: 13px; 27 | box-sizing: border-box; 28 | } 29 | } 30 | 31 | .item:last-child { 32 | margin-right: 0; 33 | } 34 | } 35 | 36 | .category-container::-webkit-scrollbar { 37 | display: none; // Safari and Chrome 38 | } 39 | -------------------------------------------------------------------------------- /src/components/category/item/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const Item = ({ title, category, selectCategory }) => ( 4 |
  • 9 |
    selectCategory(title)}>{title}
    10 |
  • 11 | ) 12 | -------------------------------------------------------------------------------- /src/components/contents/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | 3 | import { ThumbnailContainer } from '../thumbnail-container' 4 | import { ThumbnailItem } from '../thumbnail-item' 5 | import { CATEGORY_TYPE } from '../../constants' 6 | 7 | export const Contents = ({ posts, countOfInitialPost, count, category }) => { 8 | const currentDate = new Date(); 9 | const refinedPosts = useMemo(() => 10 | posts 11 | .filter( 12 | ({ node }) => 13 | category === CATEGORY_TYPE.ALL || 14 | node.frontmatter.category === category 15 | ) 16 | .filter( 17 | ({ node }) => 18 | currentDate >= new Date(node.frontmatter.date) 19 | ) 20 | .slice(0, count * countOfInitialPost) 21 | ) 22 | 23 | return ( 24 | 25 | {refinedPosts.map(({ node }, index) => ( 26 | 27 | ))} 28 | 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /src/components/disqus/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import ReactDisqusComments from 'react-disqus-comments' 3 | 4 | export class Disqus extends Component { 5 | constructor(props) { 6 | super(props) 7 | this.state = { toasts: [] } 8 | this.notifyAboutComment = this.notifyAboutComment.bind(this) 9 | this.onSnackbarDismiss = this.onSnackbarDismiss.bind(this) 10 | } 11 | 12 | onSnackbarDismiss() { 13 | const [, ...toasts] = this.state.toasts 14 | this.setState({ toasts }) 15 | } 16 | 17 | notifyAboutComment() { 18 | const toasts = this.state.toasts.slice() 19 | toasts.push({ text: 'New comment available!!' }) 20 | this.setState({ toasts }) 21 | } 22 | 23 | render() { 24 | const { post, shortName, siteUrl, slug } = this.props 25 | const url = siteUrl + slug 26 | 27 | return ( 28 | 36 | ) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/components/elements/hr/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const Hr = () =>
    6 | -------------------------------------------------------------------------------- /src/components/elements/hr/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../../styles/variables.scss'; 2 | 3 | .custom-hr { 4 | margin: 64px; 5 | background: $theme-gradient; 6 | border: none; 7 | height: 2px; 8 | } 9 | -------------------------------------------------------------------------------- /src/components/elements/index.js: -------------------------------------------------------------------------------- 1 | export * from './hr' 2 | -------------------------------------------------------------------------------- /src/components/footer/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const Footer = () => ( 6 | 12 | ) 13 | -------------------------------------------------------------------------------- /src/components/footer/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .footer { 4 | padding-top: 52px; 5 | text-align: center; 6 | font-size: 12px; 7 | 8 | a { 9 | text-decoration: none !important; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/head/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import Helmet from 'react-helmet' 4 | import { StaticQuery, graphql } from 'gatsby' 5 | 6 | export function Head({ 7 | description, 8 | lang, 9 | meta, 10 | keywords, 11 | title, 12 | thumbnail 13 | }) { 14 | return ( 15 | { 18 | const metaDescription = 19 | description || data.site.siteMetadata.description 20 | return ( 21 | 0 71 | ? { 72 | name: `keywords`, 73 | content: keywords.join(`, `), 74 | } 75 | : [] 76 | ) 77 | .concat(meta)} 78 | /> 79 | ) 80 | }} 81 | /> 82 | ) 83 | } 84 | 85 | Head.defaultProps = { 86 | lang: `en`, 87 | meta: [], 88 | keywords: [], 89 | } 90 | 91 | Head.propTypes = { 92 | description: PropTypes.string, 93 | lang: PropTypes.string, 94 | meta: PropTypes.array, 95 | keywords: PropTypes.arrayOf(PropTypes.string), 96 | title: PropTypes.string.isRequired, 97 | } 98 | 99 | const detailsQuery = graphql` 100 | query DefaultSEOQuery { 101 | site { 102 | siteMetadata { 103 | title 104 | description 105 | author 106 | siteUrl 107 | } 108 | } 109 | } 110 | ` 111 | -------------------------------------------------------------------------------- /src/components/header/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'gatsby' 3 | 4 | import './index.scss' 5 | 6 | export const Header = ({ title, location, rootPath }) => { 7 | const isRoot = location.pathname === rootPath 8 | return ( 9 | isRoot && ( 10 |

    11 | 12 | {title} 13 | 14 |

    15 | ) 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/components/header/index.scss: -------------------------------------------------------------------------------- 1 | .home-header { 2 | margin-top: 0; 3 | border-bottom: none; 4 | font-weight: 900; 5 | font-size: 48px; 6 | letter-spacing: -2px; 7 | } 8 | 9 | .link { 10 | position: relative; 11 | box-shadow: none; 12 | text-decoration: none; 13 | color: inherit; 14 | 15 | &:after { 16 | position: absolute; 17 | right: -65px; 18 | top: 50%; 19 | transform: translateY(-55%); 20 | display: inline-block; 21 | // background: url('../../../content/assets/flamingo.png'); 22 | background-size: contain; 23 | background-repeat: no-repeat; 24 | width: 55px; 25 | height: 49px; 26 | content: ""; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/components/post-container/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './index.scss' 3 | 4 | export const PostContainer = ({ html }) => ( 5 |
    6 | ) 7 | -------------------------------------------------------------------------------- /src/components/post-container/index.scss: -------------------------------------------------------------------------------- 1 | .post-container { 2 | margin-bottom: 3em; 3 | word-break: keep-all; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/post-date/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const PostDate = ({ date }) => { 6 | return

    {date}

    7 | } 8 | -------------------------------------------------------------------------------- /src/components/post-date/index.scss: -------------------------------------------------------------------------------- 1 | .post-date { 2 | text-align: right; 3 | font-size: 12px; 4 | font-style: italic; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/post-navigator/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'gatsby' 3 | 4 | import './index.scss' 5 | 6 | export const PostNavigator = ({ pageContext }) => { 7 | const { previous, next } = pageContext 8 | 9 | return ( 10 |
      11 |
    • 12 | {previous && ( 13 | 14 | ← {previous.frontmatter.title} 15 | 16 | )} 17 |
    • 18 |
    • 19 | {next && ( 20 | 21 | {next.frontmatter.title} → 22 | 23 | )} 24 |
    • 25 |
    26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /src/components/post-navigator/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .navigator { 4 | margin: 40px 0; 5 | display: flex; 6 | flex-wrap: wrap; 7 | justify-content: space-between; 8 | list-style: none; 9 | padding: 0; 10 | 11 | li { 12 | margin-bottom: 12px; 13 | } 14 | 15 | a { 16 | padding: 7px 16px 8px 16px; 17 | border-radius: 6px; 18 | font-size: 12px; 19 | opacity: 0.8; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/components/post-title/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const PostTitle = ({ title }) =>

    {title}

    4 | -------------------------------------------------------------------------------- /src/components/social-share/facebook-icon/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const FacebookIcon = ({ onClick }) => ( 6 | 14 |
    15 | 23 | Share on Facebook 24 |
    25 |
    26 | ) 27 | -------------------------------------------------------------------------------- /src/components/social-share/facebook-icon/index.scss: -------------------------------------------------------------------------------- 1 | .resp-sharing-button--facebook { 2 | background-color: #3b5998; 3 | } 4 | 5 | .resp-sharing-button--facebook:hover { 6 | background-color: #2d4373; 7 | } 8 | 9 | .resp-sharing-button--facebook { 10 | background-color: #3b5998; 11 | border-color: #3b5998; 12 | } 13 | 14 | .resp-sharing-button--facebook:hover, 15 | .resp-sharing-button--facebook:active { 16 | background-color: #2d4373; 17 | border-color: #2d4373; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/social-share/github-icon/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const GitHubIcon = () => { 6 | return ( 7 | 12 | 18 | 19 | 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /src/components/social-share/github-icon/index.scss: -------------------------------------------------------------------------------- 1 | .github { 2 | float: right; 3 | padding: 14px; 4 | opacity: 0.6; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/social-share/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { FacebookIcon } from './facebook-icon' 3 | import { TwitterIcon } from './twitter-icon' 4 | import { shareToTwitter, shareToFacebook } from '../../utils/share' 5 | 6 | import './index.scss' 7 | 8 | export const SocialShare = ({ title, author, social}) => { 9 | const text = (author) => 10 | `Recommend on "${title}" written by @${author}` 11 | 12 | const onClickTwitterIcon = e => { 13 | e.preventDefault() 14 | 15 | return shareToTwitter(window.location.href, text(social.twitter)) 16 | } 17 | 18 | const onClickFacebookIcon = e => { 19 | e.preventDefault() 20 | return shareToFacebook(window.location.href, text(social.facebook)) 21 | } 22 | 23 | return ( 24 |
    25 | 26 | 27 |
    28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/components/social-share/index.scss: -------------------------------------------------------------------------------- 1 | .social-share { 2 | text-align: right; 3 | height: 100%; 4 | } 5 | 6 | .resp-sharing-button__link, 7 | .resp-sharing-button__icon { 8 | display: inline-block; 9 | vertical-align: middle; 10 | border: none; 11 | } 12 | 13 | .resp-sharing-button__link { 14 | text-decoration: none; 15 | color: #fff; 16 | margin: 4px; 17 | height: 33px; 18 | 19 | .service-label { 20 | font-size: 12px; 21 | padding-right: 4px; 22 | } 23 | } 24 | 25 | .resp-sharing-button { 26 | height: 33px; 27 | border-radius: 6px; 28 | transition: 25ms ease-out; 29 | padding: 3px 8px 3px 10px; 30 | font-family: Helvetica Neue, Helvetica, Arial, sans-serif; 31 | } 32 | 33 | .resp-sharing-button__icon svg { 34 | width: 1em; 35 | height: 1.5em; 36 | margin-right: 0.4em; 37 | vertical-align: top; 38 | } 39 | 40 | .resp-sharing-button__icon { 41 | stroke: #fff; 42 | fill: none; 43 | } 44 | 45 | .resp-sharing-button__icon--solid { 46 | fill: #fff; 47 | stroke: none; 48 | } 49 | -------------------------------------------------------------------------------- /src/components/social-share/twitter-icon/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const TwitterIcon = ({ onClick }) => ( 6 | 13 |
    14 | 22 | Share on Twitter 23 |
    24 |
    25 | ) 26 | -------------------------------------------------------------------------------- /src/components/social-share/twitter-icon/index.scss: -------------------------------------------------------------------------------- 1 | .resp-sharing-button--twitter { 2 | background-color: #55acee; 3 | } 4 | 5 | .resp-sharing-button--twitter:hover { 6 | background-color: #2795e9; 7 | } 8 | 9 | .resp-sharing-button--twitter { 10 | background-color: #55acee; 11 | border-color: #55acee; 12 | } 13 | 14 | .resp-sharing-button--twitter:hover, 15 | .resp-sharing-button--twitter:active { 16 | background-color: #2795e9; 17 | border-color: #2795e9; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/sponsor-button/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const SponsorButton = () => ( 6 | 14 | ) 15 | -------------------------------------------------------------------------------- /src/components/sponsor-button/index.scss: -------------------------------------------------------------------------------- 1 | .sponsor-button { 2 | text-align: right; 3 | margin: 4px; 4 | 5 | .btn { 6 | color: #24292e; 7 | background-color: #fafbfc; 8 | border-color: rgba(27,31,35,.15); 9 | transition: 80ms cubic-bezier(0.33, 1, 0.68, 1); 10 | transition-property: color,background-color,box-shadow,border-color; 11 | position: relative; 12 | padding: 5px 16px; 13 | font-size: 12px; 14 | font-weight: 500; 15 | line-height: 20px; 16 | white-space: nowrap; 17 | vertical-align: middle; 18 | cursor: pointer; 19 | -webkit-user-select: none; 20 | user-select: none; 21 | border: 1px solid rgba(27,31,36,0.15); 22 | border-radius: 6px; 23 | -webkit-appearance: none; 24 | appearance: none; 25 | 26 | &:hover { 27 | background-color: #f3f4f6; 28 | transition-duration: .1s; 29 | text-decoration: none; 30 | 31 | .icon-sponsor { 32 | transform: scale(1.1); 33 | } 34 | } 35 | 36 | .octicon { 37 | color: #bf3989; 38 | display: inline-block; 39 | overflow: visible !important; 40 | fill: currentColor; 41 | vertical-align: text-bottom; 42 | } 43 | } 44 | 45 | .mr-2 { 46 | margin-right: 8px !important; 47 | } 48 | 49 | .icon-sponsor { 50 | transition: transform .15s cubic-bezier(0.2, 0, 0.13, 2); 51 | transform: scale(1); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/components/theme-switch/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | import Switch from 'react-switch' 3 | 4 | import * as Dom from '../../utils/dom' 5 | import * as Storage from '../../utils/storage' 6 | import { THEME } from '../../constants' 7 | 8 | import './index.scss' 9 | 10 | function getTheme(checked) { 11 | return checked ? THEME.DARK : THEME.LIGHT 12 | } 13 | 14 | function toggleTheme(theme) { 15 | switch (theme) { 16 | case THEME.LIGHT: { 17 | Dom.addClassToBody(THEME.LIGHT) 18 | Dom.removeClassToBody(THEME.DARK) 19 | break 20 | } 21 | case THEME.DARK: { 22 | Dom.addClassToBody(THEME.DARK) 23 | Dom.removeClassToBody(THEME.LIGHT) 24 | break 25 | } 26 | } 27 | } 28 | 29 | export const ThemeSwitch = () => { 30 | const [checked, setChecked] = useState(false) 31 | 32 | const handleChange = checked => { 33 | const theme = getTheme(checked) 34 | 35 | Storage.setTheme(checked) 36 | setChecked(checked) 37 | toggleTheme(theme) 38 | } 39 | 40 | useEffect(() => { 41 | const checked = Storage.getTheme(Dom.hasClassOfBody(THEME.DARK)) 42 | 43 | handleChange(checked) 44 | }, []) 45 | 46 | return ( 47 |
    48 |
    } 56 | uncheckedIcon={
    L
    } 57 | offColor={'#d9dfe2'} 58 | offHandleColor={'#fff'} 59 | onColor={'#999'} 60 | onHandleColor={'#282c35'} 61 | /> 62 | 63 |
    64 | ) 65 | } 66 | -------------------------------------------------------------------------------- /src/components/theme-switch/index.scss: -------------------------------------------------------------------------------- 1 | .switch-container { 2 | text-align: right; 3 | 4 | .icon { 5 | text-align: center; 6 | color: #222; 7 | font-size: 14px; 8 | font-weight: 900; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/thumbnail-container/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.scss' 4 | 5 | export const ThumbnailContainer = React.memo(({ children }) => ( 6 |
    {children}
    7 | )) 8 | -------------------------------------------------------------------------------- /src/components/thumbnail-container/index.scss: -------------------------------------------------------------------------------- 1 | .thumbnail-container { 2 | min-height: calc(100vh - 3.5rem); 3 | } -------------------------------------------------------------------------------- /src/components/thumbnail-item/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'gatsby' 3 | import { TARGET_CLASS } from '../../utils/visible' 4 | 5 | import './index.scss' 6 | 7 | export const ThumbnailItem = ({ node }) => ( 8 | 9 |
    10 |

    {node.frontmatter.title || node.fields.slug}

    11 |

    12 |

    13 | 14 | ) 15 | -------------------------------------------------------------------------------- /src/components/thumbnail-item/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .thumbnail { 4 | display: block; 5 | margin-bottom: 12px; 6 | padding: 4px; 7 | padding-bottom: 12px; 8 | box-shadow: none; 9 | transition: text-shadow 0.3s, opacity 0.4s; 10 | opacity: 0; 11 | 12 | p { 13 | font-size: 90%; 14 | line-height: 1.4; 15 | } 16 | } 17 | 18 | .thumbnail.visible { 19 | opacity: 1; 20 | } 21 | -------------------------------------------------------------------------------- /src/components/top/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'gatsby' 3 | import { GitHubIcon } from '../social-share/github-icon' 4 | 5 | import './index.scss' 6 | 7 | export const Top = ({ title, location, rootPath }) => { 8 | const isRoot = location.pathname === rootPath 9 | return ( 10 |
    11 | {!isRoot && ( 12 | 13 | {title} 14 | 15 | )} 16 | 17 |
    18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /src/components/top/index.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables.scss'; 2 | 3 | .top { 4 | position: relative; 5 | width: 100%; 6 | height: 60px; 7 | // background: linear-gradient(315deg, #7f53ac 0%, #647dee 74%); 8 | // background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); 9 | // summer background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); 10 | // background: linear-gradient(-45deg, #BB2528, #EA4630, #F8B229, #146B3A, #165B33); 11 | // spring background: linear-gradient(-45deg, #1fab89, #62d2a2, #ffc8c8, #ff9999); 12 | background: linear-gradient(87.23deg, #8D7EEE -5.97%, #9BE1FB 31.47%, #E07FA8 77.82%, #EDCFD2 105.16%); 13 | // background-size: 182% 200%; 14 | // -webkit-animation: Gradient 7s ease infinite; 15 | // -moz-animation: Gradient 7s ease infinite; 16 | // animation: Gradient 7s ease infinite; 17 | 18 | .link { 19 | display: inline-block; 20 | font-size: 28px; 21 | padding-top: 8px; 22 | color: $top-header-text-color; 23 | opacity: 0.7; 24 | margin-left: 20px; 25 | font-family: 'Catamaran'; 26 | font-weight: 800; 27 | } 28 | } 29 | 30 | @-webkit-keyframes Gradient { 31 | 0% { 32 | background-position: 0% 50%; 33 | } 34 | 35 | 50% { 36 | background-position: 100% 50%; 37 | } 38 | 39 | 100% { 40 | background-position: 0% 50%; 41 | } 42 | } 43 | 44 | @-moz-keyframes Gradient { 45 | 0% { 46 | background-position: 0% 50%; 47 | } 48 | 49 | 50% { 50 | background-position: 100% 50%; 51 | } 52 | 53 | 100% { 54 | background-position: 0% 50%; 55 | } 56 | } 57 | 58 | @keyframes Gradient { 59 | 0% { 60 | background-position: 0% 50%; 61 | } 62 | 63 | 50% { 64 | background-position: 100% 50%; 65 | } 66 | 67 | 100% { 68 | background-position: 0% 50%; 69 | } 70 | } -------------------------------------------------------------------------------- /src/components/utterances/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react' 2 | 3 | const src = 'https://utteranc.es/client.js' 4 | const branch = 'master' 5 | 6 | export const Utterences = ({ repo }) => { 7 | const rootElm = React.createRef() 8 | 9 | useEffect(() => { 10 | const utterances = document.createElement('script') 11 | const utterancesConfig = { 12 | src, 13 | repo, 14 | branch, 15 | async: true, 16 | 'issue-term': 'pathname', 17 | crossorigin: 'anonymous', 18 | } 19 | 20 | Object.keys(utterancesConfig).forEach(configKey => { 21 | utterances.setAttribute(configKey, utterancesConfig[configKey]) 22 | }) 23 | rootElm.current.appendChild(utterances) 24 | }, []) 25 | 26 | return
    27 | } 28 | -------------------------------------------------------------------------------- /src/constants/enum.js: -------------------------------------------------------------------------------- 1 | export const CATEGORY_TYPE = { 2 | ALL: 'All', 3 | } 4 | 5 | export const THEME = { 6 | LIGHT: 'light', 7 | DARK: 'dark', 8 | } 9 | -------------------------------------------------------------------------------- /src/constants/index.js: -------------------------------------------------------------------------------- 1 | export * from './meta' 2 | export * from './window' 3 | export * from './enum' 4 | export * from './lang' 5 | -------------------------------------------------------------------------------- /src/constants/lang.js: -------------------------------------------------------------------------------- 1 | export const KOREAN = 'ko' 2 | export const ENGLISH = 'en' 3 | -------------------------------------------------------------------------------- /src/constants/meta.js: -------------------------------------------------------------------------------- 1 | export const HOME_TITLE = 'Home' 2 | -------------------------------------------------------------------------------- /src/constants/window.js: -------------------------------------------------------------------------------- 1 | export const SCROLL_Y = 'y' 2 | -------------------------------------------------------------------------------- /src/html.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | export default class HTML extends React.Component { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 15 | 16 | 21 | 22 | {this.props.headComponents} 23 | 24 | 25 | 26 | {this.props.preBodyComponents} 27 | 28 |
    33 | {this.props.postBodyComponents} 34 | 35 | 36 | ) 37 | } 38 | } 39 | 40 | HTML.propTypes = { 41 | htmlAttributes: PropTypes.object, 42 | headComponents: PropTypes.array, 43 | bodyAttributes: PropTypes.object, 44 | preBodyComponents: PropTypes.array, 45 | body: PropTypes.string, 46 | postBodyComponents: PropTypes.array, 47 | } 48 | -------------------------------------------------------------------------------- /src/layout/SnowFlake.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect } from 'react' 2 | 3 | export const SnowFlake = ({ children }) => { 4 | const canvasRef = useRef(null) 5 | 6 | useEffect(() => { 7 | let snowflakes = [] 8 | let snowflake 9 | const COUNT = 700 10 | const canvasNode = canvasRef.current 11 | const ctx = canvasNode.getContext('2d') 12 | let i = 0 13 | const width = document.documentElement.offsetWidth 14 | const height = document.documentElement.offsetHeight 15 | canvasNode.width = width 16 | canvasNode.height = height 17 | 18 | const reset = () => { 19 | return { 20 | x: Math.random() * width, 21 | y: Math.random() * -height, 22 | vy: 1 + Math.random() * 3, 23 | vx: 0.5 - Math.random(), 24 | r: 1 + Math.random() * 2, 25 | opacity: 0.5 + Math.random() * 0.5, 26 | } 27 | } 28 | 29 | const init = () => { 30 | ctx.fillStyle = '#FFF' 31 | 32 | for (i = 0; i < COUNT; i++) { 33 | snowflake = reset() 34 | snowflakes.push(snowflake) 35 | } 36 | requestAnimationFrame(update) 37 | } 38 | 39 | for (i = 0; i < COUNT; i++) { 40 | snowflake = reset() 41 | snowflakes.push(snowflake) 42 | } 43 | 44 | const update = () => { 45 | ctx.clearRect(0, 0, width, height) 46 | 47 | for (i = 0; i < COUNT; i++) { 48 | snowflake = snowflakes[i] 49 | snowflake.y += snowflake.vy 50 | snowflake.x += snowflake.vx 51 | 52 | ctx.globalAlpha = snowflake.opacity 53 | ctx.beginPath() 54 | ctx.arc(snowflake.x, snowflake.y, snowflake.r, 0, Math.PI * 2, false) 55 | ctx.closePath() 56 | ctx.fill() 57 | 58 | if (snowflake.y > height) { 59 | snowflake = reset() 60 | } 61 | } 62 | 63 | requestAnimationFrame(update) 64 | } 65 | 66 | init() 67 | }, [canvasRef]) 68 | 69 | return ( 70 | <> 71 | 72 | {children} 73 | 74 | ) 75 | } 76 | -------------------------------------------------------------------------------- /src/layout/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { Top } from '../components/top' 4 | import { Header } from '../components/header' 5 | import { ThemeSwitch } from '../components/theme-switch' 6 | import { Footer } from '../components/footer' 7 | import { rhythm } from '../utils/typography' 8 | import './index.scss' 9 | 10 | export const Layout = ({ location, title, children }) => { 11 | const rootPath = `${__PATH_PREFIX__}/` 12 | 13 | return ( 14 | 15 | 16 |
    24 | 25 |
    26 | {children} 27 |
    28 |
    29 |
    30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /src/layout/index.scss: -------------------------------------------------------------------------------- 1 | @import '../styles/variables.scss'; 2 | @import '../styles/light-theme.scss'; 3 | @import '../styles/dark-theme.scss'; 4 | @import '../styles/resume.scss'; 5 | @import '../styles/snow-flake.scss'; 6 | 7 | body { 8 | font-family: 'Noto Sans KR', sans-serif; 9 | background-color: $light-background-color; 10 | -webkit-text-size-adjust: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | transition: background-color 0.3s, color 0.3s; 13 | } -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { graphql } from 'gatsby' 3 | 4 | import { Layout } from '../layout' 5 | import { Head } from '../components/head' 6 | 7 | class NotFoundPage extends React.Component { 8 | render() { 9 | const { data } = this.props 10 | const siteTitle = data.site.siteMetadata.title 11 | 12 | return ( 13 | 14 | 15 |

    Not Found

    16 |

    You just hit a route that doesn't exist... the sadness.

    17 |
    18 | ) 19 | } 20 | } 21 | 22 | export default NotFoundPage 23 | 24 | export const pageQuery = graphql` 25 | query { 26 | site { 27 | siteMetadata { 28 | title 29 | } 30 | } 31 | } 32 | ` 33 | -------------------------------------------------------------------------------- /src/pages/about.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { graphql } from 'gatsby' 3 | 4 | import { Head } from '../components/head' 5 | import * as Lang from '../constants' 6 | import { rhythm } from '../utils/typography' 7 | 8 | import '../styles/resume.scss' 9 | 10 | export default ({ data }) => { 11 | const resumeData = data.site.siteMetadata.resume 12 | const resumes = data.allMarkdownRemark.edges 13 | const resume = resumes 14 | .filter(({ node }) => node.frontmatter.lang === Lang.KOREAN) 15 | .map(({ node }) => node)[0] 16 | 17 | return ( 18 | <> 19 | 24 |
    35 |
    36 |
    37 | 38 | ) 39 | } 40 | 41 | export const pageQuery = graphql` 42 | query { 43 | site { 44 | siteMetadata { 45 | resume { 46 | title 47 | description 48 | thumbnail 49 | } 50 | } 51 | } 52 | allMarkdownRemark(filter: { frontmatter: { category: { eq: null } } }) { 53 | edges { 54 | node { 55 | id 56 | excerpt(pruneLength: 160) 57 | html 58 | frontmatter { 59 | title 60 | date(formatString: "MMMM DD, YYYY") 61 | lang 62 | } 63 | } 64 | } 65 | } 66 | } 67 | ` 68 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from 'react' 2 | import { graphql } from 'gatsby' 3 | import _ from 'lodash' 4 | 5 | import { Layout } from '../layout' 6 | import { Bio } from '../components/bio' 7 | import { Head } from '../components/head' 8 | import { Category } from '../components/category' 9 | import { Contents } from '../components/contents' 10 | 11 | import * as ScrollManager from '../utils/scroll' 12 | import * as Storage from '../utils/storage' 13 | import * as IOManager from '../utils/visible' 14 | import * as EventManager from '../utils/event-manager' 15 | import * as Dom from '../utils/dom' 16 | 17 | import { HOME_TITLE, CATEGORY_TYPE } from '../constants' 18 | 19 | const DEST_POS = 316 20 | const BASE_LINE = 80 21 | 22 | function getDistance(currentPos) { 23 | return Dom.getDocumentHeight() - currentPos 24 | } 25 | 26 | export default ({ data, location }) => { 27 | const initialCount = Storage.getCount(1) 28 | const initialCategory = Storage.getCategory(CATEGORY_TYPE.ALL) 29 | const [count, setCount] = useState(initialCount) 30 | const countRef = useRef(count) 31 | const [category, setCategory] = useState(initialCategory) 32 | 33 | const { siteMetadata } = data.site 34 | const { countOfInitialPost } = siteMetadata.configs 35 | const posts = data.allMarkdownRemark.edges 36 | const categories = _.uniq(posts.map(({ node }) => node.frontmatter.category)) 37 | 38 | useEffect(() => { 39 | window.addEventListener(`scroll`, onScroll, { passive: false }) 40 | IOManager.init() 41 | ScrollManager.init() 42 | 43 | return () => { 44 | window.removeEventListener(`scroll`, onScroll, { passive: false }) 45 | IOManager.destroy() 46 | ScrollManager.destroy() 47 | } 48 | }, []) 49 | 50 | useEffect(() => { 51 | countRef.current = count 52 | IOManager.refreshObserver() 53 | Storage.setCount(count) 54 | Storage.setCategory(category) 55 | }) 56 | 57 | const selectCategory = category => { 58 | setCategory(category) 59 | ScrollManager.go(DEST_POS) 60 | } 61 | 62 | const onScroll = () => { 63 | const currentPos = window.scrollY + window.innerHeight 64 | const isTriggerPos = () => getDistance(currentPos) < BASE_LINE 65 | const doesNeedMore = () => 66 | posts.length > countRef.current * countOfInitialPost 67 | 68 | return EventManager.toFit(() => setCount(prev => prev + 1), { 69 | dismissCondition: () => !isTriggerPos(), 70 | triggerCondition: () => isTriggerPos() && doesNeedMore(), 71 | })() 72 | } 73 | 74 | return ( 75 | 76 | 77 | 78 | 83 | 89 | 90 | ) 91 | } 92 | 93 | export const pageQuery = graphql` 94 | query { 95 | site { 96 | siteMetadata { 97 | title 98 | configs { 99 | countOfInitialPost 100 | } 101 | } 102 | } 103 | allMarkdownRemark( 104 | sort: { fields: [frontmatter___date], order: DESC } 105 | filter: { frontmatter: { category: { ne: null } } } 106 | ) { 107 | edges { 108 | node { 109 | excerpt(pruneLength: 200, truncate: true) 110 | fields { 111 | slug 112 | } 113 | frontmatter { 114 | date(formatString: "MMMM DD, YYYY") 115 | title 116 | category 117 | } 118 | } 119 | } 120 | } 121 | } 122 | ` 123 | -------------------------------------------------------------------------------- /src/styles/code.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML 3 | * Based on https://github.com/chriskempson/tomorrow-theme 4 | * @author Rose Pritchard 5 | * @custoimized by Jbee 6 | */ 7 | 8 | @import url(https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css); 9 | @import './variables.scss'; 10 | 11 | .gatsby-highlight-code-line { 12 | background-color: hsla(207, 95%, 15%, 1); 13 | display: block; 14 | margin-right: -1.2em; 15 | margin-left: -1.2em; 16 | padding-right: 1em; 17 | padding-left: 0.75em; 18 | border-left: 0.35em solid #0687f0; 19 | } 20 | 21 | code { 22 | font-weight: 500 !important; 23 | } 24 | 25 | code[class*='language-'], 26 | pre[class*='language-'] { 27 | color: #e0e0e0; 28 | background: none; 29 | font-family: 'Fira Code', 'Consolas', 'Monaco', 'Andale Mono', 'Ubuntu Mono', 30 | monospace; 31 | text-align: left; 32 | white-space: pre; 33 | word-spacing: normal; 34 | word-break: normal; 35 | word-wrap: normal; 36 | line-height: 1.6; 37 | font-size: 0.95em; 38 | 39 | -moz-tab-size: 2; 40 | -o-tab-size: 2; 41 | tab-size: 2; 42 | 43 | -webkit-hyphens: none; 44 | -moz-hyphens: none; 45 | -ms-hyphens: none; 46 | hyphens: none; 47 | 48 | -ms-overflow-style: none; // IE 10+ 49 | overflow: -moz-scrollbars-none; // Firefox 50 | } 51 | 52 | pre[class*='language-']::-webkit-scrollbar { 53 | display: none; // Safari and Chrome 54 | } 55 | 56 | /* Code blocks */ 57 | pre[class*='language-'] { 58 | padding: 1.2em; 59 | margin: 1.5em -2.5em; 60 | overflow: auto; 61 | border-radius: 0.6em; 62 | } 63 | 64 | details summary { 65 | cursor: pointer; 66 | } 67 | 68 | summary { 69 | display: list-item; 70 | } 71 | 72 | @media screen and (max-width: 730px) { 73 | pre[class*='language-'] { 74 | margin: 1.5em -1.2rem; 75 | border-radius: 0; 76 | } 77 | } 78 | 79 | :not(pre)>code[class*='language-'], 80 | pre[class*='language-'] { 81 | background: #242323; 82 | } 83 | 84 | /* Inline code */ 85 | :not(pre)>code[class*='language-'] { 86 | padding: .11em .3em; 87 | margin: 0 .1em; 88 | border-radius: .3em; 89 | white-space: normal; 90 | } 91 | 92 | .token.comment, 93 | .token.block-comment, 94 | .token.prolog, 95 | .token.doctype, 96 | .token.cdata { 97 | color: #7a8390; 98 | } 99 | 100 | .token.punctuation { 101 | color: #e0e0e0; 102 | } 103 | 104 | .token.tag, 105 | .token.attr-name, 106 | .token.namespace, 107 | .token.deleted { 108 | color: #e2777a; 109 | } 110 | 111 | .token.function-name { 112 | color: #6196cc; 113 | } 114 | 115 | .token.boolean, 116 | .token.number, 117 | .token.function { 118 | color: #ff9100; 119 | } 120 | 121 | .token.property, 122 | .token.class-name, 123 | .token.constant, 124 | .token.symbol { 125 | color: #ffff00; 126 | } 127 | 128 | .token.selector, 129 | .token.important, 130 | .token.atrule, 131 | .token.keyword, 132 | .token.builtin { 133 | color: #b388ff; 134 | } 135 | 136 | .token.string, 137 | .token.char, 138 | .token.attr-value, 139 | .token.regex, 140 | .token.variable { 141 | color: #00e676; 142 | } 143 | 144 | .token.operator, 145 | .token.entity, 146 | .token.url { 147 | color: #67cdcc; 148 | } 149 | 150 | .token.important, 151 | .token.bold { 152 | font-weight: bold; 153 | } 154 | 155 | .token.italic { 156 | font-style: italic; 157 | } 158 | 159 | .token.entity { 160 | cursor: help; 161 | } 162 | 163 | .token.inserted { 164 | color: green; 165 | } -------------------------------------------------------------------------------- /src/styles/dark-theme.scss: -------------------------------------------------------------------------------- 1 | body.dark { 2 | background-color: $dark-background-color; 3 | text-shadow: $dark-text-shadow; 4 | color: $dark-light-font-color; 5 | 6 | // home 7 | .home-header { 8 | color: $dark-light-font-color; 9 | } 10 | 11 | .bio { 12 | .author-name-content { 13 | background-color: $dark-category-border-color; 14 | } 15 | .author-introduction { 16 | color: $dark-middle-font-color; 17 | } 18 | a { 19 | color: $dark-link-color; 20 | } 21 | } 22 | 23 | .category-container { 24 | border-top: 1px solid $dark-category-border-color; 25 | border-bottom: 1px solid $dark-category-border-color; 26 | border-right: 6px solid $dark-category-border-color; 27 | border-left: 6px solid $dark-category-border-color; 28 | background-color: $dark-category-background-color; 29 | .item { 30 | border: 1px solid $dark-category-border-color; 31 | background-color: $dark-category-item-color; 32 | -webkit-box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.1); 33 | box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.1); 34 | a { 35 | color: $dark-category-text-color; 36 | } 37 | &[aria-selected='true'] { 38 | border: 2px solid $dark-category-highlight-border-color; 39 | font-weight: bolder; 40 | } 41 | &[aria-selected='true'] a { 42 | color: $dark-category-highlight-text-color; 43 | } 44 | } 45 | } 46 | 47 | .thumbnail { 48 | h3 { 49 | color: $dark-light-font-color; 50 | } 51 | p { 52 | color: $dark-middle-font-color; 53 | } 54 | &:hover { 55 | text-shadow: $dark-hover-text-shadow; 56 | } 57 | } 58 | 59 | .post-date { 60 | color: $light-gray; 61 | } 62 | 63 | .footer { 64 | color: $dark-middle-font-color; 65 | a { 66 | color: $dark-lightest-font-color; 67 | } 68 | } 69 | 70 | h1, 71 | h2 { 72 | border-bottom-color: rgba(255, 255, 255, 0.3); 73 | } 74 | 75 | h4 { 76 | font-size: 1.1rem; 77 | } 78 | 79 | .navigator { 80 | a { 81 | background-color: $navigator-background-color; 82 | color: $navigator-text-color; 83 | } 84 | } 85 | 86 | blockquote { 87 | color: $dark-blockquote-quote-color; 88 | &::before { 89 | background-image: $dark-blockquote-quote-image; 90 | } 91 | } 92 | 93 | /* Inline code */ 94 | :not(pre) > code[class*='language-'] { 95 | background: $dark-inline-dimmed-color; 96 | color: $dark-inline-text-color; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/styles/light-theme.scss: -------------------------------------------------------------------------------- 1 | body.light { 2 | background-color: $light-background-color; 3 | text-shadow: $light-text-shadow; 4 | 5 | // home 6 | .home-header { 7 | color: $dark-gray; 8 | } 9 | 10 | .bio { 11 | .author-name-content { 12 | background-color: $light-category-border-color; 13 | } 14 | .author-introduction { 15 | color: $middle-gray; 16 | } 17 | a { 18 | color: $light-link-color; 19 | } 20 | } 21 | 22 | .category-container { 23 | border-top: 1px solid $light-category-border-color; 24 | border-bottom: 1px solid $light-category-border-color; 25 | border-right: 6px solid $light-category-border-color; 26 | border-left: 6px solid $light-category-border-color; 27 | background-color: $light-category-background-color; 28 | .item { 29 | border: 1px solid $light-category-border-color; 30 | background-color: $light-category-item-color; 31 | -webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); 32 | box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); 33 | a { 34 | color: $light-category-text-color; 35 | } 36 | &[aria-selected='true'] { 37 | border: 2px solid $light-category-highlight-border-color; 38 | font-weight: bolder; 39 | } 40 | &[aria-selected='true'] a { 41 | color: $light-category-highlight-text-color; 42 | } 43 | } 44 | } 45 | 46 | .thumbnail { 47 | h3 { 48 | color: $dark-gray; 49 | } 50 | p { 51 | color: $middle-gray; 52 | } 53 | &:hover { 54 | text-shadow: $light-hover-text-shadow; 55 | } 56 | } 57 | 58 | .post-date { 59 | color: $middle-gray; 60 | } 61 | 62 | .footer { 63 | color: $light-gray; 64 | a { 65 | color: $dark-gray; 66 | } 67 | } 68 | 69 | // post 70 | .navigator { 71 | a { 72 | background-color: $navigator-background-color; 73 | color: $navigator-text-color; 74 | } 75 | } 76 | 77 | blockquote { 78 | color: $light-blockquote-quote-color; 79 | &::before { 80 | background-image: $light-blockquote-quote-image; 81 | } 82 | } 83 | 84 | h4 { 85 | font-size: 1.1rem; 86 | } 87 | 88 | /* Inline code */ 89 | :not(pre) > code[class*='language-'] { 90 | background: $light-inline-dimmed-color; 91 | color: $light-inline-text-color; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/styles/post.scss: -------------------------------------------------------------------------------- 1 | blockquote { 2 | position: relative; 3 | margin-top: 12px; 4 | padding: 12px 8px 0px 36px; 5 | 6 | border-left: none; 7 | font-weight: 300; 8 | 9 | &::before { 10 | position: absolute; 11 | top: 16px; 12 | left: 4px; 13 | display: inline-block; 14 | background-size: contain; 15 | opacity: 0.2; 16 | width: 22px; 17 | height: 22px; 18 | z-index: 1; 19 | content: ''; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/styles/resume.scss: -------------------------------------------------------------------------------- 1 | // ===Color 2 | $theme: #0064FF; 3 | 4 | .about { 5 | word-break: keep-all; 6 | .title { 7 | position: relative; 8 | margin-bottom: 0; 9 | padding-bottom: 0; 10 | 11 | &:after { 12 | content: ""; 13 | position: absolute; 14 | display: inline-block; 15 | top: -6px; 16 | left: -16px; 17 | width: 12px; 18 | height: 12px; 19 | border-radius: 50%; 20 | background-color: $theme; 21 | } 22 | } 23 | 24 | .personal-links { 25 | margin-bottom: 20px; 26 | 27 | a { 28 | opacity: 0.5; 29 | font-size: 14px; 30 | } 31 | } 32 | 33 | .highlight { 34 | position: relative; 35 | 36 | &:after { 37 | content: ''; 38 | display: inline-block; 39 | position: absolute; 40 | height: 12px; 41 | width: 100%; 42 | bottom: 10px; 43 | background-color: $theme; 44 | opacity: 0.15; 45 | left: 0; 46 | } 47 | } 48 | h1, .no-border { 49 | border-bottom: transparent!important; 50 | margin-top: 2.4em; 51 | } 52 | 53 | h2 { 54 | margin-top: 1.5em; 55 | margin-bottom: 0.5em; 56 | font-size: 28px; 57 | 58 | border-bottom: 0; 59 | } 60 | 61 | h3 { 62 | font-weight: 700; 63 | margin-top: 1em; 64 | margin-bottom: 0.5em; 65 | font-size: 24px; 66 | 67 | border-bottom: 0; 68 | display: flex; 69 | align-items: center; 70 | } 71 | 72 | h4 { 73 | font-weight: 600; 74 | margin-top: 1.8em; 75 | margin-bottom: 0.6em; 76 | font-size: 20px; 77 | 78 | padding-bottom: calc(0.4rem - 1px); 79 | border-bottom: 1px solid hsla(0,0%,0%,0.07); 80 | } 81 | 82 | thead tr th{ 83 | padding-top: 0; 84 | word-break: keep-all; 85 | } 86 | 87 | div.final { 88 | margin-top: 5em !important; 89 | } 90 | } 91 | 92 | div.period { 93 | font-size: 18px; 94 | font-weight: 300; 95 | margin-left: auto; 96 | color: rgb(155,154,151); 97 | } 98 | -------------------------------------------------------------------------------- /src/styles/snow-flake.scss: -------------------------------------------------------------------------------- 1 | .snowflakes { 2 | z-index: -1; 3 | position: absolute; 4 | top: 0; 5 | left: 0; 6 | } 7 | -------------------------------------------------------------------------------- /src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // app 2 | $theme-gradient: linear-gradient(72deg, #ffcdd2, #7e57c2); 3 | $top-header-text-color: #fff; 4 | 5 | /** 6 | * @light theme 7 | */ 8 | 9 | // body 10 | $light-background-color: #fff; 11 | $light-text-shadow: 0 0 0.1px rgba(0, 0, 0, 0.3); 12 | $light-hover-text-shadow: 0 0 6px rgba(0, 0, 0, 0.2); 13 | 14 | // index 15 | $dimmed-color: #eef5db; 16 | $light-link-color: #000080; 17 | $dark-gray: #333; 18 | $middle-gray: #7d7d7d; 19 | $light-gray: #aaa; 20 | 21 | // blog-templates 22 | $navigator-text-color: #cc007a; 23 | $navigator-background-color: #fceff7; 24 | $light-blockquote-quote-image: url('/images/quote-black.png'); 25 | $light-blockquote-quote-color: #000; 26 | 27 | // code 28 | $light-inline-dimmed-color: rgba(175, 184, 193, 0.2); 29 | $light-inline-text-color: #212429; 30 | $dark-inline-dimmed-color: rgba(175, 184, 193, 0.2); 31 | $dark-inline-text-color: #d8d8d8; 32 | 33 | // category 34 | $light-category-border-color: #ecf0f2; 35 | $light-category-highlight-border-color: #909da1; 36 | $light-category-background-color: #f4f7f8; 37 | $light-category-text-color: #666; 38 | $light-category-highlight-text-color: #636c6e; 39 | $light-category-item-color: #fff; 40 | 41 | /** 42 | * @dark theme 43 | */ 44 | $dark-background-color: #282c35; 45 | $dark-link-color: #9fa8da; 46 | 47 | $dark-lightest-font-color: #fff; 48 | $dark-light-font-color: #eeeeee; 49 | $dark-middle-font-color: #d8d7d7; 50 | 51 | $dark-text-shadow: 0 0 0.1px rgba(255, 255, 255, 0.3); 52 | $dark-hover-text-shadow: 0 0 6px rgba(255, 255, 255, 0.2); 53 | $dark-blockquote-quote-image: url('/images/quote-white.png'); 54 | $dark-blockquote-quote-color: #fff; 55 | 56 | $dark-category-item-color: #282c35; 57 | $dark-category-background-color: #24272c; 58 | 59 | $dark-category-border-color: rgb(56, 54, 54); 60 | $dark-category-text-color: #d8d7d7; 61 | 62 | $dark-category-highlight-border-color: #666; 63 | $dark-category-highlight-text-color: #fff; -------------------------------------------------------------------------------- /src/templates/blog-post.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react' 2 | import { graphql } from 'gatsby' 3 | 4 | import * as Elements from '../components/elements' 5 | import { Layout } from '../layout' 6 | import { Head } from '../components/head' 7 | import { PostTitle } from '../components/post-title' 8 | import { PostDate } from '../components/post-date' 9 | import { PostContainer } from '../components/post-container' 10 | import { SocialShare } from '../components/social-share' 11 | import { SponsorButton } from '../components/sponsor-button' 12 | import { Bio } from '../components/bio' 13 | import { PostNavigator } from '../components/post-navigator' 14 | import { Disqus } from '../components/disqus' 15 | import { Utterences } from '../components/utterances' 16 | import * as ScrollManager from '../utils/scroll' 17 | 18 | import '../styles/code.scss' 19 | import '../styles/post.scss' 20 | 21 | export default ({ data, pageContext, location }) => { 22 | useEffect(() => { 23 | ScrollManager.init() 24 | return () => ScrollManager.destroy() 25 | }, []) 26 | 27 | const post = data.markdownRemark 28 | const metaData = data.site.siteMetadata 29 | const { title, comment, siteUrl, author, social } = metaData 30 | const { disqusShortName, utterances } = comment 31 | const { title: postTitle, date, thumbnail } = post.frontmatter 32 | const thumbnailSrc = thumbnail 33 | ? `${siteUrl}${thumbnail.childImageSharp.fixed.src}` 34 | : undefined 35 | 36 | return ( 37 | 38 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {!!disqusShortName && ( 52 | 58 | )} 59 | {!!utterances && } 60 | 61 | ) 62 | } 63 | 64 | export const pageQuery = graphql` 65 | query BlogPostBySlug($slug: String!) { 66 | site { 67 | siteMetadata { 68 | title 69 | author 70 | siteUrl 71 | comment { 72 | disqusShortName 73 | utterances 74 | } 75 | social { 76 | twitter 77 | facebook 78 | } 79 | } 80 | } 81 | markdownRemark(fields: { slug: { eq: $slug } }) { 82 | id 83 | excerpt(pruneLength: 283) 84 | html 85 | frontmatter { 86 | title 87 | date(formatString: "MMMM DD, YYYY") 88 | thumbnail { 89 | childImageSharp { 90 | fixed(width: 800) { 91 | src 92 | srcSet 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | ` 100 | -------------------------------------------------------------------------------- /src/utils/dom.js: -------------------------------------------------------------------------------- 1 | const BODY = 'body' 2 | 3 | export const getElements = selector => document.querySelectorAll(selector) 4 | export const getElement = selector => document.querySelector(selector) 5 | export const addClass = (element, className) => element.classList.add(className) 6 | export const removeClass = (element, className) => 7 | element.classList.remove(className) 8 | export const hasClass = (element, className) => 9 | element.classList.contains(className) 10 | export const getBody = () => getElement(BODY) 11 | export const addClassToBody = className => addClass(getBody(), className) 12 | export const removeClassToBody = className => removeClass(getBody(), className) 13 | export const hasClassOfBody = className => hasClass(getBody(), className) 14 | export const getRect = className => 15 | getElement(className).getBoundingClientRect() 16 | export const getPosY = className => getRect(className).y 17 | 18 | export const getDocumentHeight = () => document.documentElement.offsetHeight 19 | -------------------------------------------------------------------------------- /src/utils/event-manager.js: -------------------------------------------------------------------------------- 1 | export function toFit( 2 | cb, 3 | { dismissCondition = () => false, triggerCondition = () => true } 4 | ) { 5 | if (!cb) { 6 | throw Error('Invalid required arguments') 7 | } 8 | 9 | let tick = false 10 | 11 | return function() { 12 | if (tick) { 13 | return 14 | } 15 | 16 | tick = true 17 | return requestAnimationFrame(() => { 18 | if (dismissCondition()) { 19 | tick = false 20 | return 21 | } 22 | 23 | if (triggerCondition()) { 24 | tick = false 25 | return cb() 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/scroll.js: -------------------------------------------------------------------------------- 1 | import SmoothScroll from 'smooth-scroll/dist/smooth-scroll.min' 2 | 3 | let scroll 4 | 5 | export function init() { 6 | scroll = new SmoothScroll('a[href*="#"]', { 7 | speed: 500, 8 | speedAsDuration: true, 9 | }) 10 | return scroll 11 | } 12 | 13 | export function destroy() { 14 | if (!scroll) throw Error('Not founded SmoothScroll instance') 15 | 16 | scroll.destroy() 17 | scroll = null 18 | 19 | return scroll 20 | } 21 | 22 | export function go(dest) { 23 | if (!scroll) throw Error('Not founded SmoothScroll instance') 24 | 25 | scroll.animateScroll(dest) 26 | 27 | return scroll 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/share.js: -------------------------------------------------------------------------------- 1 | export const shareToFacebook = (href, text) => { 2 | window.FB.ui({ 3 | method: 'share', 4 | mobile_iframe: true, 5 | href, 6 | quote: text, 7 | }) 8 | } 9 | 10 | export const shareToTwitter = (href, text) => { 11 | window.open( 12 | `https://twitter.com/share?url=${encodeURI(encodeURI(href))}&text=${text}`, 13 | 'sharer', 14 | 'toolbar=0,status=0,width=626,height=436' 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /src/utils/storage/browser.js: -------------------------------------------------------------------------------- 1 | const win = typeof window !== `undefined` ? window : {} 2 | 3 | export const localStorage = win.localStorage 4 | export const sessionStorage = win.sessionStorage 5 | -------------------------------------------------------------------------------- /src/utils/storage/core.js: -------------------------------------------------------------------------------- 1 | function isEmpty(storage) { 2 | return !storage || storage === {} 3 | } 4 | 5 | export function getValueFrom(storage, key) { 6 | if (isEmpty(storage)) { 7 | return 8 | } 9 | const rawData = storage.getItem(key) 10 | 11 | if (!rawData) { 12 | return 13 | } 14 | return JSON.parse(rawData) 15 | } 16 | 17 | export function setValueTo(storage, key, data) { 18 | if (isEmpty(storage)) { 19 | return 20 | } 21 | return storage.setItem(key, JSON.stringify(data)) 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/storage/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | setValueToSessionStorage, 3 | getValueFromSessionStorage, 4 | } from './sessionStorage' 5 | import { 6 | setValueToLocalStorage, 7 | getValueFromLocalStorage, 8 | } from './localStorage' 9 | 10 | const SESSION_STORAGE_KEY = '__felog_session_storage_key__' 11 | const LOCAL_STORAGE_KEY = '__felog_local_storage_key__' 12 | 13 | export function getCount(defaultValue) { 14 | return ( 15 | getValueFromSessionStorage(`${SESSION_STORAGE_KEY}/count`) || defaultValue 16 | ) 17 | } 18 | 19 | export function setCount(val) { 20 | return setValueToSessionStorage(`${SESSION_STORAGE_KEY}/count`, val) 21 | } 22 | 23 | export function getCategory(defaultValue) { 24 | return ( 25 | getValueFromSessionStorage(`${SESSION_STORAGE_KEY}/category`) || 26 | defaultValue 27 | ) 28 | } 29 | 30 | export function setCategory(val) { 31 | return setValueToSessionStorage(`${SESSION_STORAGE_KEY}/category`, val) 32 | } 33 | 34 | export function getTheme(defaultValue) { 35 | return getValueFromLocalStorage(`${LOCAL_STORAGE_KEY}/theme`) || defaultValue 36 | } 37 | 38 | export function setTheme(val) { 39 | return setValueToLocalStorage(`${LOCAL_STORAGE_KEY}/theme`, val) 40 | } -------------------------------------------------------------------------------- /src/utils/storage/localStorage.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | 3 | import { setValueTo, getValueFrom } from './core' 4 | import { localStorage } from './browser' 5 | 6 | export const setValueToLocalStorage = _.partial(setValueTo, localStorage) 7 | export const getValueFromLocalStorage = _.partial(getValueFrom, localStorage) 8 | -------------------------------------------------------------------------------- /src/utils/storage/sessionStorage.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | 3 | import { setValueTo, getValueFrom } from './core' 4 | import { sessionStorage } from './browser' 5 | 6 | export const setValueToSessionStorage = _.partial(setValueTo, sessionStorage) 7 | export const getValueFromSessionStorage = _.partial( 8 | getValueFrom, 9 | sessionStorage 10 | ) 11 | -------------------------------------------------------------------------------- /src/utils/typography.js: -------------------------------------------------------------------------------- 1 | import Typography from 'typography' 2 | import GitHubTheme from 'typography-theme-github' 3 | 4 | GitHubTheme.overrideThemeStyles = () => { 5 | return { 6 | a: { 7 | boxShadow: `none`, 8 | textDecoration: `none`, 9 | color: `#0687f0`, 10 | }, 11 | 'a.gatsby-resp-image-link': { 12 | boxShadow: `none`, 13 | textDecoration: `none`, 14 | }, 15 | 16 | 'a:hover': { 17 | textDecoration: `none`, 18 | }, 19 | 20 | h1: { 21 | fontWeight: 800, 22 | lineHeight: 1.2, 23 | fontFamily: 'Catamaran', 24 | }, 25 | 26 | h2: { 27 | fontWeight: 700, 28 | lineHeight: 1.2, 29 | marginTop: '56px', 30 | marginBottom: '20px', 31 | fontFamily: 'Catamaran', 32 | }, 33 | 34 | ul: { 35 | marginBottom: '6px', 36 | }, 37 | 38 | li: { 39 | marginBottom: '2px', 40 | }, 41 | } 42 | } 43 | 44 | const typography = new Typography(GitHubTheme) 45 | 46 | // Hot reload typography in development. 47 | if (process.env.NODE_ENV !== `production`) { 48 | typography.injectStyles() 49 | } 50 | 51 | export default typography 52 | export const rhythm = typography.rhythm 53 | export const scale = typography.scale 54 | -------------------------------------------------------------------------------- /src/utils/visible.js: -------------------------------------------------------------------------------- 1 | import * as Dom from './dom' 2 | 3 | const ROOT_ID = '#___gatsby' 4 | export const TARGET_CLASS = 'observed' 5 | const VISIBLE_RECOGNIZE_CLASS = 'visible' 6 | const INTERSECTION_OBSERVER_ROOT_MARGIN = '20px' 7 | const INTERSECTION_OBSERVER_THRESHOLD = 0.8 8 | 9 | let observer 10 | 11 | function observeCallback(entries) { 12 | return entries 13 | .filter(({ isIntersecting }) => isIntersecting) 14 | .forEach(({ target }) => Dom.addClass(target, VISIBLE_RECOGNIZE_CLASS)) 15 | } 16 | 17 | function observerTargeting() { 18 | return Dom.getElements(`.${TARGET_CLASS}`).forEach(el => observer.observe(el)) 19 | } 20 | 21 | function disconnect() { 22 | if (!observer) { 23 | throw Error('Not found IntersectionObserver instance') 24 | } 25 | return Promise.resolve(observer.disconnect()) 26 | } 27 | 28 | export function init() { 29 | observer = new IntersectionObserver(observeCallback, { 30 | root: Dom.getElement(ROOT_ID), 31 | rootMargin: INTERSECTION_OBSERVER_ROOT_MARGIN, 32 | threshold: INTERSECTION_OBSERVER_THRESHOLD, 33 | }) 34 | 35 | return observerTargeting() 36 | } 37 | 38 | export function destroy() { 39 | return disconnect().then(() => (observer = null)) 40 | } 41 | 42 | export function refreshObserver() { 43 | return disconnect().then(observerTargeting) 44 | } 45 | -------------------------------------------------------------------------------- /static/ads.txt: -------------------------------------------------------------------------------- 1 | google.com, pub-1175788313024686, DIRECT, f08c47fec0942fa0 -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/static/favicon.ico -------------------------------------------------------------------------------- /static/images/quote-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/static/images/quote-black.png -------------------------------------------------------------------------------- /static/images/quote-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/static/images/quote-white.png -------------------------------------------------------------------------------- /static/resume_thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoYoung210/SOSO/d28df1e804bef6b8f8ff3e940e344a417f27641e/static/resume_thumbnail.jpg -------------------------------------------------------------------------------- /static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | --------------------------------------------------------------------------------