Permalink
Browse files

initial commit

  • Loading branch information...
jamesknelson committed Jan 7, 2019
1 parent 3c79804 commit b64663812438257f53dbdb96917236f8a30b467b
Showing with 29,101 additions and 1 deletion.
  1. +6 −0 .gitignore
  2. +11 −0 .prettierrc
  3. +1 −1 LICENSE → LICENSE.md
  4. +93 −0 README.md
  5. +101 −0 cli.js
  6. +20 −0 package.json
  7. +31 −0 template-ts/navi.config.js
  8. +44 −0 template-ts/package.json
  9. BIN template-ts/public/favicon.ico
  10. +40 −0 template-ts/public/index.html
  11. +15 −0 template-ts/public/manifest.json
  12. +16 −0 template-ts/src/App.test.tsx
  13. +19 −0 template-ts/src/App.tsx
  14. +11 −0 template-ts/src/components/ArticleMeta.module.css
  15. +50 −0 template-ts/src/components/ArticleMeta.tsx
  16. +9 −0 template-ts/src/components/ArticleSummary.module.css
  17. +24 −0 template-ts/src/components/ArticleSummary.tsx
  18. +13 −0 template-ts/src/components/Bio.module.css
  19. +29 −0 template-ts/src/components/Bio.tsx
  20. +25 −0 template-ts/src/components/BlogIndexPage.module.css
  21. +61 −0 template-ts/src/components/BlogIndexPage.tsx
  22. +19 −0 template-ts/src/components/BlogLayout.module.css
  23. +48 −0 template-ts/src/components/BlogLayout.tsx
  24. +194 −0 template-ts/src/components/BlogPostLayout.module.css
  25. +66 −0 template-ts/src/components/BlogPostLayout.tsx
  26. +41 −0 template-ts/src/components/LoadingIndicator.module.css
  27. +23 −0 template-ts/src/components/LoadingIndicator.tsx
  28. 0 template-ts/src/components/NotFoundPage.module.css
  29. +17 −0 template-ts/src/components/NotFoundPage.tsx
  30. +11 −0 template-ts/src/components/Pagination.module.css
  31. +38 −0 template-ts/src/components/Pagination.tsx
  32. +9 −0 template-ts/src/components/TagIndexPage.module.css
  33. +32 −0 template-ts/src/components/TagIndexPage.tsx
  34. +20 −0 template-ts/src/components/TagPage.module.css
  35. +27 −0 template-ts/src/components/TagPage.tsx
  36. BIN template-ts/src/components/bio-pic.jpg
  37. +52 −0 template-ts/src/index.module.css
  38. +51 −0 template-ts/src/index.tsx
  39. +9 −0 template-ts/src/mdx-js.d.ts
  40. +9 −0 template-ts/src/pages/about/document.mdx
  41. +9 −0 template-ts/src/pages/about/document.module.css
  42. +6 −0 template-ts/src/pages/about/index.ts
  43. +108 −0 template-ts/src/pages/index.tsx
  44. +58 −0 template-ts/src/pages/posts/2019-01-05-welcome/document.mdx
  45. +39 −0 template-ts/src/pages/posts/2019-01-05-welcome/document.module.css
  46. +75 −0 template-ts/src/pages/posts/2019-01-05-welcome/navi-logo.svg
  47. +6 −0 template-ts/src/pages/posts/2019-01-05-welcome/post.ts
  48. +7 −0 template-ts/src/pages/posts/2019-01-05-welcome/react-logo.svg
  49. +86 −0 template-ts/src/pages/posts/index.ts
  50. +82 −0 template-ts/src/pages/tags.tsx
  51. +1 −0 template-ts/src/react-app-env.d.ts
  52. +81 −0 template-ts/src/renderPageToString.ts
  53. +57 −0 template-ts/src/renderRSSFeedToString.ts
  54. +135 −0 template-ts/src/serviceWorker.ts
  55. +12 −0 template-ts/src/siteMetadata.ts
  56. +10 −0 template-ts/src/utils/formats.ts
  57. +23 −0 template-ts/src/utils/getTagsFromSiteMap.ts
  58. +22 −0 template-ts/tsconfig.json
  59. +12,602 −0 template-ts/yarn.lock
  60. +31 −0 template/navi.config.js
  61. +38 −0 template/package.json
  62. BIN template/public/favicon.ico
  63. +40 −0 template/public/index.html
  64. +15 −0 template/public/manifest.json
  65. +14 −0 template/src/App.js
  66. +16 −0 template/src/App.test.js
  67. +43 −0 template/src/components/ArticleMeta.js
  68. +11 −0 template/src/components/ArticleMeta.module.css
  69. +16 −0 template/src/components/ArticleSummary.js
  70. +9 −0 template/src/components/ArticleSummary.module.css
  71. +22 −0 template/src/components/Bio.js
  72. +13 −0 template/src/components/Bio.module.css
  73. +56 −0 template/src/components/BlogIndexPage.js
  74. +25 −0 template/src/components/BlogIndexPage.module.css
  75. +41 −0 template/src/components/BlogLayout.js
  76. +19 −0 template/src/components/BlogLayout.module.css
  77. +64 −0 template/src/components/BlogPostLayout.js
  78. +194 −0 template/src/components/BlogPostLayout.module.css
  79. +19 −0 template/src/components/LoadingIndicator.js
  80. +41 −0 template/src/components/LoadingIndicator.module.css
  81. +17 −0 template/src/components/NotFoundPage.js
  82. 0 template/src/components/NotFoundPage.module.css
  83. +32 −0 template/src/components/Pagination.js
  84. +11 −0 template/src/components/Pagination.module.css
  85. +20 −0 template/src/components/TagIndexPage.js
  86. +9 −0 template/src/components/TagIndexPage.module.css
  87. +20 −0 template/src/components/TagPage.js
  88. +20 −0 template/src/components/TagPage.module.css
  89. BIN template/src/components/bio-pic.jpg
  90. +54 −0 template/src/index.js
  91. +52 −0 template/src/index.module.css
  92. +9 −0 template/src/pages/about/document.mdx
  93. +9 −0 template/src/pages/about/document.module.css
  94. +6 −0 template/src/pages/about/index.js
  95. +110 −0 template/src/pages/index.js
  96. +58 −0 template/src/pages/posts/2019-01-05-welcome/document.mdx
  97. +39 −0 template/src/pages/posts/2019-01-05-welcome/document.module.css
  98. +75 −0 template/src/pages/posts/2019-01-05-welcome/navi-logo.svg
  99. +6 −0 template/src/pages/posts/2019-01-05-welcome/post.js
  100. +7 −0 template/src/pages/posts/2019-01-05-welcome/react-logo.svg
  101. +82 −0 template/src/pages/posts/index.js
  102. +82 −0 template/src/pages/tags.js
  103. +77 −0 template/src/renderPageToString.js
  104. +51 −0 template/src/renderRSSFeedToString.js
  105. +135 −0 template/src/serviceWorker.js
  106. +11 −0 template/src/siteMetadata.js
  107. +10 −0 template/src/utils/formats.js
  108. +21 −0 template/src/utils/getTagsFromSiteMap.js
  109. +12,568 −0 template/yarn.lock
  110. +79 −0 yarn.lock
@@ -0,0 +1,6 @@
.esm-cache
.vscode
node_modules
build
*.log
dist
@@ -0,0 +1,11 @@
{
"useTabs": false,
"printWidth": 80,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "all",
"jsxBracketSameLine": true,
"parser": "typescript",
"semi": false,
"rcVerbose": false
}
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Frontend Armory
Copyright (c) 2019 James K Nelson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,93 @@
npx create-react-blog
=====================

Create a blog with **create-react-app**, **MDX**, and **Navi**.<br />
Themed after Gatsby's blog starter and Dan Abramov's overreacted.io.

Comes with:

⛑ TypeScript support<br />
📡 RSS feed generation<br />
🏷️ Tagged posts<br />
🚀 HTML files for each URL<br />
📜 Smooth scrolling to hash links<br />
🔥 Animated page loading transition<br />
🔗 Easy code splitting with `import()`<br />
⏩ Paginated index page


Getting started
---------------

The simplest way to get started is to use `npx`:

```bash
npx create-react-blog react-blog
cd react-blog
npm start
```

If you'd like to use TypeScript, just pass in a `--typescript` option:

```bash
npx create-react-blog react-blog --typescript
```

Alternatively, you can clone this repository yourself and use one of the templates yourself. If you take this approach, make sure to also run `npm install`:

```bash
git clone git@github.com:frontarm/create-react-blog.git
mv create-react-blog/template react-blog
cd react-blog
npm install
npm start
```

To statically build your blog and then start a local server for testing:

```bash
npm run build
npm run serve
```

The quickest and easiet way to deploy your blog is with [Netlify](https://netlify.com/), which is already set up and ready to go:

```bash
# Deploy to a test URL
npm run deploy
# Deploy to a production URL
npm run deploy:prod
```

Of course, since your site is just a bunch of HTML files, it can be deployed anywhere you'd like. Here's a couple alternatives:

- [Deploying with ZEIT Now](https://zeit.co/docs/v2/deployments/basics/)
- [Surge.sh](https://surge.sh/)


How to...
---------

**To update the site's title,** edit the metadata in `src/siteMetadata.js`.

**To change the site's colors,** edit the `:root` block in `src/index.module.css`.

**To create a new post,** add a new directory to `src/pages/posts` that is prefixed with the new post's publication date, then create a `post.js` file inside it:

```jsx
export default {
title: `Learn How To Build This Blog From Scratch`,
tags: ['react', 'navi'],
spoiler: "An online course with loads of live demos and exercises.",
getContent: () => import('./document.mdx'),
}
```

**To set the maximum number of posts on an index page,**, set the `indexPageSize` property of the object exported by `src/siteMetadata.js`.

**To modify the generated HTML,** update the `src/renderPageToString.js` file.

**To add non-blog pages,** just use [`Navi.createPage()`](https://frontarm.com/navi/reference/declarations/#createpage), [`Navi.createSwitch()`](https://frontarm.com/navi/reference/declarations/#createswitch) and [`Navi.createRedirect()`](https://frontarm.com/navi/reference/declarations/#createredirect). For an example, check the about page at [src/pages/about/index.js](src/pages/about/index.js). If you create a page, remember to add it to the root switch at [src/pages/index.js](src/pages/index.js).

**To brush up on React's fundamentals,** check out the [React (without the buzzwords)](https://frontarm.com/courses/learn-raw-react/) and [Asynchronous JavaScript](https://frontarm.com/courses/async-javascript/) courses.
101 cli.js
@@ -0,0 +1,101 @@
#!/usr/bin/env node
/**
* Based on initit
* https://github.com/c8r/initit
* MIT License
*/

const fs = require('fs-extra')
const path = require('path')
const os = require('os')
const exec = require('child_process').execSync
const spawn = require('cross-spawn')

const [name = 'react-blog'] = process.argv.slice(2)

create({ name, template: `frontarm/create-react-blog/template` })
.then(res => process.exit(0))
.catch(err => {
console.log(err)
process.exit(1)
})

function install() {
return new Promise((resolve, reject) => {
const child = spawn('npm', [ 'install' ], {
stdio: 'inherit'
})
child.on('close', code => {
if (code !== 0) {
reject()
return
}
resolve()
})
})
}

function gitInit () {
exec('git --version', { stdio: 'inherit' })
exec('git init', { stdio: 'inherit' })
exec('git add .', { stdio: 'inherit' })
exec('git commit -am "Init"', { stdio: 'inherit' })
return true
}

function getTar({
user,
repo,
path = '',
name
}) {
const url = `https://codeload.github.com/${user}/${repo}/tar.gz/master`
const cmd = `curl ${url} | tar -xz -C ${name} --strip=3 ${repo}-master/${path}`
exec(cmd, { stdio: 'inherit' })
}

async function create(opts = {}) {
if (!opts.name) {
throw new Error('name argument required')
return
}

if (!opts.template) {
throw new Error('template argument required')
return
}

const dirname = path.resolve(opts.name)
const name = path.basename(dirname)
const [ user, repo, ...paths ] = opts.template.split('/')

fs.ensureDirSync(name)

getTar(Object.assign({}, opts, {
name,
user,
repo,
path: paths.join('/')
}))

const templatePkg = require(
path.join(dirname, 'package.json')
)

const pkg = Object.assign({}, templatePkg, {
name,
version: '1.0.0',
})

fs.writeFileSync(
path.join(dirname, 'package.json'),
JSON.stringify(pkg, null, 2) + os.EOL
)

process.chdir(dirname)

const installed = await install()
const initialized = gitInit()

return { name, dirname }
}
@@ -0,0 +1,20 @@
{
"name": "create-react-blog",
"description": "Initialize a React blog with create-react-app, MDX, and Navi",
"version": "0.11.0",
"license": "MIT",
"author": "James K Nelson <james@frontarm.com>",
"bin": {
"create-react-blog": "cli.js"
},
"keywords": [
"mdx",
"blog",
"react",
"navi"
],
"dependencies": {
"cross-spawn": "^6.0.5",
"fs-extra": "^7.0.1"
}
}
@@ -0,0 +1,31 @@
import path from 'path'
import getTagsFromSiteMap from './src/utils/getTagsFromSiteMap'

export const resolveSiteMapOptions = {
/**
* navi-scripts will call this function when creating a list of URLs which
* need to be statically built. It allows you to substitute in a list of
* values when URLs contain wildcards, e.g. /tags/:tag -> ["/tags/react"]
*/
async expandPattern(pattern, router) {
if (/\/:tag$/.test(pattern)) {
let siteMap = await router.resolveSiteMap('/')
return getTagsFromSiteMap(siteMap).map(tag => pattern.replace(':tag', tag))
}
},
}

/**
* Get the file to write each URL to during the build
*/
export function getPagePathname({ url }) {
if (url.pathname === '/rss') {
return 'rss.xml'
}
if (url.pathname === '/') {
return 'index.html'
}
return path.join(url.pathname.slice(1), 'index.html')
}

export { default as renderPageToString } from './src/renderPageToString'
@@ -0,0 +1,44 @@
{
"name": "blog",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "23.3.12",
"@types/node": "10.12.18",
"@types/react": "16.7.18",
"@types/react-dom": "16.0.11",
"feed": "^2.0.2",
"import-all.macro": "^2.0.3",
"lodash": "^4.17.11",
"navi": "^0.10.5",
"navi-scripts": "^0.10.5",
"netlify-cli": "^2.6.0",
"prismjs": "^1.15.0",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-navi": "^0.10.0",
"react-scripts-mdx": "2.1.4",
"rimraf": "^2.6.2",
"slugify": "^1.3.2",
"ts-node": "^7.0.1",
"typescript": "^3.2.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && ts-node -O {\\\"module\\\":\\\"commonjs\\\"} node_modules/.bin/navi-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"serve": "navi-scripts serve",
"deploy": "netlify deploy --dir=build",
"deploy:prod": "netlify deploy --dir=build --prod"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Binary file not shown.
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
@@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
@@ -0,0 +1,16 @@
import * as Navi from 'navi'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import pages from './pages'

it('renders without crashing', () => {
const div = document.createElement('div')
const navigation = Navi.createMemoryNavigation({
pages,
url: '/',
})

ReactDOM.render(<App navigation={navigation} />, div)
ReactDOM.unmountComponentAtNode(div)
})
Oops, something went wrong.

0 comments on commit b646638

Please sign in to comment.