Skip to content

Commit

Permalink
feat(docz-core): add basic plugin logic
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Apr 15, 2018
1 parent 5ec9fde commit add17ad
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 35 deletions.
4 changes: 3 additions & 1 deletion packages/playgrodd-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
"express": "^4.16.3",
"fast-glob": "^2.2.0",
"load-cfg": "^0.0.1",
"mkdirp": "^0.5.1"
"mkdirp": "^0.5.1",
"prettier": "^1.12.0"
},
"devDependencies": {
"@types/babel-traverse": "^6.25.3",
"@types/babylon": "^6.16.2",
"@types/del": "^3.0.1",
"@types/express": "^4.11.1",
"@types/mkdirp": "^0.5.2",
"@types/prettier": "^1.12.0",
"shelljs": "^0.8.1"
}
}
88 changes: 75 additions & 13 deletions packages/playgrodd-core/src/Bundler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import * as fs from 'fs'
import * as path from 'path'
import * as mkdir from 'mkdirp'
import * as del from 'del'
import { compile } from 'art-template'
import * as prettier from 'prettier'

import * as paths from './config/paths'
import { Entry } from './Entry'
import { Plugin, IPluginFactory } from './Plugin'
import { ConfigArgs } from './Server'

const mkd = (dir: string): void => {
Expand All @@ -15,7 +18,16 @@ const mkd = (dir: string): void => {
}
}

const touch = (file: string, content: string) => {
const format = (raw: string) =>
prettier.format(raw, {
semi: false,
singleQuote: true,
trailingComma: 'all',
})

const touch = (file: string, raw: string) => {
const content = /js/.test(path.extname(file)) ? format(raw) : raw

mkd(paths.playgrodd)
fs.writeFileSync(file, content, 'utf-8')
}
Expand All @@ -28,7 +40,7 @@ export type TCompilerFn<C> = (config: C) => Promise<any>
export type TServerFn<S> = (compiler: any) => S

export interface ICompilerOpts {
theme: string
args: ConfigArgs
}

export interface IConstructorParams<C, S> extends ICompilerOpts {
Expand All @@ -44,35 +56,85 @@ const html = compiled('index.tpl.html')

export class Bundler<C = any, S = any> {
readonly id: string
readonly theme: string
readonly args: ConfigArgs
private config: TConfigFn<C>
private compiler: TCompilerFn<C>
private server: TServerFn<S>

constructor({
args,

id,
config,
theme,
compiler,
server,
}: IConstructorParams<C, S>) {
this.args = args
this.id = id
this.theme = theme
this.config = config
this.compiler = compiler
this.server = server
}

public async createCompiler(entries: Entry[]) {
const { theme } = this
const config = this.config(entries)
private reduceWithPlugins(dev: boolean) {
return (config: C, plugin: Plugin) =>
plugin.bundlerConfig(config, dev) || config
}

private mountConfig(entries: Entry[]) {
const { plugins, env } = this.args

const dev = env === 'development'
const initialConfig = this.config(entries)

return Boolean(plugins) && plugins.length > 0
? plugins.reduce(this.reduceWithPlugins(dev), initialConfig)
: initialConfig
}

private routesFromEntries(entries: Entry[]) {
return (
entries &&
entries.length > 0 &&
entries.reduce((obj, entry) => {
return Object.assign({}, obj, { [entry.name]: entry.route })
}, {})
)
}

private propOfPlugins(method: keyof IPluginFactory) {
const { plugins } = this.args
return plugins && plugins.map(p => p[method]).filter(m => m)
}

private generateFilesByTemplate(entries: Entry[]) {
const { theme } = this.args

await del(paths.playgrodd)
touch(paths.appJs, app({ theme, entries }))
touch(paths.indexJs, js({}))
touch(paths.indexHtml, html({}))

return await this.compiler(config)
touch(
paths.appJs,
app({
THEME: theme,
ENTRIES: entries,
ROUTES: JSON.stringify(this.routesFromEntries(entries)),
WRAPPERS: this.propOfPlugins('wrapper'),
})
)

touch(
paths.indexJs,
js({
BEFORE_RENDERS: this.propOfPlugins('beforeRender'),
AFTER_RENDERS: this.propOfPlugins('afterRender'),
})
)
}

public async createCompiler(entries: Entry[]) {
await del(paths.playgrodd)
this.generateFilesByTemplate(entries)
return await this.compiler(this.mountConfig(entries))
}

public async createServer(compiler: any): Promise<S> {
Expand All @@ -96,8 +158,8 @@ export function createBundler<C, S>(
): IBundlerCreate<C, S> {
return (args: ConfigArgs): Bundler<C, S> =>
new Bundler({
args,
id: factory.id,
theme: args.theme,
config: factory.config(args),
compiler: factory.compiler(args),
server: factory.server(args),
Expand Down
49 changes: 47 additions & 2 deletions packages/playgrodd-core/src/Plugin.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
export function createPlugin<Config = any, Server = any>() {
return null
import { isFn } from './utils/helpers'

export type IBundlerConfig = <Config>(config: Config, dev: boolean) => Config
export type IBundlerCompiler = <Compiler>(compiler: Compiler) => void
export type IBundlerServer = <Server>(server: Server) => void
export type IBeforeRender = () => void
export type IAfterRender = () => void
export type IWrapper = <R>(props: { children: any }) => R

export interface IPluginFactory {
bundlerConfig: IBundlerConfig
bundlerCompiler: IBundlerCompiler
bundlerServer: IBundlerServer
beforeRender: IBeforeRender
afterRender: IAfterRender
wrapper: IWrapper
}

export class Plugin {
readonly bundlerConfig: IBundlerConfig
readonly bundlerCompiler: IBundlerCompiler
readonly bundlerServer: IBundlerServer
readonly beforeRender: IBeforeRender
readonly afterRender: IAfterRender
readonly wrapper: IWrapper

constructor(p: IPluginFactory) {
this.bundlerConfig = (config: any, dev: boolean) => {
return isFn(p.bundlerConfig) && p.bundlerConfig(config, dev)
}

this.bundlerCompiler = async (compiler: any) => {
isFn(p.bundlerCompiler) && (await p.bundlerCompiler(compiler))
}

this.bundlerServer = async (server: any) => {
isFn(p.bundlerServer) && (await p.bundlerServer(server))
}

this.beforeRender = p.beforeRender
this.afterRender = p.afterRender
this.wrapper = p.wrapper
}
}

export function createPlugin(factory: IPluginFactory) {
return new Plugin(factory)
}
3 changes: 2 additions & 1 deletion packages/playgrodd-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { Paths } from './config/Paths'

export { Entry } from './Entry'
export { createBundler, IBundlerCreate } from './Bundler'
export { Server, ConfigArgs } from './server'
export { createPlugin } from './Plugin'
export { Server, ConfigArgs } from './Server'
39 changes: 25 additions & 14 deletions packages/playgrodd-core/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { pick } from './utils/helpers'

import { Entries } from './Entries'
import { Bundler } from './Bundler'
import { Plugin } from './Plugin'

process.env.BABEL_ENV = process.env.BABEL_ENV || 'development'
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
Expand All @@ -13,17 +14,6 @@ const ENV = process.env.NODE_ENV
const HOST = process.env.HOST || '0.0.0.0'
const PROTOCOL = process.env.HTTPS === 'true' ? 'https' : 'http'

export interface ConfigArgs {
paths: any
port: number
theme: string
src: string
env: string
host: string
protocol: string
plugins: any[]
}

export interface IConstructorParams {
port: number
theme: string
Expand All @@ -32,25 +22,39 @@ export interface IConstructorParams {
src: string
}

export interface ConfigArgs extends IConstructorParams {
paths: any
env: string
host: string
protocol: string
plugins: Plugin[]
}

export class Server {
private port: number
private src: string
private bundler: Bundler
private plugins: Plugin[]
private entries: Entries
private bundler: Bundler

constructor(args: IConstructorParams) {
const initialArgs = this.getInitialArgs(args)
const { port, theme, files, bundler, src } = load('playgrodd', initialArgs)
const { port, theme, files, bundler, src, plugins } = load(
'playgrodd',
initialArgs
)

this.port = port
this.src = src
this.plugins = plugins
this.entries = new Entries(files)

this.bundler = this.getBundler(bundler).bundler({
port,
paths,
theme,
src,
plugins,
env: ENV,
host: HOST,
protocol: PROTOCOL,
Expand All @@ -70,11 +74,18 @@ export class Server {
}

public async start() {
const { entries, bundler } = this
const { bundler, entries, plugins } = this

const compiler = await bundler.createCompiler(entries.parse(this.src))
const server = await bundler.createServer(compiler)

if (plugins && plugins.length > 0) {
for (const plugin of plugins) {
await plugin.bundlerCompiler(compiler)
await plugin.bundlerServer(server)
}
}

server.listen(this.port)
}
}
23 changes: 20 additions & 3 deletions packages/playgrodd-core/templates/app.tpl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
<% entries.forEach(function(entry) { %>import '<%- entry.filepath %>'
<% ENTRIES.forEach(function(entry) { %>import '<%- entry.filepath %>'
<% }); %>
import React from 'react'
import { hot } from 'react-hot-loader'
import { Theme } from '<%- theme %>'
import { Theme } from '<%- THEME %>'

export const App = hot(module)(Theme)
const _wrappers = [<%- WRAPPERS %>]

const recursiveWrappers = ([Wrapper, ...rest], props) => (
<Wrapper {...props}>
{rest.length ? recursiveWrappers(rest, props) : props.children}
</Wrapper>
)

const Wrapper = props =>
_wrappers.length ? recursiveWrappers(_wrappers, props) : props.children

const WrappedTheme = () => (
<Wrapper>
<Theme routes={<%- ROUTES %>} />
</Wrapper>
)

export const App = hot(module)(WrappedTheme)
9 changes: 8 additions & 1 deletion packages/playgrodd-core/templates/index.tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@ import React from 'react'
import { render } from 'react-dom'
import { App } from './app'

render(<App />, document.querySelector('#root'))
const _beforeRenders = [<%- BEFORE_RENDERS %>]
const _afterRenders = [<%- AFTER_RENDERS %>]

const beforeRender = () => _beforeRenders.forEach(f => f && f())
const afterRender = () => _afterRenders.forEach(f => f && f())

beforeRender()
render(<App />, document.querySelector('#root'), afterRender)
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,10 @@
version "9.6.4"
resolved "https://registry.npmjs.org/@types/node/-/node-9.6.4.tgz#0ef7b4cfc3499881c81e0ea1ce61a23f6f4f5b42"

"@types/prettier@^1.12.0":
version "1.12.0"
resolved "https://registry.npmjs.org/@types/prettier/-/prettier-1.12.0.tgz#61ed6bdc64386f49c9e1f179cf84ef26ddc4740c"

"@types/react-dom@^16.0.5":
version "16.0.5"
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.0.5.tgz#a757457662e3819409229e8f86795ff37b371f96"
Expand Down Expand Up @@ -5965,6 +5969,10 @@ prettier@^1.11.1:
version "1.11.1"
resolved "https://registry.npmjs.org/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"

prettier@^1.12.0:
version "1.12.0"
resolved "https://registry.npmjs.org/prettier/-/prettier-1.12.0.tgz#d26fc5894b9230de97629b39cae225b503724ce8"

pretty-error@^2.0.2, pretty-error@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
Expand Down

0 comments on commit add17ad

Please sign in to comment.