쉘에서 핫 리로드되는 작은 정적 사이트 생성기입니다. Bash 4.4 이상을 가정합니다.
경고: 여기 야크가 있습니다!
shite
의 임무는 내 웹사이트(https://evalapply.org)를 만드는 데 도움을 주는 것입니다. 따라서 shite
의 범위, (잘못된) 기능 세트, Polish는 항상 프로덕션 등급이 될 것입니다. 여기서 프로덕션은 "내 컴퓨터에서 작동합니다. )" :)
목차
글쎄요, shite
웹사이트를 만드는 것을 목표로 하고 있습니다.
이는 선택적으로 파일 이벤트 스트림(핫 리로딩 비트의 경우)에 의해 구동되는 파이프라인 워크플로로 만들어진 간단한 게시 시스템입니다.
지난 세기의 Perl/PHP 신사 해커라면 놀랄 일이 아닐 것입니다.
그것은 어리석은 노래를 휘파람으로 불고 야크를 면도하기 때문에 존재합니다.
이것이 기본적으로 수행되는 작업입니다(참조: shite_templating_publish_sources
함수).
cat " ${watch_dir} /sources/ ${url_slug} " |
__shite_templating_compile_source_to_html ${file_type} |
__shite_templating_wrap_content_html ${content_type} |
__shite_templating_wrap_page_html |
${html_formatter_fn} |
tee " ${watch_dir} /public/ ${slug} .html "
# The complete "business logic" is 300-ish lines as of this comment,
# counted as all lines except comments and blank lines.
grep -E -v " s?#|^$ "
./bin/{events,metadata,templating,utils,hotreload}.sh |
wc -l
당신이 너무 흥분하기 전에, MIT 라이센스는 이 작은 똥 제작자가 당신의 똥을 작동시키지 못하더라도 내가 똥을 줄 필요가 없다는 것을 의미한다는 것을 경고하고 싶습니다. 기여에는 더 많은 경고가 있습니다.
그리고 마지막으로, 여기에 있는 모든 텍스트를 Sean Connery의 음성으로 읽을 것을 선언합니다.
내 shite
꿈속에서 나는 욕망한다...
무엇보다도 ("비즈니스 로직") 작게 유지하는 것입니다. 머리 속에 캐시하고, 디버그하고, 리팩터링할 수 있을 만큼 작습니다.
슈퍼유저 권한 없이 설치하고 사용하려면
툴체인을 극도로 피하고 종속성을 구축합니다. gems/npms/venvs/what-have-yous가 없습니다. 따라서 Bash는 어디에나 있기 때문에 Bash가 언어입니다. 특정 고급 기능이 필요한 경우 pandoc
또는 tidy
와 같은 표준 패키지도 있습니다.
좋은 heredocs에 설정된 일반 HTML을 사용한 종속성 없는 템플릿입니다.
간단한 메타데이터 시스템, 콘텐츠 네임스페이스, 정적 자산 구성 등
웹 서버는 선택 사항입니다(또는 해당 문제에 대한 모든 종류의 서버 프로세스). 결국 우리는 file://
탐색과 잘 작동하는 정적 사이트를 목표로 합니다.
작고 구성 가능하며 순전히 기능적인 Unix 도구 같은 부분으로 구성하는 것입니다. 왜냐하면 저는 그런 종류의 것을 매우 좋아하기 때문입니다.
REPL과 유사한 편집-저장-빌드-미리 보기 워크플로를 원활하게 제공합니다.
오랜 공백 끝에 실수로 블로그를 다시 시작하게 되었습니다. 클라우드에 단어를 넣기 전에 나는 "현대적인" 정적 사이트 생성기를 사용하여 혼란스러워했습니다. WordPress는 지난 세기이기 때문입니다(또는 스스로에게 그렇게 말했습니다). 그러다가 SSG Jamstack 맞춤형 템플릿 구축 등의 마법에 짜증이 났습니다. 이제 나는 이것을 만드는 어두운 길에 있습니다. 다음 위치에서 블로그에 게시되고 있습니다: Shite: Shell의 정적 사이트: 1/2부
나는 주로 "hotreload" 모드에서 똥을 사용하는데, 주로 게시물을 작성하고(orgmode에서) 실시간으로 미리보기(Firefox에서)합니다. 덜 주로, 스타일 및/또는 페이지 템플릿에 대한 수정 사항을 핫 미리보기로 사용합니다. 적어도 주로, 게시물에 대해 끝없이 노력한 후에는 "핫 리로드하지 않음" 모드에서 전체 사이트 재구축을 수행하는 데 사용합니다.
아래 데모 예시를 살펴보세요.
기본적으로 이는 sources
아래에 있는 파일을 생성, 업데이트, 삭제하는 경우 해당 파일이 자동으로 HTML로 변환되고 로컬에서 public
로 게시되어야 하며 내 사이트가 열려 있는 웹 브라우저에서 적절한 페이지 탐색 또는 다시 로드 작업이 발생해야 함을 의미합니다.
새로운 터미널 세션이나 tmux 창에서 "main" 스크립트를 호출하세요.
./shite.sh
./shite.sh
의 shite_global_data
배열에 설정한 기본값에 따라 Firefox에서 인덱스 파일을 여는 데 유용합니다.
Emacs 또는 Vim에서 sources
아래의 일부 콘텐츠 파일을 엽니다. 콘텐츠를 편집하고 저장하고 브라우저에 나타나는 내용을 확인하세요. (예, Emacs/Vim을 지정하는 것은 어리석은 일입니다. 왜냐하면 나는 inotify 이벤트를 기반으로 핫 액션을 실행하기 때문입니다. 분명히 다른 편집자들은 파일 업데이트를 다르게 수행합니다. 저는 Emacs나 Vim을 사용하기 때문에 그들이 일으키는 이벤트를 감시하므로 내 컴퓨터에서 작동합니다. : )).
브라우저는 스크롤 위치를 기억하는 경우가 많습니다. 때때로 핫리로드는 정말 짜증나는 일입니다. 그래서 그냥 스페이스를 누르고 콘텐츠 파일을 저장하여 핫 리로드를 다시 실행했습니다.
CSS 스타일시트와 같은 일부 정적 자산으로 이동합니다. 배경색 값과 같은 것을 변경하십시오. 브라우저에서 색상 변화를 저장하고 관찰하십시오.
templates.sh
의 일부 템플릿 조각(예: 블로그 게시물 템플릿)을 조정합니다. 그런 다음 일부 블로그 게시물 콘텐츠 파일로 전환하고 수정된 템플릿으로 페이지 빌드를 트리거하도록 수정합니다(예: 히트 스페이스 및 저장).
이것은 해킹입니다. 소스 아래의 루트 index.org 페이지는 특별합니다. 이를 수정한다는 것은 인덱스 페이지, 태그에 대한 게시물 목록을 다시 작성하고 RSS 피드, 사이트맵, robots.txt 등과 같은 관련 메타 파일도 다시 작성한다는 의미입니다.
깨끗한 새 터미널 세션에서 "no"를 사용하고 선택적으로 배포 환경의 base_url
사용하여 shite.sh
호출합니다.
"로컬" file:/// 탐색을 위해 전체 사이트를 재구축합니다. 진정한 "서버리스" :)
./shite.sh " no "
내 도메인에 게시할 수 있도록 전체 사이트를 다시 구축하세요.
./shite.sh " no " " https://evalapply.org "
이러한 플래그는 시스템의 동작을 변경합니다.
SHITE_BUILD
"hot"으로 설정하면 이벤트 시스템이 "모니터" 모드로 실행되고, 결과적으로 hotreload 동작이 구동됩니다. "no"로 설정하면 브라우저 핫 리로드가 억제됩니다.SHITE_DEBUG_TEMPLATES
"디버그"로 설정하면 템플릿 기반 소스 콘텐츠를 게시하기 전에 템플릿이 먼저 소싱됩니다. shite
내부가 꽤 Unixy입니다. 아니면 그렇게 생각하고 싶습니다.
코드는 함수형 프로그래밍 스타일의 Bash입니다. 모든 것은 함수입니다. 대부분의 함수는 순수한 함수입니다. 그 자체로는 작은 Unix 도구입니다. 대부분의 논리는 파이프라인 지향적입니다. Shell은 FP에 나쁜 곳이 아니기 때문에 이것은 놀랍게도 잘 작동합니다.
또한 나는 Clojure 및 Emacs와 같은 실시간/대화형 런타임에서 작업하는 것을 좋아하기 때문에 shite
로 작성할 때 실시간 대화형 REPL과 같은 경험을 원했습니다.
shite
핫 빌드 및 저장 시 다시 로드가 가능한 완전 반응형 이벤트 기반 시스템이 되었습니다.
세 가지 주요 디렉터리 네임스페이스가 있습니다.
sources
입니다.public
대상bin
URL 명명 체계는 sources
아래의 하위 디렉터리 구조를 따르며 pubilic
디렉터리 구조 아래에 있는 그대로 복제됩니다. 이는 습지 표준 URL 네임스페이스 체계이므로 게시된 콘텐츠에도 직접 적용됩니다. 다음과 같습니다:
file:///absolute/path/to/shite/posts/slug/index.html
http://localhost:8080/posts/slug/index.html
https://your-domain-name.com/posts/slug/index.html
모든 "공용" 함수는 shite_the_func_name
으로 네임스페이스가 지정됩니다. 모든 "비공개" 함수는 __shite_the_func_name
으로 네임스페이스가 지정됩니다.
기능은 다음과 같습니다.
깨끗한 새 터미널 세션에서:
source ./bin/utils_dev.sh
shitTABTAB
또는 __shiTABTAB
누르세요.type -a func_name
입력하세요.shite_global_data
및 shite_page_data
설정합니다. 페이지 조각(예: 머리글, 바닥글, 탐색) 및 전체 페이지 정의(예: 기본 페이지 템플릿)에 대한 템플릿이 있습니다. 이는 heredocs에 포함된 일반 HTML로 작성됩니다. ./bin/templates.sh
이를 제공합니다.
템플릿은 다양한 소스의 가변 데이터로 채워집니다.
shite_global_data
에는 사이트 전체 메타데이터가 포함되고, shite_page_data
에는 페이지별 메타데이터가 포함됩니다. 일부 외부 프로세스는 페이지를 처리하기 전에 이러한 배열을 미리 설정해야 합니다.예를 들어 전체 페이지는 다음과 같이 구성될 수 있습니다.
cat ./sample/hello.md |
pandoc -f markdown -t html |
cat << EOF
<!DOCTYPE html>
<html>
<head>
$( shite_template_common_meta )
$( shite_template_common_links )
${shite_page_data[canonical_url]}
</head>
<body ${shite_page_data[page_id]} >
$( shite_template_common_header )
<main>
$( cat - )
</main>
$( shite_template_common_footer )
</body>
</html>
EOF
shite
의 메타데이터 시스템은 키-값 쌍으로 정의됩니다. 키는 메타데이터 항목의 이름을 지정하며 해당 유형의 모든 값과 연결됩니다. 아래 예.
앞서 언급한 것처럼 런타임 메타데이터는 연관 배열 shite_global_data
및 shite_page_data
에 의해 환경에 전달됩니다. 이는 직접 구성으로 채워질 수도 있고 외부 소스에서 업데이트될 수도 있습니다.
각 페이지는 페이지 상단의 "머리말"에 자체 메타데이터를 지정할 수 있습니다. 이는 다른 소스에서 파생된 페이지 메타데이터에도 사용됩니다.
shite
다음과 같이 주어진 콘텐츠 유형과 호환되는 구문을 사용하여 머리말을 작성하기를 기대합니다.
주석 줄 # SHITE_META
사용하여 페이지별 메타데이터로도 shite
분석해야 하는 조직 스타일 메타데이터를 구분합니다.
# SHITE_META
#+title: This is a Title
#+slug: this/is/a/slug
#+date: Friday 26 August 2022 03:38:01 PM IST
#+tags: foo bar baz quxx
# SHITE_META
#+more_org_metadata: but not processed as shite metadata
#+still_more_org_metadata: and still not processed as shite metadata
* this is a top level heading
this is some orgmode content
#+TOC: headlines 1 local
** this is a sub heading
- this is a point
- this is another point
- a third point
Jekyll 스타일 YAML 머리말을 ---
구분 기호 사이에 넣어 작성하세요.
---
TITLE : This is a Title
slug : this/is/a/slug
DATE : Friday 26 August 2022 03:38:01 PM IST
TAGS : foo BAR baz QUXX
---
# this is a heading
this is some markdown content
## this is a subheading
- this is a point
- this is another point
- a third point
<meta name="KEY" content="value">
규칙을 준수하는 표준 <meta>
태그를 간단히 사용할 수 있습니다.
< meta name =" TITLE " content =" This is a Title " >
< meta name =" slug " content =" this/is/a/slug " >
< meta name =" DATE " content =" Friday 26 August 2022 03:38:01 PM IST " >
< meta name =" TAGS " content =" foo BAR baz QUXX " >
< h1 > This is a heading </ h1 >
< p > This is some text </ p >
< h2 > This is a subheading </ h2 >
< p >
< ul >
< li > This is a point </ li >
< li > This is another point. </ li >
< li > This is a third point. </ li >
</ ul >
</ p >
여기 야크가 있습니다!
Clojure/Lisp/Spreadsheet 스타일의 인스타그램을 만족시키는 라이브 대화형 워크플로에 완전히 빠져 있기 때문에 핫 리로드와 핫 탐색도 똥 만들기에 필요합니다.
그러나 알려진 인터넷의 절반을 종속성으로 다운로드하는 것을 원하지 않는 독립형 라이브 웹 개발 서버/도구는 존재하지 않는 것 같습니다. 아까도 말했듯이, 나는 정말 하고 싶지 않은 일이다.
DuckSearch는 Emacs에 참을성 없는 모드를 제공했는데, 이는 꽤 인기가 있지만 저는 이것을 Emacs에 직접 연결하고 싶지 않습니다. 운 좋게도 'inotify-tools' 및 'xdotool'을 특징으로 하는 이 흥미로운 브레인웨이브도 전달되었습니다: github.com/traviscross/inotify-refresh
핫 카피!
내 컴퓨터가 F5 키를 누르는 것 보다 더 뜨거운 것이 있을까요? 마치 내가 마음 속 깊이 원하는 것이 무엇인지 아는 것처럼.
이벤트 하위 시스템은 다른 모든 것과 직교하며 시스템의 나머지 부분과 구성됩니다.
디자인은 늪지 표준 스트리밍 아키텍처입니다. 파일 시스템 이벤트를 감시한 다음 이를 필터링, 중복 제거, 분석하고 다른 이벤트 프로세서로 라우팅합니다. 현재 이러한 프로세서는 두 개뿐입니다. 하나는 이벤트와 관련된 페이지나 자산을 컴파일하고 게시하기 위한 것이고, 다른 하나는 동일한 이벤트에 따라 브라우저를 핫 리로드(또는 핫 탐색)하기 위한 것입니다.
기본적으로는 다음과 같습니다.
# detect file events
__shite_detect_changes ${watch_dir} ' create,modify,close_write,moved_to,delete ' |
__shite_events_gen_csv ${watch_dir} |
# hot-compile-and-publish content, HTML, static, etc.
tee >( shite_templating_publish_sources > /dev/null ) |
# browser hot-reload
tee >( __shite_hot_cmd_public_events ${window_id} ${base_url} |
__shite_hot_cmd_exec )
이벤트는 다음과 같이 구성된 CSV 레코드의 스트림입니다.
unix_epoch_seconds,event_type,base_dir,sub_dir,url_slug,file_type,content_type `
우리는 다양한 종류의 작업을 발생시키기 위해 이벤트 기록의 다양한 부분을 사용합니다.
앞서 링크된 inotify-refresh 스크립트는 브라우저 창 세트를 주기적으로 새로 고치려고 시도합니다. 그러나 우리는 매우 열망하고 싶습니다. 콘텐츠 파일 및/또는 정적 자산에 대한 모든 편집 작업은 사이트를 표시하는 브라우저 탭에서 핫 리로드/탐색 작업을 즉시 트리거해야 합니다.
우리는 모니터링하려는 파일 이벤트를 매핑할 수 있는 상호 배타적이고 집합적으로 철저한 버킷이라는 고유한 다시 로드 시나리오를 정의하려고 합니다.
이렇게 하면 업데이트를 일종의 미리 쓰기 로그로 모델링하고 분석 파이프라인을 통해 이벤트를 펀칭하고 이를 정확히 일치하는 시나리오와 연결한 다음 최종적으로 작업을 실행할 수 있습니다. 예를 들어:
다음 경우에 현재 탭을 새로 고칩니다.
언제 집에 가세요
다음과 같은 경우 콘텐츠로 이동하세요.
우리는 컴퓨터가 우리 자신의 키보드 동작을 에뮬레이션하도록 만들기 때문에 우리의 개인적인 행동을 망칠 수 있습니다. 우리가 텍스트 편집기에서 우리의 글을 계속 작성하고 컴퓨터가 핫리로드 작업을 하게 한다면 우리는 짜증을 내지 않을 것입니다.
세상에는 많은 야크가 있습니다.
실제로 널리 퍼진 다중 사이트 출판 분야의 경우:
shite
.이것은 작은 야크입니다. 아마 곧 yakshave가 될 것입니다.
분명히 인기 있는 git 호스트의 CI 작업을 사용하여 shite
빌드를 실행할 수 있습니다. 하지만 우리가 이미 1900년대 후반의 최첨단 기술로 발전했는데, 완전한 스트리밍과 완전한 반응성을 갖춘 투박한 현대 기술을 왜 사용합니까?
풍자는 제쳐두고, 내가 실행하는 원격 시스템에서 동일한 이벤트 시스템을 사용하여 핫 배포 지원을 추가할 수 없는 이유를 모르겠습니다.
원격 상자에서:
sources
의 복제본이 보관되어 있습니다.sources
에 대해 실시간으로 진행됩니다(브라우저 관찰 제외).내 로컬 박스에서:
https://mydomain.com/posts/hello/index.html
에서 F5를 누르세요.원격 서버에 핫 배포하는 경우 SSH를 통해 브라우저 새로 고침을 로컬 상자로 다시 가져오려면 작업을 수행하세요.
어쩌면 "개발/초안 작성" 시간 설정/해체 시나리오가 있을까요? 어쩌면 새로운 글쓰기 세션을 시작하는 데 사용하는 'dev_server' 기능일까요?
여기까지 왔는데도 여전히 기여하고 싶다면...
왜?
왜 거룩하고 선한 모든 것의 이름으로 그렇게 하시겠습니까? 이것이 바보의 짓이라는 것이 눈이 멀 정도로 명백하지 않습니까? Bash가 실제 프로그래밍 언어도 아니라는 말을 들어보셨나요? 그리고 당신의 PR이 영원히 시들어버릴 것이고 당신의 코멘트가 이름 없는 공허 속으로 빠져들게 될 것이라는 것은 너무나 명백하지 않습니까?
예, 패치를 보내는 것은 끔찍한 생각입니다.
하지만 당신의 똥 제작자에 대한 당신의 희망과 꿈을 이메일로 보내주세요! Gmail에서 이름과 성으로 된 이메일을 읽었습니다.
우리는 함께 우스꽝스러운 노래를 불고 각자의 야크를 우리만의 특별한 방식으로 깎을 수 있습니다.
근원이 우리와 함께 있기를 바랍니다.
이 저작물은 MIT 라이선스와 CC By-SA 4.0 라이선스에 따라 이중 라이선스를 받았습니다.
SPDX-License-Identifier: mit OR cc-by-sa-4.0