1
1
mirror of https://github.com/jxnblk/mdx-deck.git synced 2024-11-26 00:35:02 +03:00

Add head content to static output

This commit is contained in:
Brent Jackson 2018-08-14 19:15:56 -04:00
parent 130f24120b
commit dceda1e555
8 changed files with 139 additions and 63 deletions

View File

@ -1,8 +1,12 @@
export { future as theme } from '../themes'
import { Image, Notes, Appear } from '../dist'
import { Head, Image, Notes, Appear } from '../dist'
import { Invert, Split, SplitRight, FullScreenCode } from '../layouts'
import Counter from './Counter'
<Head>
<title>hello deck</title>
</Head>
# mdx-deck
MDX-based presention decks

View File

@ -1,12 +1,18 @@
const webpack = require('webpack')
const createConfig = require('./config')
const renderHTML = require('./html')
const build = async (opts = {}) => {
const { body, head } = await renderHTML(opts)
opts.head = head
opts.body = body
const config = createConfig(opts)
config.mode = 'production'
config.output = {
path: opts.outDir
}
const compiler = webpack(config)
return new Promise((resolve, reject) => {

View File

@ -54,7 +54,8 @@ const rules = [
]
const template = ({
title = 'ok',
head = '<title>mdx-deck</title>',
body = '',
js,
publicPath
}) => `<!DOCTYPE html>
@ -63,10 +64,10 @@ const template = ({
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<style>*{box-sizing:border-box}body{font-family:system-ui,sans-serif;margin:0}</style>
<title>${title}</title>
${head}
</head>
<body>
<div id=root></div>
<div id=root>${body}</div>
${HTMLPlugin.generateJSReferences(js, publicPath)}
</body>
</html>
@ -101,16 +102,16 @@ const baseConfig = {
}
const createConfig = (opts = {}) => {
baseConfig.context = opts.dirname
const config = Object.assign({}, baseConfig)
config.context = opts.dirname
baseConfig.resolve.modules.push(
config.resolve.modules.push(
opts.dirname,
path.join(opts.dirname, 'node_modules')
)
baseConfig.entry = [
config.entry = [
path.join(__dirname, '../dist/entry.js')
// opts.entry
]
const defs = Object.assign({}, opts.globals, {
@ -118,15 +119,11 @@ const createConfig = (opts = {}) => {
HOT_PORT: JSON.stringify(opts.hotPort)
})
baseConfig.plugins.push(
config.plugins.push(
new webpack.DefinePlugin(defs),
new HTMLPlugin({ template, context: opts })
)
const config = typeof opts.config === 'function'
? opts.config(baseConfig)
: baseConfig
if (config.resolve.alias) {
const hotAlias = config.resolve.alias['webpack-hot-client/client']
if (!fs.existsSync(hotAlias)) {

59
lib/html.js Normal file
View File

@ -0,0 +1,59 @@
const fs = require('fs')
const path = require('path')
const React = require('react')
const {
renderToString,
renderToStaticMarkup
} = require('react-dom/server')
const webpack = require('webpack')
const rimraf = require('rimraf')
const createConfig = require('./config')
const getApp = async opts => {
opts.tempdir = path.join(opts.outDir, 'TEMP')
if (!fs.existsSync(opts.outDir)) fs.mkdirSync(opts.outDir)
if (!fs.existsSync(opts.tempdir)) fs.mkdirSync(opts.tempdir)
const config = createConfig(opts)
config.output = {
path: opts.tempdir,
filename: '[name].js',
libraryTarget: 'umd'
}
config.entry = {
App: path.join(__dirname, '../dist/entry.js')
}
config.target = 'node'
const compiler = webpack(config)
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err) {
reject(err)
return
}
const App = require(
path.resolve(opts.tempdir, './App.js')
).default
rimraf(opts.tempdir, err => {
console.error(err)
})
resolve(App)
})
})
}
const renderHTML = async opts => {
const App = await getApp(opts)
const headTags = []
const body = renderToString(
React.createElement(App, { headTags })
)
const head = renderToStaticMarkup(headTags)
return { body, head }
}
module.exports = renderHTML

View File

@ -54,6 +54,7 @@
"react-syntax-highlighter": "^8.0.1",
"remark-emoji": "^2.0.1",
"remark-unwrap-images": "0.0.2-0",
"rimraf": "^2.6.2",
"stringify-object": "^3.2.2",
"styled-components": ">=3.0.0",
"styled-system": "^3.0.2",

View File

@ -21,7 +21,7 @@ export class HeadProvider extends React.Component {
render () {
const context = {
...this.state,
...this.props,
push: this.push
}

View File

@ -11,6 +11,7 @@ export default class App extends React.Component {
render () {
return (
<SlideDeck
{...this.props}
slides={slides}
theme={theme}
components={components}
@ -20,9 +21,11 @@ export default class App extends React.Component {
}
}
render(
<App />,
document.getElementById('root')
)
if (typeof document !== 'undefined') {
render(
<App />,
document.getElementById('root')
)
}
if (module.hot) module.hot.accept()

View File

@ -6,6 +6,7 @@ import debounce from 'lodash.debounce'
import querystring from 'querystring'
import Swipeable from 'react-swipeable'
import { Provider as ContextProvider } from './context'
import { HeadProvider } from './Head'
import DefaultProvider from './Provider'
import Carousel from './Carousel'
import Slide from './Slide'
@ -19,7 +20,7 @@ import GoogleFonts from './GoogleFonts'
import defaultTheme from './themes'
import defaultComponents from './components'
export { default as Head } from './Head'
export { Head } from './Head'
export { default as Image } from './Image'
export { default as Notes } from './Notes'
export { default as Appear } from './Appear'
@ -82,7 +83,8 @@ export class SlideDeck extends React.Component {
Provider: PropTypes.func,
width: PropTypes.string,
height: PropTypes.string,
ignoreKeyEvents: PropTypes.bool
ignoreKeyEvents: PropTypes.bool,
headTags: PropTypes.array.isRequired,
}
static defaultProps = {
@ -92,7 +94,8 @@ export class SlideDeck extends React.Component {
Provider: DefaultProvider,
width: '100vw',
height: '100vh',
ignoreKeyEvents: false
ignoreKeyEvents: false,
headTags: [],
}
state = {
@ -223,7 +226,8 @@ export class SlideDeck extends React.Component {
components: propsComponents,
Provider: PropsProvider,
width,
height
height,
headTags
} = this.props
const { index, length, mode, step} = this.state
@ -248,48 +252,50 @@ export class SlideDeck extends React.Component {
return (
<ContextProvider value={context}>
<ThemeProvider theme={theme}>
<MDXProvider
components={{
...defaultComponents,
...components
}}>
<Provider {...this.state} update={this.update}>
{mode === modes.grid ? (
<Grid
slides={slides}
update={this.update}
/>
) : (
<Swipeable
onSwipedLeft={() => this.update(inc)}
onSwipedRight={() => this.update(dec)}
trackMouse>
<Wrapper
{...this.state}
<HeadProvider tags={headTags}>
<ThemeProvider theme={theme}>
<MDXProvider
components={{
...defaultComponents,
...components
}}>
<Provider {...this.state} update={this.update}>
{mode === modes.grid ? (
<Grid
slides={slides}
width={width}
height={height}
update={this.update}>
<GoogleFonts />
<Carousel index={index}>
{slides.map((Component, i) => (
<Slide
key={i}
id={'slide-' + i}
index={i}
className='Slide'
>
<Component />
</Slide>
))}
</Carousel>
</Wrapper>
</Swipeable>
)}
</Provider>
</MDXProvider>
</ThemeProvider>
update={this.update}
/>
) : (
<Swipeable
onSwipedLeft={() => this.update(inc)}
onSwipedRight={() => this.update(dec)}
trackMouse>
<Wrapper
{...this.state}
slides={slides}
width={width}
height={height}
update={this.update}>
<GoogleFonts />
<Carousel index={index}>
{slides.map((Component, i) => (
<Slide
key={i}
id={'slide-' + i}
index={i}
className='Slide'
>
<Component />
</Slide>
))}
</Carousel>
</Wrapper>
</Swipeable>
)}
</Provider>
</MDXProvider>
</ThemeProvider>
</HeadProvider>
</ContextProvider>
)
}