Eleventy (또는 11ty)는 Node.js 정적 사이트 생성기 (SSG)입니다.
SSG는 정적 HTML, CSS 및 JavaScript 파일 세트를 만들기 위해 빌드시 대부분의 렌더링 작업을 수행합니다. 결과 페이지에는 런타임 또는 데이터베이스와 같은 서버 측 종속성이 필요하지 않습니다.
https://www.sitepoint.com/getting-started-with-eleventy/
이로 인해 몇 가지 주요 이점이 있습니다.
Eleventy는 점점 인기를 얻었으며 웹 개발의 유명인으로부터 주목을 받고 있습니다. 콘텐츠 사이트 및 블로그에 적합하지만 온라인 상점 및 보고 시스템에 맞게 조정되었습니다.
대부분의 경우 Eleventy를 사용하여 Nunchucks와 같은 엔진으로 구동 되는 템플릿에 콘텐츠를 삽입하는 Markdown 문서에서 HTML 페이지를 생성합니다. 그러나 이 튜토리얼에서는 Eleventy를 모든 자산에 대한 완전한 빌드 시스템으로 사용하는 방법도 보여줍니다. npm 스크립트, webpack 또는 Gulp.js와 같은 별도의 시스템이 반드시 필요한 것은 아니지만 자동화 된 빌드 및 실시간 재로드를 계속 즐길 수 있습니다.
JavaScript 프레임 워크가 필요하십니까?
몇몇 SSG는 React 또는 Vue.js와 같은 클라이언트 측 JavaScript 프레임 워크를 채택합니다. Eleventy와 함께 프레임 워크를 사용할 수 있지만 적용되지는 않습니다.
제 생각에는 복잡한 앱을 만들지 않는 한 JavaScript 프레임 워크가 필요하지 않을 것입니다. 앱을 만드는 경우 SSG는 올바른 도구가 아닙니다!
코드보기
Eleventy는 단순하다고 주장하지만 기본을 넘어 서면 어려울 수 있습니다. 이 튜토리얼은 페이지와 블로그 / 기사 게시물이 있는 간단한 사이트를 구축하는 방법을 보여줍니다.이 작업은 종종 WordPress에서 처리합니다.
전체 코드는 https://github.com/craigbuckler/11ty-starter에서 확인할 수 있습니다. 터미널에 다음 명령을 입력하여 Windows, macOS 또는 Linux에서 다운로드, 설치 및 실행할 수 있습니다.
git clone https://github.com/craigbuckler/11ty-starter
cd 11ty-starter
npm i
npx eleventy --serve
그런 다음 브라우저에서 http://localhost:8080의 홈페이지로 이동합니다.
아래 단계는 사이트를 처음부터 구축하는 방법을 설명합니다.
Eleventy 설치
Node.js 프로젝트와 마찬가지로 먼저 디렉터리를 만들고 package.json 파일을 초기화합니다.
mkdir mysite
cd mysite
npm init
그런 다음 Eleventy를 개발 종속성으로 설치하십시오.
npm i @11ty/eleventy --save-dev
참고 :이 프로젝트는 개발 머신에서만 실행하면 되므로 개발 종속성으로 모듈을 설치합니다. 자동화 된 빌드 프로세스가 있는 일부 호스트는 표준 런타임 종속성을 사용해야 할 수 있습니다.
첫 페이지 렌더링
모든 소스 파일이 상주 할 src 디렉토리를 만든 다음 그 안에 index.md 파일을 만듭니다. 다음과 같은 홈 페이지 컨텐츠를 추가하십시오.
‐‐‐
title: 11ty starter site
‐‐‐
This is a demonstration website using the [11ty static site generator](https://www.11ty.dev/). It shows pages, blog posts, lists, and tags.
The whole build process is managed through 11ty.
‐‐‐ 대시 마커 사이의 내용을 서문이라고 합니다. Eleventy 및 템플릿에 대한 매개 변수를 설정하는 데 사용할 수 있는 페이지에 대한 이름-값 메타 데이터를 정의합니다. 여기에는 제목 만 설정되어 있지만 곧 설명, 날짜, 태그 및 기타 데이터를 추가하게 됩니다.
.eleventy.js라는 Eleventy 구성 파일이 프로젝트의 루트 폴더에 생성되어야 합니다. 이 간단한 예제 코드는 다음을 지정하는 객체를 반환합니다.
// 11ty configuration
module.exports = config => {
// 11ty defaults
return {
dir: {
input: 'src',
output: 'build'
}
};
};
사이트를 구축하고 Browsersync로 구동 되는 라이브 리로딩 서버를 시작하려면 다음을 입력하십시오.
npx eleventy --serve
Eleventy는 src 디렉토리에서 찾은 모든 것을 렌더링하고 빌드 할 결과 콘텐츠를 출력합니다.
$ npx eleventy --serve
Writing build/index.html from ./src/index.md.
Wrote 1 file in 0.12 seconds (v0.11.0)
Watching...
[Browsersync] Access URLs:
---------------------------------------
Local: http://localhost:8080
External: http://172.27.204.106:8080
---------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
---------------------------------------
[Browsersync] Serving files from: build
이 경우 브라우저에서 URL http://localhost:8080을 로드하여 단일 build/index.html 파일에 액세스 할 수 있습니다.
build/index.html에서 생성 된 HTML 파일에는 src/index.md의 마크 다운 파일에서 렌더링 된 콘텐츠가 포함되어 있습니다.
<p>This is a demonstration website using the <a href="https://www.11ty.dev/">11ty static site generator</a>. It shows pages, blog posts, lists, and tags.</p>
<p>The whole build process is managed through 11ty.</p>
Eleventy 서버는 Ctrl | Cmd + C.
참고 : 새 파일이 자동으로 렌더링 되므로 사이트 개발 중에 Eleventy를 중지 할 필요가 거의 없습니다. 그러나 아래 섹션에서는 추가 구성 옵션을 추가하므로 다시 시작해야 합니다.
템플릿 생성
Eleventy는 거의 모든 JavaScript 템플릿 엔진을 사용할 수 있습니다. Nunchucks는 포괄적이고 11ty.dev의 문서 전체에서 사용되기 때문에 좋은 옵션입니다.
src / index.md의 머리말을 다음과 같이 변경하십시오.
‐‐‐
title: 11ty starter site
description: This is a demonstration website generated using the 11ty static site generator.
layout: page.njk
‐‐‐
이것은 Eleventy가 레이아웃에 page.njk Nunchucks 템플릿을 사용하도록 지시합니다. 기본적으로 Eleventy는 소스 디렉토리 (src /)의 _includes 하위 디렉토리에서 템플릿을 찾습니다. 여기에 있는 모든 파일은 자체적으로 렌더링 되지 않지만 빌드 프로세스 중에 사용됩니다.
src/_includes/page.njk에서 이 새 템플릿을 만듭니다.
{% include "partials/htmlhead.njk" %}
<main>
{% block content %}
<h1>{{ title }}</h1>
{{ content | safe }}
{% endblock %}
</main>
{% include "partials/htmlfoot.njk" %}
템플릿은 페이지의 서문에 정의 된 제목을 <h1> 제목 내에 배치하고 {{content}}를 마크 다운에서 생성 된 HTML로 대체합니다. (안전한 Nunchucks 필터를 사용하여 따옴표와 꺾쇠 괄호를 이스케이프 하지 않고 HTML을 출력합니다.)
두 개의 {% include %} 정의 참조 파일은 템플릿에 포함되어 있습니다. 페이지의 제목과 설명도 사용하는 src / _includes / partials / htmlhead.njk에서 HTML 헤더 파일을 만듭니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title }}</title>
<meta name="description" content="{{ description }}">
</head>
<body>
그런 다음 src / _includes / partials / htmlfoot.njk에 HTML 바닥 글을 만듭니다.
</body>
</html>
npx eleventy --serve를 사용하여 Eleventy를 중지하고 다시 시작하십시오.
렌더링 된 build \ index.html 파일은 이제 완전한 형식의 HTML 페이지를 포함합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>11ty starter site</title>
<meta name="description" content="This is a demonstration website generated using the 11ty static site generator.">
</head>
<body>
<h1>11ty starter site</h1>
<p>This is a demonstration website using the <a href="https://www.11ty.dev/">11ty static site generator</a>. It shows pages, blog posts, lists, and tags.</p>
<p>The whole build process is managed through 11ty.</p>
</body>
</html>
참고 : 브라우저 내에서 소스를 보면 <body> 요소 뒤에 BrowserSync에서 추가 한 <script>도 볼 수 있습니다. 이는 실시간 재로드를 트리거 하는 데 사용되며 최종 빌드에는 표시되지 않습니다 (아래의 "제작 사이트 구축"섹션 참조).
추가 페이지 생성
이제 필수 "회사 소개"섹션과 같은 추가 콘텐츠를 만들 수 있습니다.
src/about/index.md
:
‐‐‐
title: About us
description: What we do.
‐‐‐
Some information about us.
src/about/team.md
:
‐‐‐
title: Our team
description: Information about us.
‐‐‐
Who are we and what we do.
src/about/privacy.md:
‐‐‐
title: Privacy policy
description: We keep your details private.
‐‐‐
Our privacy policy.
이 파일 중 어느 것도 서문에서 템플릿을 참조하지 않습니다. Eleventy를 사용하면 <directory-name> .json 파일을 생성하여 디렉토리의 모든 파일에 대한 기본값을 정의 할 수 있습니다. 이 경우 이름은 src / about / about.json입니다. 페이지의 서문에 명시 적으로 정의되지 않은 경우 사용할 JSON 값을 설정합니다.
{
"layout": "page.njk"
}
npx eleventy --serve를 다시 실행하고 빌드 폴더를 조사하여 사이트가 어떻게 형성되기 시작하는지 확인합니다.
따라서 브라우저에서 슬러그와 유사한 URL을 사용할 수 있습니다. 예를 들어 http://localhost:8080/about/team/은 팀 페이지 index.html 파일을 표시합니다.
안타깝게도 페이지를 탐색하는 것은 불가능합니다! 메뉴가 필요합니다 ...
탐색 메뉴 만들기
Eleventy는 다음을 입력하여 설치되는 표준 탐색 플러그인을 제공합니다.
npm i @11ty/eleventy-navigation --save-dev
플러그인은 최종 return 문 전에 .eleventy.js 구성 파일에서 참조되어야 합니다.
// 11ty configuration
module.exports = config => {
/* --- PLUGINS --- */
// navigation
config.addPlugin( require('@11ty/eleventy-navigation') );
// 11ty defaults
return {
dir: {
input: 'src',
output: 'build'
}
};
};
eleventyNavigation : 메뉴에서 원하는 모든 페이지에 앞부분 섹션을 정의해야 합니다. 이 섹션은 다음을 설정합니다.
src / index.md의 홈페이지 머리말은 그에 따라 업데이트 될 수 있습니다 :
‐‐‐
title: 11ty starter site
description: This is a demonstration website generated using the 11ty static site generator.
layout: page.njk
eleventyNavigation:
key: home
order: 100
‐‐‐
src / about / index.md의 정보 페이지 :
‐‐‐
title: About us
description: What we do.
eleventyNavigation:
key: about
order: 200
‐‐‐
src / about / team.md의 팀 페이지 :
‐‐‐
title: Our team
description: Information about us.
eleventyNavigation:
key: team
parent: about
order: 210
‐‐‐
src / about / privacy.md의 개인 정보 보호 정책 페이지 :
‐‐‐
title: Privacy policy
description: We keep your details private.
eleventyNavigation:
key: privacy
parent: about
order: 220
‐‐‐
참고 : 10 배 이상의 order 값을 사용하면 나중에 수동으로 번호를 다시 매기 지 않고도 다른 페이지 사이에 페이지를 삽입 할 수 있습니다.
이제 탐색 메뉴를 src / _includes / page.njk의 페이지 템플릿에 추가 할 수 있습니다.
{% include "partials/htmlhead.njk" %}
<header>
<nav>
{{ collections.all | eleventyNavigation | eleventyNavigationToHtml | safe }}
</nav>
</header>
<main>
...
이것은 모든 페이지를 검사하고 eleventyNavigation() 함수로 필터링하여 계층 목록을 생성하는 마법의 Eleventy 플러그인 코드입니다. 해당 목록 렌더링은 eleventyNavigationToHtml() 함수를 사용하여 HTML로 렌더링 됩니다.
다시 시작 npx eleventy --serve 메뉴를 보려면 페이지를로드하십시오.
이제 eleventyNavigation 서문 내에 정의 된 모든 페이지로 이동할 수 있습니다.
탐색 개선
탐색 플러그인은 기본 HTML 목록을 반환합니다.
<ul>
<li><a href="/">home</a></li>
<li>
<a href="/about/">about</a>
<ul>
<li><a href="/about/team/">team</a></li>
<li><a href="/about/privacy/">privacy</a></li>
</ul>
</li>
</ul>
이는 대부분의 사이트에 적합하지만 개선 할 수 있습니다. 예를 들면 :
이를 달성하는 한 가지 방법은 재사용 가능한 단축 코드를 만드는 것입니다. 이는 WordPress를 사용하는 모든 사람에게 친숙합니다. 단축 코드 및 선택적 인수는 템플릿에 배치 된 HTML 문자열을 반환하는 함수를 실행합니다.
Eleventy 서버를 중지하고 src / _includes / page.njk 템플릿을 업데이트하여 <header> 및 <footer> 섹션에서 {% navlist %} 단축 코드를 사용합니다.
{% include "partials/htmlhead.njk" %}
<header>
<nav>
{% navlist collections.all | eleventyNavigation, page, 1 %}
</nav>
</header>
<main>
{% block content %}
<h1>{{ title }}</h1>
{{ content | safe }}
{% endblock %}
</main>
<footer>
<nav>
{% navlist collections.all | eleventyNavigation, page, 2 %}
</nav>
</footer>
{% include "partials/htmlfoot.njk" %}
navlist 단축 코드에는 다음 세 가지 매개 변수가 전달됩니다.
navlist 단축 코드는 return 문 전에 .eleventy.js의 .addShortcode () 함수를 사용하여 등록해야 합니다. 단축 코드 이름과 호출 할 함수가 전달됩니다.
/* --- SHORTCODES --- */
// page navigation
config.addShortcode('navlist', require('./lib/shortcodes/navlist.js'));
이제 lib / shortcodes / navlist.js에서 함수를 내보낼 수 있습니다. 아래 코드는 적절한 HTML을 생성하기 위해 모든 페이지를 재귀 적으로 검사합니다 (이를 따르기가 어렵더라도 걱정하지 마십시오).
참고 : 단축 코드 파일은 사이트의 일부가 아니기 때문에 src 폴더 외부에 생성되었지만 src / _includes에서 정의 할 수도 있습니다.
// generates a page navigation list
const
listType = 'ul',
elementActive = 'strong',
classActive = 'active',
classOpen = 'open';
// pass in collections.all | eleventyNavigation, (current) page, and maximum depth level
module.exports = (pageNav, page, maxLevel = 999) => {
function navRecurse(entry, level = 1) {
let childPages = '';
if (level < maxLevel) {
for (let child of entry.children) {
childPages += navRecurse(child, level++);
}
}
let
active = (entry.url === page.url),
classList = [];
if ((active && childPages) || childPages.includes(`<${ elementActive }>`)) classList.push(classOpen);
if (active) classList.push(classActive);
return (
'<li' +
(classList.length ? ` class="${ classList.join(' ') }"` : '') +
'>' +
(active ? `<${ elementActive }>` : `<a href="${ entry.url }">`) +
entry.title +
(active ? `</${ elementActive }>` : '</a>') +
(childPages ? `<${ listType }>${ childPages }</${ listType }>` : '') +
'</li>'
);
}
let nav = '';
for (let entry of pageNav) {
nav += navRecurse(entry);
}
return `<${ listType }>${ nav }</${ listType }>`;
};
npx eleventy --serve를 다시 실행하고 정보 페이지로 이동합니다. 이제 <nav> HTML 헤더에 다음이 포함됩니다.
<ul>
<li><a href="/">home</a></li>
<li class="active"><strong>about</strong></li>
</ul>
바닥 글 <nav> HTML에는 다음이 포함됩니다.
<ul>
<li><a href="/">home</a></li>
<li class="open active">
<strong>about</strong>
<ul>
<li><a href="/about/team/">team</a></li>
<li><a href="/about/privacy/">privacy</a></li>
</ul>
</li>
</ul>
기사 / 블로그 게시물 추가
기사 또는 블로그 게시물은 표준 페이지와 다릅니다. 일반적으로 날짜가 표시되고 색인 페이지에 역 시간순으로 표시됩니다.
새 src / articles 디렉토리를 만들고 Markdown 파일을 추가합니다. 이 예에서는 일반적으로 더 읽기 쉬운 SEO 친화적 인 URL을 만들기 위해 더 나은 이름을 사용하지만 artice-01.md에서 article-06.md까지라는 6 개의 파일이 생성되었습니다.
article / article-01.md의 예제 콘텐츠 :
‐‐‐
title: The first article
description: This is the first article.
date: 2020-09-01
tags:
- HTML
- CSS
‐‐‐
This is an article post.
## Subheading
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
각 게시물에는 날짜와 하나 이상의 태그가 지정됩니다 (여기서는 HTML 및 CSS가 사용됨). Eleventy는 각 태그에 대한 컬렉션을 자동으로 생성합니다. 예를 들어, HTML 컬렉션은 HTML로 태그가 지정된 모든 게시물의 배열입니다. 이 컬렉션을 사용하여 흥미로운 방식으로 해당 페이지를 색인화 하거나 표시 할 수 있습니다.
가장 최근의 article-06.md 파일에는 초안 값 세트와 먼 미래의 날짜가 있습니다.
‐‐‐
title: The sixth article
description: This is the sixth article.
draft: true
date: 2029-09-06
tags:
- HTML
- CSS
- JavaScript
‐‐‐
이는 날짜가 지나고 초안이 제거 될 때까지 게시물이 라이브 사이트에 게시 되지 않아야 함을 나타냅니다. Eleventy는 이 기능을 구현하지 않으므로 초안 게시물을 생략하는 고유 한 맞춤 컬렉션을 만들어야 합니다.
.eleventy.js 상단에 몇 줄을 추가하여 개발 모드를 감지하고 현재 날짜 시간을 반환합니다.
// 11ty configuration
const
dev = global.dev = (process.env.ELEVENTY_ENV === 'development'),
now = new Date();
module.exports = config => {
...
}
그런 다음 return 문 앞에 .addCollection()을 호출하여 post라는 컬렉션을 정의합니다. 다음 코드는 src/articles 디렉토리에 있는 모든 md 파일을 추출하지만 초안 또는 향후 게시 날짜가 설정된 모든 파일을 제거합니다 (개발 모드를 사용하지 않는 경우).
// post collection (in src/articles)
config.addCollection('post', collection =>
collection
.getFilteredByGlob('./src/articles/*.md')
.filter(p => dev || (!p.data.draft && p.date <= now))
);
게시물에 대한 새 src / _includes / post.njk 템플릿을 만듭니다. 이는 page.njk 템플릿을 기반으로 하지만 콘텐츠 블록에는 이 게시물 컬렉션에서 추출한 기사 날짜, 단어 수 및 다음 / 이전 링크도 표시됩니다.
{% extends "page.njk" %}
{% block content %}
<h1>{{ title }}</h1>
{% if date %}<p class="time"><time datetime="{{ date }}">{{ date }}</time></p>{% endif %}
<p class="words">{{ content | wordcount }} words</p>
{{ content | safe }}
{% set nextPost = collections.post | getNextCollectionItem(page) %}
{% if nextPost %}<p>Next article: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></p>{% endif %}
{% set previousPost = collections.post | getPreviousCollectionItem(page) %}
{% if previousPost %}<p>Previous article: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></p>{% endif %}
{% endblock %}
마지막으로 src / articles / article.json 파일을 정의하여 post.njk를 기본 템플릿으로 설정합니다.
{
"layout": "post.njk"
}
npx eleventy --serve를 실행하고 http : // localhost : 8080 / articles / article-01 /로 이동합니다.
기사 / 블로그 색인 페이지 만들기
한 게시물에서 다른 게시물로 이동할 수 있지만 http : // localhost : 8080 / articles /에 색인 페이지를 만들어 모든 게시물을 역 시간순 (최신부터)으로 표시하는 것이 유용합니다.
Eleventy는 위에서 만든 posts 컬렉션과 같은 일련의 데이터를 반복하여 페이지 수에 관계없이 페이지를 만들 수 있는 페이지 매김 기능을 제공합니다.
다음 콘텐츠로 src / articles / index.md에 새 파일을 만듭니다.
‐‐‐
title: Article index
description: A list of articles published on this site.
layout: page.njk
eleventyNavigation:
key: articles
order: 900
pagination:
data: collections.post
alias: pagelist
reverse: true
size: 3
‐‐‐
The following articles are available.
서문 구성은 다음을 수행합니다.
이제 새 pagelist.njk 부분을 포함하도록 src / _includes / page.njk의 콘텐츠 블록을 수정합니다.
{% block content %}
<h1>{{ title }}</h1>
{{ content | safe }}
{% include "partials/pagelist.njk" %}
{% endblock %}
페이지 목록 페이지 매김 개체를 반복하고 각 게시물의 링크, 제목, 날짜 및 설명을 출력하는 코드를 사용하여 src / _includes / partials / pagelist.njk에 해당 부분을 만듭니다.
{% if pagelist %}
<aside class="pagelist">
{%- for post in pagelist -%}
<article>
<h2><a href="{{ post.url }}">{{ post.data.title }}</a></h2>
{% if post.data.date %}<p class="time"><time datetime="{{ post.data.date }}">{{ post.data.date }}</time></p>{% endif %}
<p>{{ post.data.description }}</p>
</article>
{%- endfor -%}
</aside>
{% endif %}
이 코드 아래에 다음 및 이전 링크를 추가하여 페이지가 매겨진 색인을 탐색 할 수 있습니다.
{% if pagination.href.previous or pagination.href.next %}
<nav class="pagenav">
{% if pagination.href.previous %}
<p><a href="{{ pagination.href.previous }}">previous</a></p>
{% endif %}
{% if pagination.href.next %}
<p><a href="{{ pagination.href.next }}">next</a></p>
{% endif %}
</nav>
{% endif %}
빌드 프로세스를 다시 시작하기 전에 ELEVENTY_ENV 환경 변수를 development로 설정하여 초안 및 미래 날짜의 게시물이 빌드에 포함되도록 하십시오. Linux / macOS에서는 다음을 입력하십시오.
ELEVENTY_ENV=development
또는 Windows cmd 프롬프트에서 :
set ELEVENTY_ENV=development
또는 Windows Powershell :
$env:ELEVENTY_ENV="development"
npx eleventy --serve를 다시 실행하고 브라우저를 새로 고칩니다. http : // localhost : 8080 / articles /에있는 최신 기사 3 개를 보여주는 새 기사 링크가 메뉴에 나타납니다.
다음 링크는 http : // localhost : 8080 / articles / 1 /의 추가 기사 페이지로 연결됩니다.
사용자 지정 필터 만들기
위의 스크린 샷은 날짜가 친숙하지 않은 JavaScript 문자열로 표시됩니다. Eleventy는 데이터를 수정하고 문자열을 반환 할 수 있는 필터를 제공합니다. Markdown에서 생성 된 콘텐츠가 인코딩되지 않은 HTML을 출력하기 위해 안전한 필터를 통과 할 때 이미 사용 된 것을 보셨을 것입니다. {{content | 안전한}}.
다음 코드를 사용하여 새 lib / filters / dateformat.js 파일을 만듭니다. 두 가지 기능을 내 보냅니다.
// date formatting functions
const toMonth = new Intl.DateTimeFormat('en', { month: 'long' });
// format a date to YYYY-MM-DD
module.exports.ymd = date => (
date instanceof Date ?
`${ date.getUTCFullYear() }-${ String(date.getUTCMonth() + 1).padStart(2, '0') }-${ String(date.getUTCDate()).padStart(2, '0') }` : ''
);
// format a date to DD MMMM, YYYY
module.exports.friendly = date => (
date instanceof Date ?
date.getUTCDate() + ' ' + toMonth.format(date) + ', ' + date.getUTCFullYear() : ''
);
게시물의 단어 수를 가장 가까운 10 개로 반올림하고 쉼표 구분 기호와 예상 읽기 시간으로 형식을 지정하는 필터를 만들 수도 있습니다. 다음 코드로 lib / filters / readtime.js를 만듭니다.
// format number of words and reading time
const
roundTo = 10,
readPerMin = 200,
numFormat = new Intl.NumberFormat('en');
module.exports = count => {
const
words = Math.ceil(count / roundTo) * roundTo,
mins = Math.ceil(count / readPerMin);
return `${ numFormat.format(words) } words, ${ numFormat.format(mins) }-minute read`;
};
return 문 이전에 .eleventy.js에 필터를 등록합니다.
/* --- FILTERS --- */
// format dates
const dateformat = require('./lib/filters/dateformat');
config.addFilter('datefriendly', dateformat.friendly);
config.addFilter('dateymd', dateformat.ymd);
// format word count and reading time
config.addFilter('readtime', require('./lib/filters/readtime'));
그런 다음 src / _includes / post.njk를 업데이트하여 dateymd, datefriendly 및 readtime 필터를 사용합니다.
{% if date %}<p class="time"><time datetime="{{ date | dateymd }}">{{ date | datefriendly }}</time></p>{% endif %}
<p class="words">{{ content | wordcount | readtime }}</p>
그런 다음 src / _includes / partials / pagelist.njk에서 기사 색인 부분을 변경하여 dateymd 및 datefriendly 필터를 사용합니다.
{% if post.data.date %}<p class="time"><time datetime="{{ post.data.date | dateymd }}">{{ post.data.date | datefriendly }}</time></p>{% endif %}
npx eleventy --serve로 빌드를 다시 시작하고 브라우저를 새로 고칩니다. 기사를 로드 하여 친숙한 날짜, 형식이 지정된 단어 수 및 예상 읽기 시간을 확인하십시오.
결과 HTML :
<p class="time"><time datetime="2020-09-05">5 September, 2020</time></p>
<p class="words">80 words, 1-minute read</p>
JavaScript 템플릿으로 이미지 처리
Eleventy는 .eleventy.js의 .addPassthroughCopy () 함수를 사용하여 모든 폴더에서 파일을 복사 할 수 있습니다. 예를 들어 src / images /의 모든 파일을 build / images /에 복사하려면 다음을 추가합니다.
config.addPassthroughCopy('src/images');
이미지가 이미 최적화 된 경우 적절할 수 있지만 자동화 된 빌드 시간 최적화는 파일 축소를 보장합니다. 이 시점에서 개발자는 종종 npm 스크립트, 웹팩 또는 Gulp.js와 같은 다른 시스템을 사용하지만 그럴 필요는 없습니다.
JavaScript는 Eleventy의 최고급 템플릿 옵션입니다. .11ty.js로 끝나는 모든 파일은 빌드 중에 처리됩니다. 파일은 다음을 사용하여 JavaScript 클래스를 내 보내야 합니다.
이미지 크기를 줄이려면 JPEG, PNG 및 SVG 파일 용 imagemin 및 플러그인을 설치하십시오.
npm i imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
src에 이미지 디렉토리를 만들고 이미지를 추가 한 후 다음 코드를 사용하여 새 src/images/images.11ty.js 파일을 만듭니다.
// image minification
const
dest = './build/images',
fsp = require('fs').promises,
imagemin = require('imagemin'),
plugins = [
require('imagemin-mozjpeg')(),
require('imagemin-pngquant')({ strip: true }),
require('imagemin-svgo')()
];
module.exports = class {
data() {
return {
permalink: false,
eleventyExcludeFromCollections: true
};
}
// process all files
async render() {
// destination already exists?
try {
let dir = await fsp.stat(dest);
if (dir.isDirectory()) return true;
}
catch(e){}
// process images
console.log('optimizing images');
await imagemin(['src/images/*', '!src/images/*.js'], {
destination: dest,
plugins
});
return true;
}
};
npx eleventy --serve를 다시 실행하면 이미지의 최적화 된 버전이 build / images / 폴더에 복사됩니다.
참고 : 위 코드는 build / images 디렉토리를 찾으면 종료됩니다. 이는 모든 빌드 중에 동일한 이미지의 재 처리를 포기하고 Eleventy가 빠르게 유지되도록 하는 간단한 솔루션입니다. 이미지를 더 추가하는 경우 먼저 build / images 폴더를 삭제하여 모두 생성되도록 합니다. 더 나은 옵션을 사용할 수 있지만 훨씬 더 많은 코드가 필요합니다!
이제 마크 다운 또는 템플릿 파일 내에 이미지를 추가 할 수 있습니다. 예를 들어 src / _includes / page.njk에 정의 된 <header>에는 로고와 히어로 이미지가 있을 수 있습니다.
<header>
<p class="logo"><a href="/"><img src="/images/logo.svg" width="50" height="50" alt="11ty starter">11ty starter</a></p>
<nav>
{% navlist collections.all | eleventyNavigation, page, 1 %}
</nav>
<figure><img src="/images/{% if hero %}{{ hero }}{% else %}orb.jpg{% endif %}" width="400" height="300" alt="decoration" /></figure>
</header>
Hero 값은 필요에 따라 앞쪽에 설정할 수 있습니다. 예를 들어 src / articles / articles.json에서 :
{
"layout": "post.njk",
"hero": "phone.jpg"
}
변환으로 CSS 처리
비슷한 방식으로 CSS를 처리하거나 다른 빌드 시스템을 사용할 수 있습니다. 그러나 Eleventy 변환은 이 상황에서 좋은 옵션입니다. 변환은 현재 렌더링 된 문자열 내용과 파일 경로를 전달하는 함수입니다. 그런 다음 해당 콘텐츠의 수정 된 버전을 반환합니다.
CSS 전처리에 Sass 사용을 고려했지만 몇 가지 플러그인이 있는 PostCSS는 부분, 변수, 믹스 인 및 중첩을 지원하는 경량 대안을 구현할 수 있습니다. 프로젝트에 PostCSS 모듈을 설치합니다.
npm i postcss postcss-advanced-variables postcss-nested postcss-scss cssnano --save-dev
그런 다음 다음 코드로 lib / transforms / postcss.js 파일을 만듭니다. 빌드가 개발 모드에서 실행될 때 소스 맵을 처리, 축소 및 추가하기 전에 .css 파일이 전달되고 있는지 확인합니다.
// PostCSS CSS processing
/* global dev */
const
postcss = require('postcss'),
postcssPlugins = [
require('postcss-advanced-variables'),
require('postcss-nested'),
require('cssnano')
],
postcssOptions = {
from: 'src/scss/entry.scss',
syntax: require('postcss-scss'),
map: dev ? { inline: true } : false
};
module.exports = async (content, outputPath) => {
if (!String(outputPath).endsWith('.css')) return content;
return (
await postcss(postcssPlugins).process(content, postcssOptions)
).css;
};
변환은 return 문 전에 .eleventy.js의 .addTransform() 함수를 사용하여 등록해야 합니다. .addWatchTarget() 호출은 src / scss / 디렉토리에서 파일이 변경 될 때마다 전체 사이트 재 빌드를 트리거 합니다.
// CSS processing
config.addTransform('postcss', require('./lib/transforms/postcss'));
config.addWatchTarget('./src/scss/');
src / scss / main.scss 파일을 만들고 필요한 SCSS 또는 CSS 코드를 포함합니다. 예제 코드는 추가 SCSS 파일을 가져옵니다.
// settings
@import '01-settings/_variables';
@import '01-settings/_mixins';
// reset
@import '02-generic/_reset';
// elements
@import '03-elements/_primary';
// etc...
Eleventy는 CSS 또는 SCSS 파일을 직접 처리하지 않으므로 다음 코드를 사용하여 src / scss / main.njk에 새 템플릿 파일을 만들어야 합니다.
‐‐‐
permalink: /css/main.css
eleventyExcludeFromCollections: true
‐‐‐
@import 'main.scss';
이렇게 하면 main.scss 파일을 가져 와서 변환 함수가 적절하게 처리하기 전에 build / css / main.css에 렌더링 합니다. 둘 이상의 CSS 파일이 필요한 경우 유사한 SCSS / CSS 및 .njk 파일을 만들 수 있습니다.
npx eleventy --serve를 다시 실행하고 build / css / main.css에 빌드 된 CSS 파일의 내용을 확인합니다. 소스 맵은 브라우저의 개발자 도구에서 스타일을 검사 할 때 CSS 선언의 원래 소스 파일 위치를 사용할 수 있도록 합니다.
변환으로 HTML 축소
유사한 변환을 사용하여 html-minifier로 HTML을 축소 할 수 있습니다. 다음과 같이 설치하십시오.
npm i html-minifier --save-dev
다음 코드를 사용하여 새 lib / transforms / htmlminify.js 파일을 만듭니다. .html 파일이 처리되고 있는지 확인하고 축소 된 버전을 반환합니다.
// minify HTML
const htmlmin = require('html-minifier');
module.exports = (content, outputPath = '.html') => {
if (!String(outputPath).endsWith('.html')) return content;
return htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true
});
};
이전과 마찬가지로 return 문 앞 어딘가에 .eleventy.js에 변환을 등록합니다.
// minify HTML
config.addTransform('htmlminify', require('./lib/transforms/htmlminify'));
참고 : 개발 중에 HTML을 축소하거나 미화하지 않는 것을 고려할 수 있습니다. 즉, HTML 공백은 브라우저 렌더링에 영향을 줄 수 있으므로 일반적으로 프로덕션에서와 동일한 방식으로 코드를 빌드하는 것이 가장 좋습니다. 소스보기가 더 어려워 지지만 브라우저 개발자 도구는 결과 DOM을 표시합니다.
변환으로 자산 인라인
HTML 내에서 다른 애셋을 인라인 해야 하는 경우가 많습니다. SVG는 이미지가 DOM의 일부가 되고 CSS로 조작 할 수 있기 때문에 주요 후보입니다. <style> 요소의 CSS, <script> 요소의 JavaScript 또는 <img> 요소의 base64 인코딩 이미지를 인라인하여 HTTP 요청을 줄이는 것도 실용적 일 수 있습니다.
인라인 소스 모듈은 모든 상황을 처리 할 수 있습니다. 다음과 같이 설치하십시오.
npm i inline-source --save-dev
이제 다음 코드가 포함 된 새 lib / transforms / inline.js 파일을 추가하여 HTML 콘텐츠를 확인하고 처리합니다.
// inline data
const { inlineSource } = require('inline-source');
module.exports = async (content, outputPath) => {
if (!String(outputPath).endsWith('.html')) return content;
return await inlineSource(content, {
compress: true,
rootpath: './build/'
});
};
return 문 앞에 .eleventy.js에 변환을 등록합니다.
// inline assets
config.addTransform('inline', require('./lib/transforms/inline'));
이제 <img>, <link> 또는 <script> 태그에 인라인 속성을 추가합니다. 예를 들면 :
<img src="/images/logo.svg" width="50" height="50" alt="11ty starter" inline>
빌드 중에 변환은 <img> 태그를 가져온 <svg> 코드로 바꿉니다.
JavaScript 템플릿으로 JavaScript 처리
클라이언트 측 자바 스크립트는 변환으로 처리 될 수 있지만 <something> .11ty.js라는 자바 스크립트 템플릿도 Eleventy에서 자동으로 처리되기 때문에 옵션입니다 (위의 '자바 스크립트 템플릿으로 이미지 처리'섹션 참조).
예제 코드는 간단한 어두운 / 밝은 테마 전환을 구현하는 ES6 스크립트를 제공합니다. Rollup.js는 main.js에서 참조하는 모든 모듈을 단일 파일로 묶고 트리 쉐이킹을 수행하여 사용하지 않는 기능을 제거하는 데 사용됩니다. 그런 다음 간결한 플러그인이 결과 코드를 축소합니다.
다음을 사용하여 Rollup.js 모듈을 설치합니다.
npm i rollup rollup-plugin-terser --save-dev
그런 다음 src에 js 디렉토리를 만들고 ES6 스크립트를 추가합니다. 다른 항목을 가져 오는 단일 src / js / main.js 항목 스크립트를 정의해야 합니다. 예를 들면 :
import * as theme from './lib/theme.js';
다음 코드로 새 src / js / javascript.11ty.js 파일을 생성하여 src / js / main.js를 단일 번들로 처리하고 개발 모드에서 빌드 할 때 소스 맵을 추가합니다.
// JavaScript processing
/* global dev */
const
jsMain = 'js/main.js',
rollup = require('rollup'),
terser = require('rollup-plugin-terser').terser,
inputOpts = {
input: './src/' + jsMain
},
outputOpts = {
format: 'es',
sourcemap: dev,
plugins: [
terser({
mangle: {
toplevel: true
},
compress: {
drop_console: !dev,
drop_debugger: !dev
},
output: {
quote_style: 1
}
})
]
}
;
module.exports = class {
data() {
return {
permalink: jsMain,
eleventyExcludeFromCollections: true
};
}
// PostCSS processing
async render() {
const
bundle = await rollup.rollup(inputOpts),
{ output } = await bundle.generate(outputOpts),
out = output.length && output[0];
let code = '';
if (out) {
// JS code
code = out.code;
// inline source map
if (out.map) {
let b64 = new Buffer.from(out.map.toString());
code += '//# sourceMappingURL=data:application/json;base64,' + b64.toString('base64');
}
}
return code;
}
};
JavaScript 파일을 변경하면 반환 전에 .eleventy.js에 다음 줄을 추가하여 다시 빌드를 트리거 할 수 있습니다.
config.addWatchTarget('./src/js/');
그러면 결과 스크립트가 페이지에 포함될 수 있습니다 (예 : src / _includes / partials / htmlfoot.njk).
<script type="module" src="/js/main.js"></script>
</body>
</html>
참고 : 샘플 코드는 ES5로 트랜스 파일 하는 대신 ES6 모듈을 빌드합니다. 스크립트는 더 작지만 브라우저 호환성은 더 제한됩니다. 즉, 점진적으로 개선되었으며 사이트는 JavaScript없이 작동합니다.
npx eleventy --serve를 다시 시작하면 축소 된 스크립트가 로드되고 실행됩니다. 이제 최종 사이트를 수상 경력에 빛나는 영광으로 볼 수 있습니다.
Build a Production Site
사이트가 마음에 들면 소스 맵 및 기타 개발 옵션 없이 프로덕션 모드에서 빌드 할 수 있습니다.
빌드 폴더를 삭제하고 ELEVENTY_ENV를 Linux / macOS에서 프로덕션으로 설정합니다.
ELEVENTY_ENV=production
또는 Windows cmd 프롬프트 :
set ELEVENTY_ENV=production
또는 Windows Powershell :
$env:ELEVENTY_ENV="production"
그런 다음 npx eleventy를 실행하여 전체 사이트를 빌드하십시오.
/build 디렉토리의 결과 파일은 모든 호스트에 업로드 할 수 있습니다. 일부 정적 사이트 전문가 서비스는 새 코드가 GitHub 또는 유사한 저장소에 푸시 될 때마다 사이트를 자동으로 빌드하고 게시 할 수 있습니다.
Eleventy와 함께하는 다음 단계
이 예제 프로젝트는 다양한 유형의 콘텐츠를 빌드하기 위한 몇 가지 옵션과 함께 Eleventy의 기본 사항을 보여줍니다. 그러나 Eleventy는 유연하며 원하는 기술을 자유롭게 사용할 수 있습니다. 수십 개의 시작 프로젝트가 있으며 각각은 약간 다른 접근 방식을 취합니다.
추가 사이트 기능에 대한 제안 :
등록된 댓글이 없습니다.