Skip to content

Commit

Permalink
Switch from React to Preact
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Spitzer committed Apr 22, 2018
1 parent 71a2fc7 commit 14bc486
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 47 deletions.
15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.3.2",
"react-dom": "^16.3.2",
"preact": "^8.2.7",
"preact-compat": "^3.18.0",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"start": "node scripts/start",
"build": "node scripts/build",
"test": "node scripts/test --env=jsdom",
"eject": "react-scripts eject",
"preanalyze": "npm run build",
"analyze": "source-map-explorer --html build/static/js/main.* > packages.html"
},
"devDependencies": {
"module-alias": "^2.0.6",
"preact-compat-enzyme": "^0.2.5",
"preact-render-to-json": "^3.6.6",
"preact-test-utils": "^0.1.3",
"pretty-format": "^22.4.3",
"source-map-explorer": "^1.5.0"
}
}
33 changes: 14 additions & 19 deletions packages.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="data:text/css;base64,LyogVmVuZG9yZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcm1taC93ZWJ0cmVlbWFwL2Jsb2IvOWZhMGMwNjZhMTBlYTQ0MDJkOTYwYjBjNmMxYTQzMjg0NmFjN2ZjNC93ZWJ0cmVlbWFwLmNzcyAqLwoKLndlYnRyZWVtYXAtbm9kZSB7CiAgLyogUmVxdWlyZWQgYXR0cmlidXRlcy4gKi8KICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgb3ZlcmZsb3c6IGhpZGRlbjsgICAvKiBUbyBoaWRlIG92ZXJsb25nIGNhcHRpb25zLiAqLwogIGJhY2tncm91bmQ6IHdoaXRlOyAgLyogTm9kZXMgbXVzdCBiZSBvcGFxdWUgZm9yIHpJbmRleCBsYXllcmluZy4gKi8KICBib3JkZXI6IHNvbGlkIDFweCBibGFjazsgIC8qIENhbGN1bGF0aW9ucyBhc3N1bWUgMXB4IGJvcmRlci4gKi8KCiAgLyogT3B0aW9uYWw6IENTUyBhbmltYXRpb24uICovCiAgdHJhbnNpdGlvbjogdG9wICAgIDAuM3MsCiAgICAgICAgICAgICAgbGVmdCAgIDAuM3MsCiAgICAgICAgICAgICAgd2lkdGggIDAuM3MsCiAgICAgICAgICAgICAgaGVpZ2h0IDAuM3M7Cn0KCi8qIE9wdGlvbmFsOiBoaWdobGlnaHQgbm9kZXMgb24gbW91c2VvdmVyLiAqLwoud2VidHJlZW1hcC1ub2RlOmhvdmVyIHsKICBiYWNrZ3JvdW5kOiAjZWVlOwp9CgovKiBPcHRpb25hbDogRGlmZmVyZW50IGJhY2tncm91bmQgY29sb3JzIGRlcGVuZGluZyBvbiBzeW1ib2wuICovCi53ZWJ0cmVlbWFwLXN5bWJvbC1ic3MgewogIGJhY2tncm91bmQ6ICM2NkMyQTU7Cn0KLndlYnRyZWVtYXAtc3ltYm9sLWRhdGEgewogIGJhY2tncm91bmQ6ICNGQzhENjI7Cn0KLndlYnRyZWVtYXAtc3ltYm9sLXJlYWQtb25seV9kYXRhIHsKICBiYWNrZ3JvdW5kOiAjOERBMENCOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1jb2RlIHsKICBiYWNrZ3JvdW5kOiAjRTc4QUMzOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC13ZWFrX3N5bWJvbCB7CiAgYmFja2dyb3VuZDogI0E2RDg1NDsKfQoud2VidHJlZW1hcC1zeW1ib2wtYnNzLndlYnRyZWVtYXAtYWdncmVnYXRlIHsKICBiYWNrZ3JvdW5kOiAjQjNFMkNEOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1kYXRhLndlYnRyZWVtYXAtYWdncmVnYXRlIHsKICBiYWNrZ3JvdW5kOiAjRkRDREFDOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1yZWFkLW9ubHlfZGF0YS53ZWJ0cmVlbWFwLWFnZ3JlZ2F0ZSB7CiAgYmFja2dyb3VuZDogI0NCRDVFODsKfQoud2VidHJlZW1hcC1zeW1ib2wtY29kZS53ZWJ0cmVlbWFwLWFnZ3JlZ2F0ZSB7CiAgYmFja2dyb3VuZDogI0Y0Q0FFNDsKfQoud2VidHJlZW1hcC1zeW1ib2wtd2Vha19zeW1ib2wud2VidHJlZW1hcC1hZ2dyZWdhdGUgewogIGJhY2tncm91bmQ6ICNFNkY1Qzk7Cn0KCiNsZWdlbmQgPiAqIHsKICBib3JkZXI6IHNvbGlkIDFweCAjNDQ0Owp9CgovKiBPcHRpb25hbDogRGlmZmVyZW50IGJvcmRlcnMgZGVwZW5kaW5nIG9uIGxldmVsLiAqLwoud2VidHJlZW1hcC1sZXZlbDAgewogIGJvcmRlcjogc29saWQgMXB4ICM0NDQ7Cn0KLndlYnRyZWVtYXAtbGV2ZWwxIHsKICBib3JkZXI6IHNvbGlkIDFweCAjNjY2Owp9Ci53ZWJ0cmVlbWFwLWxldmVsMiB7CiAgYm9yZGVyOiBzb2xpZCAxcHggIzg4ODsKfQoud2VidHJlZW1hcC1sZXZlbDMgewogIGJvcmRlcjogc29saWQgMXB4ICNhYWE7Cn0KLndlYnRyZWVtYXAtbGV2ZWw0IHsKICBib3JkZXI6IHNvbGlkIDFweCAjY2NjOwp9CgovKiBPcHRpb25hbDogc3R5bGluZyBvbiBub2RlIGNhcHRpb25zLiAqLwoud2VidHJlZW1hcC1jYXB0aW9uIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDExcHg7CiAgcGFkZGluZzogMnB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKLyogT3B0aW9uYWw6IHN0eWxpbmcgb24gY2FwdGlvbnMgb24gbW91c2UgaG92ZXIuICovCi8qLndlYnRyZWVtYXAtbm9kZTpob3ZlciA+IC53ZWJ0cmVlbWFwLWNhcHRpb24gewogIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOwp9Ki8K">
<title>build/static/js/main.a3b22bcc.js - Source Map Explorer</title>
<title>build/static/js/main.d722544c.js - Source Map Explorer</title>

<style>
html, body {
Expand Down Expand Up @@ -43,31 +43,26 @@

<script>
var tree = {
"../static/js/main.a3b22bcc.js": 1936,
"../webpack/bootstrap ba60ac32d722a99c6e16": 449,
"../node_modules/object-assign/index.js": 923,
"../node_modules/react/index.js": 18,
"../static/js/main.d722544c.js": 2124,
"../webpack/bootstrap 37631ed09a0f3e7fb3b8": 449,
"../node_modules/preact-compat/dist/preact-compat.es.js": 9092,
"../node_modules/promise/lib/core.js": 1842,
"../node_modules/fbjs/lib/invariant.js": 374,
"../node_modules/fbjs/lib/emptyObject.js": 23,
"../node_modules/fbjs/lib/emptyFunction.js": 252,
"../node_modules/react-scripts/config/polyfills.js": 94,
"../node_modules/react-scripts/config/polyfills.js": 92,
"../node_modules/promise/lib/rejection-tracking.js": 1169,
"../node_modules/asap/browser-raw.js": 645,
"../node_modules/webpack/buildin/global.js": 146,
"../node_modules/promise/lib/es6-extensions.js": 1186,
"../node_modules/whatwg-fetch/fetch.js": 7254,
"../node_modules/object-assign/index.js": 923,
"index.js": 88,
"../node_modules/react/cjs/react.production.min.js": 5201,
"../node_modules/react-dom/index.js": 225,
"../node_modules/react-dom/cjs/react-dom.production.min.js": 98750,
"../node_modules/fbjs/lib/ExecutionEnvironment.js": 280,
"../node_modules/fbjs/lib/getActiveElement.js": 177,
"../node_modules/fbjs/lib/shallowEqual.js": 381,
"../node_modules/fbjs/lib/containsNode.js": 194,
"../node_modules/fbjs/lib/isTextNode.js": 67,
"../node_modules/fbjs/lib/isNode.js": 231,
"App.js": 401,
"../node_modules/process/browser.js": 1673,
"../node_modules/prop-types/index.js": 19,
"../node_modules/prop-types/factoryWithThrowingShims.js": 505,
"../node_modules/fbjs/lib/emptyFunction.js": 252,
"../node_modules/fbjs/lib/invariant.js": 374,
"../node_modules/prop-types/lib/ReactPropTypesSecret.js": 59,
"../node_modules/preact/dist/preact.esm.js": 8488,
"App.js": 482,
"logo.svg": 48,
"registerServiceWorker.js": 1269,
"<unmapped>": 42
Expand Down
10 changes: 10 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node

process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';

const webpackPreact = require('./patch/webpackPreact');
const webpackConfig = require('react-scripts/config/webpack.config.prod');
webpackPreact(webpackConfig);

require('react-scripts/scripts/build');
6 changes: 6 additions & 0 deletions scripts/patch/webpackPreact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Hack the webpack config to load Preact instead of React
module.exports = webpackConfig =>
(webpackConfig.resolve.alias = Object.assign({}, webpackConfig.resolve.alias, {
react: 'preact-compat',
'react-dom': 'preact-compat'
}));
10 changes: 10 additions & 0 deletions scripts/start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node

process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';

const webpackPreact = require('./patch/webpackPreact');
const webpackConfig = require('react-scripts/config/webpack.config.dev');
webpackPreact(webpackConfig);

require('react-scripts/scripts/start');
30 changes: 30 additions & 0 deletions scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env node

process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';

// Load the create-react-app config.
const jestConfig = require('react-scripts/scripts/utils/createJestConfig');

// Map React's testing classes to Preact
const newJestConfig = function() {
const config = jestConfig.apply(this, arguments);
config.moduleNameMapper = Object.assign({}, config.moduleNameMapper, {
'^react-dom/server$': '<rootDir>/node_modules/preact-render-to-string/dist/index.js',
'^react-dom/test-utils$': '<rootDir>/node_modules/preact-test-utils/lib/index.js',
'^react-dom$': '<rootDir>/node_modules/preact-compat-enzyme/lib/index.js',
'^react-test-renderer/shallow$': '<rootDir>/node_modules/preact-test-utils/lib/index.js',
'^react-test-renderer$': '<rootDir>/node_modules/preact-test-utils/lib/index.js',
'^react-addons-test-utils$': '<rootDir>/node_modules/preact-test-utils/lib/index.js',
'^react$': '<rootDir>/node_modules/preact-compat-enzyme/lib/index.js'
});
return config;
};

// HACK ALERT!
module.constructor._cache[
require.resolve('react-scripts/scripts/utils/createJestConfig')
].exports = newJestConfig;

// Run the build.
require('react-scripts/scripts/test');
8 changes: 8 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

// This is just a Thing
class Thing extends Component {
render() {
return <div className="thing" />;
}
}

class App extends Component {
render() {
return (
Expand All @@ -13,6 +20,7 @@ class App extends Component {
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<Thing />
</div>
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/App.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,13 @@ it('renders without crashing', () => {
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

it('can render into snapshots', () => {
const tree = global.render(<App />);
expect(tree).toMatchSnapshot();
});

it('can shallow render into snapshots', () => {
const tree = global.shallowRender(<App />);
expect(tree).toMatchSnapshot();
});
65 changes: 65 additions & 0 deletions src/__snapshots__/App.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`can render into snapshots 1`] = `
<div
class="App"
>
<header
class="App-header"
>
<img
alt="logo"
class="App-logo"
src="logo.svg"
/>
<h1
class="App-title"
>
Welcome to React
</h1>
</header>
<p
class="App-intro"
>
To get started, edit
<code>
src/App.js
</code>
and save to reload.
</p>
<div
class="thing"
/>
</div>
`;

exports[`can shallow render into snapshots 1`] = `
<div
class="App"
>
<header
class="App-header"
>
<img
alt="logo"
class="App-logo"
src="logo.svg"
/>
<h1
class="App-title"
>
Welcome to React
</h1>
</header>
<p
class="App-intro"
>
To get started, edit
<code>
src/App.js
</code>
and save to reload.
</p>
<Thing />
</div>
`;
33 changes: 33 additions & 0 deletions src/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import render, { shallowRender } from 'preact-render-to-json';

/**
* Remove __self and __source from the list of attributes/properties.
* babel-preset-react adds these for use with the React DevTools
*/
function removeDevAttributes(vnode) {
if (vnode) {
if (vnode.children) {
vnode.children.forEach(n => removeDevAttributes(n));
}
if (vnode.props) {
if (vnode.props.__source) {
delete vnode.props.__source;
}
if (vnode.props.__self) {
delete vnode.props.__self;
}
}
}
return vnode;
}

/**
* Render Preact JSX + Components to an HTML string.
*
* @param {VNode} vnode JSX VNode to render.
* @param {Object} [context={}] Optionally pass an initial context object through the render path.
* @param {Object} [options={}] Rendering options
*/
global.render = (vnode, context) => removeDevAttributes(render(vnode, context));

global.shallowRender = (vnode, context) => removeDevAttributes(shallowRender(vnode, context));
Loading

0 comments on commit 14bc486

Please sign in to comment.