Skip to content

Commit

Permalink
feat(docz): add a mvp version of project
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Apr 15, 2018
1 parent 9d56d02 commit 05ac064
Show file tree
Hide file tree
Showing 11 changed files with 355 additions and 145 deletions.
3 changes: 2 additions & 1 deletion packages/playgrood/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ yargs
yargs => {
yargs.positional('files', {
type: 'string',
default: '**/*.doc.(js|jsx)',
default: '**/*.(js|jsx)',
describe: 'files that you want to document',
require: true,
})
},
server
Expand Down
20 changes: 13 additions & 7 deletions packages/playgrood/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"name": "playgrodd",
"description": "Blazing fast and zero config React components playground",
"version": "0.0.0",
"preferGlobal": true,
"main": "./build/main/index.js",
"version": "0.0.1",
"main": "./build/main/index.jsx",
"typings": "./build/main/index.d.ts",
"module": "./build/module/index.js",
"module": "./build/module/index.jsx",
"bin": {
"playgrodd": "./bin/index.js"
},
Expand All @@ -14,28 +13,35 @@
"build:main": "tsc -p tsconfig.json",
"build:module": "tsc -p tsconfig.module.json",
"fix": "run-s fix:*",
"fix:prettier": "prettier \"src/**/*.ts\" --write",
"fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write",
"fix:tslint": "tslint --fix --project .",
"watch": "run-s clean build:main && run-p \"build:main -- -w\"",
"clean": "trash build"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"babylon": "^6.18.0",
"emotion": "^9.0.2",
"express": "^4.16.3",
"fast-glob": "^2.2.0",
"history": "^4.7.2",
"mkdirp": "^0.5.1",
"parcel-bundler": "^1.6.2",
"prop-types": "^15.6.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-emotion": "^9.0.2",
"react-router-dom": "^4.2.2",
"trash": "^4.3.0",
"uuid": "^3.2.1",
"yargs": "^11.0.0"
},
"devDependencies": {
"@types/babylon": "^6.16.2",
"@types/express": "^4.11.1",
"@types/mkdirp": "^0.5.2",
"@types/node": "^9.4.7",
"@types/react-dom": "^16.0.4",
"@types/react-router-dom": "^4.2.5",
"@types/trash": "^4.3.0",
"@types/uuid": "^3.4.3",
"@types/yargs": "^11.0.0",
"npm-run-all": "^4.1.2",
Expand Down
28 changes: 28 additions & 0 deletions packages/playgrood/src/components/Html.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from 'react'

import { IComponent } from '../utils/components'

export interface IHtmlProps {
components: IComponent[]
}

export const Html: React.SFC<IHtmlProps> = ({ components }) => {
const stringifiedComps = JSON.stringify(components)

return (
<html>
<head>
<title>playgrodd</title>
<body>
<div id="root" />
<script src="./index.jsx" />
<script
dangerouslySetInnerHTML={{
__html: `window.__PLAYGRODD_COMPONENTS__ = ${stringifiedComps}`,
}}
/>
</body>
</head>
</html>
)
}
1 change: 0 additions & 1 deletion packages/playgrood/src/index.ts

This file was deleted.

13 changes: 0 additions & 13 deletions packages/playgrood/src/server.ts

This file was deleted.

26 changes: 26 additions & 0 deletions packages/playgrood/src/server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react'
import express, { Request, Response } from 'express'
import { Arguments } from 'yargs'
import { renderToString } from 'react-dom/server'

import { componentsFromPattern } from './utils/components'
import { createBundle, DIST_PATH } from './utils/bundle'
import { generateEntry } from './utils/entry'

import { Html } from './components/Html'

exports.server = async ({ files: pattern }: Arguments) => {
const app = express()
const components = componentsFromPattern(pattern)
const html = renderToString(<Html components={components} />)
const entry = generateEntry(components)

const bundle = await createBundle(html, entry)

app.use(express.static(DIST_PATH))
app.use('/*', async (req: Request, res: Response) => {
res.sendFile(bundle.name)
})

app.listen(3000)
}
55 changes: 55 additions & 0 deletions packages/playgrood/src/utils/bundle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import fs from 'fs'
import path from 'path'
import mkdir from 'mkdirp'
import Bundler from 'parcel-bundler'
import trash from 'trash'

const ROOT_PATH = fs.realpathSync(process.cwd())
const PLAYGRODD_PATH = path.join(ROOT_PATH, '.playgrodd')
const THEME_PATH = path.join(PLAYGRODD_PATH, 'theme')
const INDEX_HTML = path.join(THEME_PATH, 'index.html')
const INDEX_JS = path.join(THEME_PATH, 'index.jsx')

export const CACHE_PATH = path.join(PLAYGRODD_PATH, 'cache')
export const DIST_PATH = path.join(PLAYGRODD_PATH, 'dist')

const checkMkdirTheme = () => {
try {
fs.lstatSync(THEME_PATH)
} catch (err) {
mkdir.sync(THEME_PATH)
}
}

const tempFile = (filepath: string, content: string) =>
new Promise((resolve, reject) => {
checkMkdirTheme()

try {
fs.writeFileSync(filepath, content, 'utf-8')
resolve()
} catch (err) {
reject(err)
}
})

export const createBundle = async (html: string, entry: string) => {
await trash(DIST_PATH)
await trash(THEME_PATH)
await tempFile(INDEX_JS, entry)
await tempFile(INDEX_HTML, html)

const bundler = new Bundler(INDEX_HTML, {
cacheDir: CACHE_PATH,
outDir: DIST_PATH,
publicURL: '/',
outFile: 'index',
})

try {
return await bundler.bundle()
} catch (err) {
console.log(err)
return null
}
}
12 changes: 8 additions & 4 deletions packages/playgrood/src/utils/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { v4 } from 'uuid'
import { parse } from 'babylon'
import { File, Comment } from 'babel-types'

export interface Component {
export interface IComponent {
readonly id: string
readonly filepath: string
readonly route: string
Expand Down Expand Up @@ -45,9 +45,13 @@ const parseEntry = (entry: string) => {
}
}

const filterByManifest = (component: Component) => !!component.hasManifest
const filterByManifest = (component: IComponent) => !!component.hasManifest

export const componentsFromPattern = (pattern: string): IComponent[] => {
const ignoreGlob = '!node_modules'
const entries: string[] = glob.sync(
Array.isArray(pattern) ? [...pattern, ignoreGlob] : [pattern, ignoreGlob]
)

export const componentsFromPattern = (pattern: string): Component[] => {
const entries: string[] = glob.sync(pattern)
return entries.map(parseEntry).filter(filterByManifest)
}
57 changes: 57 additions & 0 deletions packages/playgrood/src/utils/entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { IComponent } from './components'

const mountLink = (component: IComponent) =>
`<li>
<Link to="/${component.route}">${component.name}</Link>
</li>`

const componentRoute = (component: IComponent) =>
`class Route${component.name} extends React.Component {
constructor(props, ctx) {
super(props, ctx)
this.state = {
render: () => null
}
}
async componentDidMount() {
const { doc: render } = await import('${component.filepath}')
this.setState({ render })
}
render() {
return <div>{this.state.render()}</div>
}
}`

const mountRoute = (component: IComponent) =>
`<Route
exact
path="/${component.route}"
render={(props) => {
const Comp = ${componentRoute(component)}
return <Comp {...props} />
}}
/>`

export const generateEntry = (components: IComponent[]) => {
return `
import 'babel-polyfill'
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link } from 'react-router-dom'
import { createBrowserHistory } from 'history'
const App = () => (
<Router history={createBrowserHistory()}>
<div>
<ul>${components.map(mountLink).join('')}</ul>
<div>${components.map(mountRoute).join('')}</div>
</div>
</Router>
)
render(<App />, document.querySelector('#root'))
`
}
7 changes: 4 additions & 3 deletions packages/playgrood/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"inlineSourceMap": true,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,

"jsx": "react",
"strict": true /* Enable all strict type-checking options. */,

/* Strict Type-Checking Options */
Expand All @@ -21,7 +22,7 @@

/* Additional Checks */
"noUnusedLocals": true /* Report errors on unused locals. */,
"noUnusedParameters": true /* Report errors on unused parameters. */,
"noUnusedParameters": false /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,

Expand All @@ -35,11 +36,11 @@
// "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
// "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,

"lib": ["es2017"],
"lib": ["es2017", "dom"],
"types": ["node"],
"typeRoots": ["node_modules/@types", "src/types"]
},
"include": ["src/**/*.ts"],
"include": ["src/**/*"],
"exclude": ["node_modules/**"],
"compileOnSave": false
}
Loading

0 comments on commit 05ac064

Please sign in to comment.