Es scheint, als hätten sich alle coolen Kids in zwei Cliquen aufgeteilt: die Headless CMS-Fraktion auf der einen Seite und die Static Site Generator-Fraktion auf der anderen. Obwohl ich zugebe, dass das ziemlich coole Team-Namen sind, konnte ich mich nicht für eine Seite entscheiden. Um Groucho Marx zu paraphrasieren: „Ich habe keine Lust, irgendeinem Club beizutreten, der mich als Mitglied aufnimmt.“
Für meinen eigenen einfachen Blog (der im Moment beschämend leer ist) könnte ein statischer Website-Generator eine großartige Lösung sein. Systeme wie Hugo und Jekyll wurden von Entwicklern, die ich liebe und denen ich vertraue, sehr empfohlen und sehen auf den ersten Blick großartig aus, aber ich stieß auf Hindernisse, als ich mein Theme ändern oder komplexere JavaScript- und Interaktionen seitenübergreifend einrichten wollte. Es gibt Wege, beide Probleme zu lösen, aber das ist nicht die Art von Wochenende, die ich haben möchte.
Außerdem liebe ich es zu experimentieren, neue Dinge zu schaffen, und ich habe im Moment eine große Schwäche für Vue. Ein Headless CMS-Setup mit einem von Back-End entkoppelten Front-End könnte für mich eine großartige Kombination sein, aber nach über 7 Jahren PHP-Schwingen mit WordPress fühlt sich das gesamte Setup für meine grundlegenden Bedürfnisse übertrieben an.
Was ich *wirklich* will, ist ein statischer Website-Generator, der es mir ermöglicht, einen Blog als Komponente einer größeren Single-Page-App zu schreiben, damit ich Raum für neue Dinge habe und trotzdem die volle Kontrolle über das Styling behalte, ohne eine Datenbank oder irgendeine Art von Back-End zu benötigen. Das ist eine lange Umschreibung, um Ihnen zu sagen, dass ich meinen eigenen Club gefunden habe, mit einem ausgesprochen uncoolen Namen.
Machen Sie sich bereit...
Die Website ohne Po. Po.
Da kein Back-End vorhanden ist, verstehen Sie? 😶
Es sind ein paar Schritte nötig, um ohne Po. Po. zu werden
- Richten Sie eine Single-Page-App mit Vue ein
- Generieren Sie jede Route zur Build-Zeit
- Erstellen Sie Blog- und Artikelkomponenten
- Integrieren Sie Webpack, um Markdown-Inhalte zu parsen
- Erweitern Sie die Funktionalität mit Plugins
- Profitieren Sie!
Der letzte Punkt muss doch Teil jedes Vorschlags sein, oder?
Ich weiß, es sieht nach vielen Schritten aus, aber das ist gar nicht so schwer, wie es scheint. Lassen Sie uns die Schritte gemeinsam durchgehen.
Richten Sie eine Single-Page-App mit Vue ein
Lassen Sie uns Vue zum Laufen bringen. Dazu benötigen wir Webpack.
Ich verstehe, Webpack ist ziemlich einschüchternd, selbst wenn man weiß, was man tut. Wahrscheinlich ist es am besten, jemand anderen die wirklich harte Arbeit machen zu lassen, also werden wir die Vue Progressive Web App Boilerplate als Grundlage verwenden und ein paar Anpassungen vornehmen.
Wir könnten die Standardeinstellung aus dem Repository verwenden, aber selbst während ich diesen Artikel schrieb, gab es dort Änderungen. Um zu vermeiden, dass das alles für uns bricht, werden wir ein von mir erstelltes Repository zu Demonstrationszwecken verwenden. Das Repository hat für jeden Schritt, den wir in diesem Beitrag behandeln, einen eigenen Branch, um Ihnen das Mitverfolgen zu erleichtern.
Klonen Sie das Repository und wechseln Sie zum Branch step-1
$ git clone https://github.com/evanfuture/vue-yes-blog.git step-1
$ cd vue-yes-blog
$ npm install
$ npm run dev
Einer meiner Lieblingsteile der modernen Entwicklung ist, dass es nur dreißig Sekunden dauert, eine progressive Web-App zum Laufen zu bringen!
Als Nächstes komplizieren wir die Dinge.
Generieren Sie jede Route zur Build-Zeit
Standardmäßig haben Single-Page-Apps nur einen einzigen Einstiegspunkt. Mit anderen Worten, sie leben unter einer einzigen URL. Das ist in einigen Fällen sinnvoll, aber wir möchten, dass unsere App sich wie eine normale Website anfühlt.
Wir müssen den History-Modus in der Vue Router-Datei nutzen, um das zu erreichen. Zuerst aktivieren wir ihn, indem wir mode: 'history' zu den Eigenschaften des Router-Objekts hinzufügen, wie folgt:
// src/router/index.js
Vue.use(Router);
export default new Router({
mode: 'history',
routes: [
// ...
Unsere Starter-App hat zwei Routen. Zusätzlich zu Hello haben wir eine zweite View-Komponente namens Banana, die unter der Route /banana liegt. Ohne History-Modus wäre die URL für diese Seite https://:1982/#/banana. History-Modus macht daraus https://:1982/banana. Viel eleganter!
Das alles funktioniert im Entwicklungsmodus (npm run dev) ziemlich gut, aber werfen wir einen Blick darauf, wie es in der Produktion aussehen würde. So kompilieren wir alles:
$ npm run build
Dieser Befehl generiert Ihre Vue-Site in den Ordner ./dist. Um sie live zu sehen, gibt es einen praktischen Befehl, um einen super einfachen HTTP-Server auf Ihrem Mac zu starten:
$ cd dist
$ python -m SimpleHTTPServer
Tut mir leid, liebe Windows-Nutzer, ich kenne das Äquivalent nicht!
Besuchen Sie jetzt localhost:8000 in Ihrem Browser. Sie sehen Ihre Website, wie sie in einer Produktionsumgebung erscheinen wird. Klicken Sie auf den Banana-Link, und alles ist in Ordnung.
Aktualisieren Sie die Seite. Huch! Das enthüllt unser erstes Problem mit Single-Page-Apps: Es wird nur eine HTML-Datei zur Build-Zeit generiert, daher gibt es keine Möglichkeit für den Browser zu wissen, dass /banana auf die Haupt-App-Seite abzielen und die Route ohne schicke Apache-Style-Weiterleitungen laden soll!
Natürlich gibt es dafür eine App. Oder zumindest ein Plugin. Die grundlegende Verwendung ist in der Dokumentation der Vue Progressive Web App Boilerplate dokumentiert. Hier steht, wie wir das Plugin starten können:
$ npm install -D prerender-spa-plugin
Fügen wir unsere Routen zur Webpack-Produktionskonfigurationsdatei hinzu:
// ./build/webpack.prod.conf.js
// ...
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin')
const PrerenderSpaPlugin = require('prerender-spa-plugin')
const loadMinified = require('./load-minified')
// ...
const webpackConfig = merge(baseWebpackConfig, {
// ...
plugins: [
// ...
new SWPrecacheWebpackPlugin({
// ...
minify: true,
stripPrefix: 'dist/'
}),
// prerender app
new PrerenderSpaPlugin(
// Path to compiled app
path.join(__dirname, '../dist'),
// List of endpoints you wish to prerender
[ '/', '/banana' ]
)
]
})
Das ist alles. Wenn Sie nun einen neuen Build ausführen, wird jede Route in diesem Array als neuer Einstiegspunkt für die App gerendert. Herzlichen Glückwunsch, wir haben im Grunde gerade statische Seitengenerierung aktiviert!
Erstellen Sie Blog- und Artikelkomponenten
Wenn Sie vorspringen, sind wir jetzt beim Branch step-2 meines Demo-Repos. Laden Sie ihn herunter, wenn Sie dem Code folgen.
$ git checkout step-2
Dieser Schritt ist ziemlich unkompliziert. Wir erstellen zwei neue Komponenten und verknüpfen sie miteinander.
Blog-Komponente
Registrieren wir die Blog-Komponente. Wir erstellen eine neue Datei namens YesBlog.vue im Verzeichnis /src/components und fügen dort das Markup für die View ein.
// ./src/components/YesBlog.vue
<template>
<div class="blog">
<h1>Blog</h1>
<router-link to="/">Home</router-link>
<hr/>
<article v-for="article in articles" :key="article.slug" class="article">
<router-link class="article__link" :to="`/blog/${ article.slug }`">
<h2 class="article__title">{{ article.title }}</h2>
<p class="article__description">{{article.description}}</p>
</router-link>
</article>
</div>
</template>
<script>
export default {
name: 'blog',
computed: {
articles() {
return [
{
slug: 'first-article',
title: 'Article One',
description: 'This is article one\'s description',
},
{
slug: 'second-article',
title: 'Article Two',
description: 'This is article two\'s description',
},
];
},
},
};
</script>
Alles, was wir hier eigentlich tun, ist die Erstellung eines Platzhalter-Arrays (articles), das mit Artikelobjekten gefüllt wird. Dieses Array erstellt unsere Artikelliste und verwendet den slug-Parameter als Post-ID. Die Parameter title und description füllen die Details des Posts aus. Vorerst ist alles hartcodiert, während wir den Rest unseres Codes einfügen.
Artikel-Komponente
Die Artikelkomponente ist ein ähnlicher Prozess. Wir erstellen eine neue Datei namens YesArticle.vue und legen das Markup für die View fest.
// ./src/components/YesArticle.vue
<template>
<div class="article">
<h1 class="blog__title">{{article.title}}</h1>
<router-link to="/blog">Back</router-link>
<hr/>
<div class="article__body" v-html="article.body"></div>
</div>
</template>
<script>
export default {
name: 'YesArticle',
props: {
id: {
type: String,
required: true,
},
},
data() {
return {
article: {
title: this.id,
body: '<h2>Testing</h2><p>Ok, let\'s do more now!</p>',
},
};
},
};
</script>
Wir verwenden die vom Router übergebenen Props, um zu wissen, mit welcher Artikel-ID wir arbeiten. Vorerst verwenden wir das einfach als Post-Titel und codieren den Body.
Routing
Wir können nicht weitermachen, bis wir unsere neuen Views zum Router hinzugefügt haben. Dies stellt sicher, dass unsere URLs gültig sind und ermöglicht unserer Navigation, ordnungsgemäß zu funktionieren. Hier ist die Gesamtheit der Router-Datei:
// ./src/router/index.js
import Router from 'vue-router';
import Hello from '@/components/Hello';
import Banana from '@/components/Banana';
import YesBlog from '@/components/YesBlog';
import YesArticle from '@/components/YesArticle';
Vue.use(Router);
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Hello',
component: Hello,
},
{
path: '/banana',
name: 'Banana',
component: Banana,
},
{
path: '/blog',
name: 'YesBlog',
component: YesBlog,
},
{
path: '/blog/:id',
name: 'YesArticle',
props: true,
component: YesArticle,
},
],
});
Beachten Sie, dass wir /:id an den Pfad der YesArticle-Komponente angehängt und ihre Props auf true gesetzt haben. Diese sind entscheidend, da sie das dynamische Routing etablieren, das wir im Props-Array der Komponente in der Komponentendatei eingerichtet haben.
Schließlich können wir einen Link zu unserer Homepage hinzufügen, der auf den Blog verweist. Das ist es, was wir in die Hello.vue-Datei einfügen, um das zu realisieren.
<router-link to="/blog">Blog</router-link>
Vorausrendern
Wir haben bisher viel Arbeit geleistet, aber nichts davon wird bleiben, bis wir unsere Routen vorausrendern. Vorausrendern ist ein schicker Begriff dafür, dass wir der App sagen, welche Routen existieren und die richtige Markierung in die richtige Route schreiben. Wir haben zuvor ein Webpack-Plugin dafür hinzugefügt, also hier ist, was wir zu unserer Webpack-Produktionskonfigurationsdatei hinzufügen können:
// ./build/webpack.prod.conf.js
// ...
// List of endpoints you wish to prerender
[ '/', '/banana', '/blog', '/blog/first-article', '/blog/second-article' ]
// ...
Ich muss zugeben, dieser Prozess kann mühsam und nervig sein. Ich meine, wer möchte mehrere Dateien anfassen, um eine URL zu erstellen?! Glücklicherweise können wir das automatisieren, was wir weiter unten behandeln werden.
Integrieren Sie Webpack, um Markdown-Inhalte zu parsen
Wir sind jetzt beim Branch step-3. Schauen Sie ihn sich an, wenn Sie dem Code folgen.
$ git checkout step-3
Die Beiträge
Wir werden Markdown verwenden, um unsere Beiträge zu schreiben, mit etwas FrontMatter, um Meta-Datenfunktionalität zu schaffen.
Erstellen Sie eine neue Datei im Verzeichnis posts, um unseren allerersten Beitrag zu erstellen.
// ./src/posts/first-article.md
---
title: Article One from MD
description: In which the hero starts fresh
created: 2017-10-01T08:01:50+02
updated:
status: publish
---
Here is the text of the article. It's pretty great, isn't it?
// ./src/posts/second-article.md
---
title: Article Two from MD
description: This is another article
created: 2017-10-01T08:01:50+02
updated:
status: publish
---
## Let's start with an H2
And then some text
And then some code:
```html
<div class="container">
<div class="main">
<div class="article insert-wp-tags-here">
<h1>Title</h1>
<div class="article-content">
<p class="intro">Intro Text</p>
<p></p>
</div>
<div class="article-meta"></div>
</div>
</div>
</div>
```
Dynamische Weiterleitung
Eine lästige Sache im Moment ist, dass wir unsere Routen für das Pre-Rendering-Plugin hartcodieren müssen. Glücklicherweise ist es mit etwas Node-Magie nicht kompliziert, dies dynamisch zu machen. Zuerst erstellen wir ein Hilfsprogramm in unserer Hilfsdatei, um die Dateien zu finden.
// ./build/utils.js
// ...
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const fs = require('fs')
exports.filesToRoutes = function (directory, extension, routePrefix = '') {
function findFilesInDir(startPath, filter){
let results = []
if (!fs.existsSync(startPath)) {
console.log("no dir ", startPath)
return
}
const files = fs.readdirSync(startPath)
for (let i = 0; i < files.length; i++) {
const filename = path.join(startPath, files[i])
const stat = fs.lstatSync(filename)
if (stat.isDirectory()) {
results = results.concat(findFilesInDir(filename, filter)) //recurse
} else if (filename.indexOf(filter) >= 0) {
results.push(filename)
}
}
return results
}
return findFilesInDir(path.join(__dirname, directory), extension)
.map((filename) => {
return filename
.replace(path.join(__dirname, directory), routePrefix)
.replace(extension, '')
})
}
exports.assetsPath = function (_path) {
// ...
Dies kann einfach kopiert und eingefügt werden, aber was wir hier getan haben, ist eine Hilfsmethode namens filesToRoutes() zu erstellen, die ein Verzeichnis, eine Erweiterung und optional ein routePrefix entgegennimmt und ein Array von Routen basierend auf einer rekursiven Dateisuche in diesem Verzeichnis zurückgibt.
Alles, was wir tun müssen, um unsere Blog-Post-Routen dynamisch zu gestalten, ist, dieses neue Array mit unseren PrerenderSpaPlugin-Routen zu verschmelzen. Die Leistung von ES6 macht das wirklich einfach.
// ./build/webpack.prod.conf.js
// ...
new PrerenderSpaPlugin(
// Path to compiled app
path.join(__dirname, '../dist'),
// List of endpoints you wish to prerender
[
'/',
'/banana',
'/blog',
...utils.filesToRoutes('../src/posts', '.md', '/blog')
]
)
Da wir utils bereits am Anfang der Datei für andere Zwecke importiert haben, können wir einfach den Spread-Operator ... verwenden, um das neue Array dynamischer Routen mit diesem zu verschmelzen, und wir sind fertig. Jetzt ist unser Pre-Rendering komplett dynamisch und hängt nur davon ab, dass wir eine neue Datei hinzufügen!
Webpack-Loader
Wir sind jetzt beim Branch step-4.
$ git checkout step-4
Um unsere Markdown-Dateien tatsächlich in verarbeitbare Inhalte umzuwandeln, benötigen wir einige Webpack-Loader. Auch hier haben andere die ganze Arbeit für uns erledigt, also müssen wir sie nur installieren und zu unserer Konfiguration hinzufügen.
Update September 2018: Seif Sayed schrieb, dass das Paket ‚markdown-it-front-matter-loader‘ veraltet ist. Der Rest dieses Artikels verwendet es immer noch, aber Sie sollten wahrscheinlich stattdessen markdown-with-front-matter-loader verwenden, und das mit dem Bonus, dass Sie dafür keinen json-loader benötigen.
$ npm install -D json-loader markdown-it-front-matter-loader markdown-it highlight.js yaml-front-matter
Wir werden nur den json-loader und den markdown-it-front-matter-loader aus unserer Webpack-Konfiguration aufrufen, aber letzterer hat Peer-Abhängigkeiten von markdown-it und highlight.js, also installieren wir diese gleichzeitig. Außerdem warnt uns nichts davor, aber yaml-front-matter ist ebenfalls erforderlich, daher fügt der obige Befehl auch dies hinzu.
Um diese schicken neuen Loader zu verwenden, fügen wir unserem Webpack-Basis-Config einen Block hinzu.
// ./build/webpack.base.conf.js
// ...
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
{
test: /\.md$/,
loaders: ['json-loader', 'markdown-it-front-matter-loader'],
},
]
}
}
Jetzt wird Webpack jedes Mal, wenn es auf eine require-Anweisung mit der Erweiterung .md stößt, den front-matter-loader verwenden (der den Metadatenblock aus unseren Artikeln sowie die Codeblöcke korrekt parst) und die JSON-Ausgabe nehmen und sie durch den json-loader laufen lassen. Auf diese Weise wissen wir, dass wir für jeden Artikel ein Objekt erhalten, das so aussieht:
// first-article.md [Object]
{
body: "<p>Here is the text of the article. It's pretty great, isn't it?</p>\n"
created: "2017-10-01T06:01:50.000Z"
description: "In which the hero starts fresh"
raw: "\n\nHere is the text of the article. It's pretty great, isn't it?\n"
slug: "first-article"
status: "publish"
title: "Article One from MD"
updated: null
}
Das ist genau das, was wir brauchen und es ist ziemlich einfach, es mit anderen Metadaten zu erweitern, wenn Sie es benötigen. Aber bisher tut das nichts! Wir müssen diese in einer unserer Komponenten requiren, damit Webpack sie finden und laden kann.
Wir könnten einfach schreiben:
require('../posts/first-article.md')
... aber dann müssten wir das für jeden Artikel tun, den wir erstellen, und das macht keinen Spaß, wenn unser Blog wächst. Wir brauchen eine Möglichkeit, alle unsere Markdown-Dateien dynamisch zu requiren.
Dynamisches Requieren
Glücklicherweise macht Webpack das! Es war nicht einfach, Dokumentation dafür zu finden, aber hier ist sie. Es gibt eine Methode namens require.context(), die wir verwenden können, um genau das zu tun, was wir brauchen. Wir fügen sie in den Skriptabschnitt unserer YesBlog-Komponente ein.
// ./src/components/YesBlog.vue
// ...
<script>
const posts = {};
const req = require.context('../posts/', false, /\.md$/);
req.keys().forEach((key) => {
posts[key] = req(key);
});
export default {
name: 'blog',
computed: {
articles() {
const articleArray = [];
Object.keys(posts).forEach((key) => {
const article = posts[key];
article.slug = key.replace('./', '').replace('.md', '');
articleArray.push(article);
});
return articleArray;
},
},
};
</script>
// ...
Was passiert hier? Wir erstellen ein posts-Objekt, das wir zuerst mit Artikeln befüllen und später innerhalb der Komponente verwenden werden. Da wir all unsere Inhalte vorausrendern, wird dieses Objekt sofort verfügbar sein.
Die Methode require.context() akzeptiert drei Argumente.
- das Verzeichnis, in dem gesucht werden soll
- ob Unterverzeichnisse einbezogen werden sollen oder nicht
- ein Regex-Filter, um Dateien zurückzugeben
In unserem Fall wollen wir nur Markdown-Dateien im posts-Verzeichnis, also:
require.context('../posts/', false, /\.md$/);
Das gibt uns eine etwas seltsame neue Funktion/Objekt, das wir parsen müssen, um es zu verwenden. Dort gibt uns req.keys() ein Array der relativen Pfade zu jeder Datei. Wenn wir req(key) aufrufen, gibt dies das gewünschte Artikelobjekt zurück, sodass wir diesen Wert einem übereinstimmenden Schlüssel in unserem posts-Objekt zuweisen können.
Schließlich generieren wir in der berechneten Methode articles() automatisch unseren Slug, indem wir jedem Post einen slug-Schlüssel mit dem Wert des Dateinamens ohne Pfad oder Erweiterungen hinzufügen. Wenn wir wollten, könnte dies geändert werden, um uns zu erlauben, den Slug im Markdown selbst festzulegen und nur auf die automatische Generierung zurückzugreifen. Gleichzeitig fügen wir die Artikelobjekte einem Array hinzu, damit wir in unserer Komponente leicht darüber iterieren können.
Extrapunkte
Es gibt zwei Dinge, die Sie wahrscheinlich sofort tun möchten, wenn Sie diese Methode verwenden. Erstens das Sortieren nach Datum und zweitens das Filtern nach Artikelstatus (z. B. Entwurf und veröffentlicht). Da wir bereits ein Array haben, kann dies mit einer einzigen Zeile geschehen, die direkt vor return articleArray hinzugefügt wird.
articleArray.filter(post => post.status === 'publish').sort((a, b) => a.created < b.created);
Letzter Schritt
Eine letzte Sache, die wir jetzt noch tun müssen, ist, unserer YesArticle-Komponente anzuweisen, die neuen Daten zu verwenden, die wir zusammen mit der Routenänderung erhalten.
// ./src/components/YesArticle.vue
// ...
data() {
return {
article: require(`../posts/${this.id}.md`), // eslint-disable-line global-require, import/no-dynamic-require
};
},
Da wir wissen, dass unsere Komponente vorausgerendert wird, können wir die ESLint-Regeln deaktivieren, die dynamische und globale requires verbieten, und den Pfad zum Post requiren, der dem id-Parameter entspricht. Dies löst unsere Webpack Markdown-Loader aus, und wir sind fertig!
OMG!
Probieren Sie das aus.
$ npm run build && cd dist && python -m SimpleHTTPServer
Besuchen Sie localhost:8000, navigieren Sie herum und aktualisieren Sie die Seiten, um die gesamte App vom neuen Einstiegspunkt aus zu laden. Es funktioniert!
Ich möchte betonen, wie cool das ist. Wir haben einen Ordner mit Markdown-Dateien in ein Array von Objekten verwandelt, das wir nach Belieben überall auf unserer Website verwenden können. Der Himmel ist die Grenze!
Wenn Sie nur sehen möchten, wie alles funktioniert, können Sie sich den letzten Branch ansehen.
$ git checkout step-complete
Erweitern Sie die Funktionalität mit Plugins
Mein Lieblingsteil an dieser Technik ist, dass alles erweiterbar und austauschbar ist.
Hat jemand einen besseren Markdown-Prozessor entwickelt? Großartig, tauschen Sie den Loader aus! Benötigen Sie Kontrolle über das SEO Ihrer Website? Es gibt ein Plugin dafür. Möchten Sie ein Kommentarsystem hinzufügen? Fügen Sie dieses Plugin hinzu.
Ich behalte diese beiden Repositories gerne im Auge für Ideen und Inspiration:
Profitieren Sie!
Sie dachten, dieser Schritt wäre ein Witz?
Das Letzte, was wir jetzt noch tun wollen, ist, von der geschaffenen Einfachheit zu profitieren und etwas kostenloses Hosting zu ergattern. Da Ihre Website nun in Ihrem Git-Repository generiert wird, müssen Sie nur noch Ihre Änderungen auf Github, Bitbucket, Gitlab oder welchem Code-Repository auch immer Sie verwenden, pushen. Ich habe mich für Gitlab entschieden, weil private Repos kostenlos sind und ich meine Entwürfe nicht öffentlich machen wollte, selbst in Repo-Form.
Nachdem das eingerichtet ist, müssen Sie einen Hoster finden. Was Sie wirklich wollen, ist ein Hoster, der kontinuierliche Integration und Bereitstellung anbietet, so dass das Mergen in Ihren Master-Branch den Befehl npm run build auslöst und Ihre Website neu generiert.
Ich habe die CI-Tools von Gitlab die ersten paar Monate nach der Einrichtung genutzt. Ich fand die Einrichtung einfach, aber die Fehlersuche schwierig. Ich bin kürzlich zu Netlify gewechselt, das einen hervorragenden kostenlosen Plan und einige großartige CLI-Tools direkt integriert hat.
In beiden Fällen können Sie Ihre eigene Domain auf deren Server verweisen und sogar ein SSL-Zertifikat für HTTPS-Unterstützung einrichten – letzteres ist wichtig, wenn Sie jemals Dinge wie die getUserMedia-API ausprobieren oder einen Shop erstellen möchten, um Verkäufe zu tätigen.
Mit all dem eingerichtet sind Sie nun Mitglied des Butt-less Website Clubs. Herzlichen Glückwunsch und willkommen, Freunde! Hoffentlich finden Sie dies als eine einfache Alternative zu komplexen Content-Management-Systemen für Ihre eigene persönliche Website und dass es Ihnen ermöglicht, mit Leichtigkeit zu experimentieren. Bitte lassen Sie mich in den Kommentaren wissen, wenn Sie dabei auf Schwierigkeiten stoßen ... oder wenn Sie Ihre wildesten Träume übertreffen. 😉
Für die Windows-Leute hier ist ein super einfacher HTTP-Server.
Funktioniert auch auf Mac!
Mehr Details unter https://www.npmjs.com/package/http-server
Danke Thomas, ich wusste, dass es einen geben würde!
Vielleicht haben Sie das schon gesehen, aber falls nicht, könnten Sie sich Nuxt ansehen. Es leistet viel von dem, was Sie besprechen, und bietet außerdem serverseitiges Rendering.
Hey Jordan, ja, Nuxt war ziemlich stark, als ich es vor einem Jahr ausprobiert habe, ich bin sicher, es ist seitdem nur noch besser geworden. Aber es kommt für mich immer noch auf dasselbe Problem an, es gab einen Punkt, an dem ich etwas tun wollte, was nicht wirklich so einfach war, und ich fing an, mit dem Framework zu kämpfen.
Der schöne Teil an der
require.context()-Methode ist, dass sie Teil von webpack ist, was bedeutet, dass dies auch mit React funktionieren kann, denke ich.TLDR-Version: Probieren Sie nuxt.js aus.
Da bin ich mir nicht so sicher, aber wenn wir nur über Vue reden, vielleicht. Mein Punkt beim Schreiben war, dass die Kenntnis der Webpack-Technik zur Umwandlung Ihrer SPA in statische Einstiegspunkte, zusammen mit der Möglichkeit, dynamische Inhaltsmengen wie Blogbeiträge einzuschließen, Ihnen die Freiheit gibt, zu tun, was Sie wollen. Ich denke, das wird auch mit React funktionieren.
Natürlich, wenn Sie nicht so tief eintauchen wollen oder wenn Sie sich damit abfinden, sich an Vue zu binden, dann ist Nuxt vielleicht das Richtige für Sie!
Sehr cool. Ich hätte nie gewusst, dass so etwas existiert, danke, dass Sie uns erleuchtet haben! Ich könnte tatsächlich einen Blog für meine https://www.kodevelopers.com/5-server-tanitimi/ Website erstellen, das wäre super-toll. Das Ding ist ein echter Zeitsparer.
Für alle Leser, die das ausprobieren möchten, aber React verwenden, habe ich eine Schritt-für-Schritt-Kopie des vue-yes-blog-Repos mit React erstellt: https://github.com/evanfuture/react-yes-blog
Frohe Feiertage!
Ich glaube, die meisten Leute, die mit "benutzen Sie einfach Nuxt" reagieren, haben entweder den ganzen Artikel nicht gelesen oder noch keinen ähnlichen Aufbau mit Nuxt versucht.
Ich bin neu bei Nuxt (vollständige Offenlegung), aber soweit ich weiß, gibt es keine Möglichkeit, out-of-the-box eine echte Jekyll-ähnliche Einrichtung zu erhalten. Die automatische Weiterleitung für Seiten ist cool, aber es gibt keine Möglichkeit, diese auf dynamische Inhalte (außerhalb einer API) zu erweitern. Noch keine Möglichkeit, FrontMatter-ähnliche Variablen zwischen Seiten und Layouts zu übergeben.
Ohne diese Kernfunktionalität ist Nuxt allein (in diesem Kontext) nicht machbar. Auf der anderen Seite adressiert Ihr hier eingerichteter Aufbau genau das.
Das gesagt… Ich habe hier auf deine Arbeit mit Webpack, Markdown und Frontmatter verwiesen und diese in einem Nuxt-Build verwendet, und bisher scheint alles gut zu funktionieren. Das Beste aus beiden Welten!
Das ist wirklich großartig, Chase, das Beste aus beiden Welten! Danke, dass du es ausprobiert hast.