diff --git a/examples/with-afterjs/.gitignore b/examples/with-afterjs/.gitignore new file mode 100644 index 000000000..52273a920 --- /dev/null +++ b/examples/with-afterjs/.gitignore @@ -0,0 +1,13 @@ +logs +*.log +npm-debug.log* +.DS_Store + +coverage +node_modules +build +public/static +.env.local +.env.development.local +.env.test.local +.env.production.local \ No newline at end of file diff --git a/examples/with-afterjs/README.md b/examples/with-afterjs/README.md new file mode 100644 index 000000000..73ddc7fb9 --- /dev/null +++ b/examples/with-afterjs/README.md @@ -0,0 +1,45 @@ +# Razzle Custom Webpack Configuration Example + +## How to use +Download the example [or clone the whole project](https://github.com/jaredpalmer/razzle.git): + +```bash +curl https://codeload.github.com/jaredpalmer/razzle/tar.gz/master | tar -xz --strip=2 razzle-master/examples/with-custom-webpack-config +cd with-custom-webpack-config +``` + +Install it and run: + +```bash +yarn install +yarn start +``` + +## Idea behind the example +This example demonstrates how to use a `razzle.config.js` file to modify Razzle's +underlying webpack configuration. It modifies the name of the server's output file +in production (`razzle build`). + +Note that this file is not transpiled, and so you must write it with vanilla +Node.js-compatible JavaScript. + +```js +// razzle.config.js +'use strict'; + +module.exports = { + modify(config, { target, dev }, webpack) { + const appConfig = config; // stay immutable here + + // Change the name of the server output file in production + if (target === 'node' && !dev) { + appConfig.output.filename = 'custom.js'; + } + + return appConfig; + }, +}; + + + +``` \ No newline at end of file diff --git a/examples/with-afterjs/lib/_app.js b/examples/with-afterjs/lib/_app.js new file mode 100644 index 000000000..bb725e9cf --- /dev/null +++ b/examples/with-afterjs/lib/_app.js @@ -0,0 +1,84 @@ +import React from 'react'; +import { Switch, Route, withRouter } from 'react-router-dom'; +import loadInitialProps from './loadInitialProps'; + +class App extends React.Component { + constructor(props) { + super(props); + this.state = { + data: props.data, + previousLocation: null, + }; + this.prefetcherCache = {}; + } + + // only runs clizzient + componentWillReceiveProps(nextProps, nextState) { + const navigated = nextProps.location !== this.props.location; + if (navigated) { + window.scrollTo(0, 0); + // save the location so we can render the old screen + this.setState({ + previousLocation: this.props.location, + data: undefined, // unless you want to keep it + }); + loadInitialProps(this.props.routes, nextProps.location.pathname, { + location: nextProps.location, + history: nextProps.history, + }) + .then(data => { + this.setState({ previousLocation: null, data: data[0] }); + }) + .catch(e => { + // @todo we should more cleverly handle errors??? + console.log(e); + }); + } + } + + prefetch = pathname => { + loadInitialProps(this.props.routes, pathname, { + history: this.props.history, + }) + .then(data => { + this.prefetcherCache = { ...this.prefetcherCache, [pathname]: data[0] }; + }) + .catch(e => console.log(e)); + }; + + updateData = data => { + this.setState({ data }); + }; + + render() { + const { previousLocation, data } = this.state; + const { location, history, match } = this.props; + const initialData = this.prefetcherCache[location.pathname] + ? this.prefetcherCache[location.pathname] + : data; + + return ( + + {this.props.routes.map((r, i) => ( + { + return React.createElement(r.component, { + ...initialData, + history, + location: previousLocation || location, + match, + prefetch: this.prefetch, + }); + }} + /> + ))} + + ); + } +} + +export default withRouter(App); diff --git a/examples/with-afterjs/lib/_document.js b/examples/with-afterjs/lib/_document.js new file mode 100644 index 000000000..3b4f2ae5e --- /dev/null +++ b/examples/with-afterjs/lib/_document.js @@ -0,0 +1,49 @@ +import React from 'react'; + +class Document extends React.Component { + static getInitialProps({ assets, data, renderPage }) { + const page = renderPage(); + return { assets, data, ...page }; + } + + render() { + const { helmet, assets, data } = this.props; + // get attributes from React Helmet + const htmlAttrs = helmet.htmlAttributes.toComponent(); + const bodyAttrs = helmet.bodyAttributes.toComponent(); + + return ( + + + + + Welcome to the Afterparty + + {helmet.title.toComponent()} + {helmet.meta.toComponent()} + {helmet.link.toComponent()} + {assets.client.css && ( + + )} + + +
DO_NOT_DELETE_THIS_YOU_WILL_BREAK_YOUR_APP
+