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:
parent
130f24120b
commit
dceda1e555
@ -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
|
||||
|
@ -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) => {
|
||||
|
@ -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
59
lib/html.js
Normal 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
|
@ -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",
|
||||
|
@ -21,7 +21,7 @@ export class HeadProvider extends React.Component {
|
||||
|
||||
render () {
|
||||
const context = {
|
||||
...this.state,
|
||||
...this.props,
|
||||
push: this.push
|
||||
}
|
||||
|
||||
|
11
src/entry.js
11
src/entry.js
@ -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()
|
||||
|
96
src/index.js
96
src/index.js
@ -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>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user