Skip to content

Commit b9d6707

Browse files
author
Michal Svrček
committed
configurable-react-scripts
1 parent abec63e commit b9d6707

File tree

16 files changed

+1662
-215
lines changed

16 files changed

+1662
-215
lines changed

README.md

+32-209
Large diffs are not rendered by default.

examples/relay/README.md

+1,356
Large diffs are not rendered by default.

examples/relay/libs/relay.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var path = require('path');
2+
var chalk = require('chalk');
3+
var fs = require('fs')
4+
5+
exports.schemaPath = path.resolve(__dirname, '../graphql-schema.json');
6+
7+
exports.getBabelRelayPlugin = function(){
8+
if(!fs.existsSync(exports.schemaPath)) {
9+
console.log(chalk.red('GraphQL schema not found - have you run "npm run setupRelay"?'))
10+
process.exit("GraphQL schema not found");
11+
}
12+
13+
var schema = require(exports.schemaPath);
14+
var getBabelRelayPlugin = require('babel-relay-plugin');
15+
return getBabelRelayPlugin(schema.data);
16+
}
17+

examples/relay/libs/setupRelay.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const chalk = require('chalk');
2+
const fetch = require('node-fetch');
3+
const graphQlutilities = require('graphql/utilities');
4+
const fs = require('fs');
5+
require('dotenv').config({silent: true});
6+
7+
const relay = require('./relay');
8+
9+
const requireGraphQlConfig = function() {
10+
return new Promise((resolve, reject) => {
11+
if (!process.env.GRAPHQL_ENDPOINT) {
12+
reject(new Error(
13+
chalk.red('Relay requires a url to your graphql server\n') +
14+
'Specifiy this in a ' + chalk.cyan('GRAPHQL_ENDPOINT') + ' environment variable.'
15+
));
16+
} else {
17+
console.log(chalk.green("Relay support - GRAPHQL_ENDPOINT configured successfully"));
18+
resolve();
19+
}
20+
});
21+
}
22+
23+
const loadSchema = function() {
24+
return new Promise((resolve, reject) => {
25+
if (!fs.existsSync(relay.schemaPath)) {
26+
reject(new Error(
27+
chalk.yellow('Relay support - babel-relay-plugin didn\'t find graphql-schema.json\n')
28+
));
29+
} else {
30+
console.log(chalk.green("Relay support - graphql-schema.json find"));
31+
resolve()
32+
}
33+
})
34+
}
35+
36+
var validateSchemaJson = function () {
37+
return new Promise((resolve, reject) => {
38+
var schemaFileContents = fs.readFileSync(relay.schemaPath);
39+
// check that schema.json is valid json
40+
var schemaJSON;
41+
try {
42+
schemaJSON = JSON.parse(schemaFileContents);
43+
} catch (err) {
44+
return reject(new Error(
45+
chalk.red('JSON parsing of the contents of graphql-schema.json failed.\n') +
46+
'Check the contents of ' + relay.schemaPath + '. It does not appear to be valid json\n'
47+
));
48+
}
49+
50+
try {
51+
graphQlutilities.buildClientSchema(schemaJSON.data);
52+
} catch (err) {
53+
reject(new Error(
54+
chalk.red('Could not parse the contents of schema.json into a valid graphql schema that is compatiable with this version of Relay and babel-relay-plugin\n') +
55+
'Upgrading graphql library on your server may be a solution.'
56+
));
57+
}
58+
59+
console.log('Relay support - schema is valid');
60+
resolve();
61+
});
62+
}
63+
64+
// retreive JSON of graaphql schema via introspection for Babel Relay Plugin to use
65+
var fetchRelaySchema = function () {
66+
console.log('Relay support - fetching schema from ' + chalk.cyan(process.env.GRAPHQL_ENDPOINT));
67+
return fetch(process.env.GRAPHQL_ENDPOINT, {
68+
method: 'POST',
69+
headers: {
70+
'Accept': 'application/json',
71+
'Content-Type': 'application/json'
72+
},
73+
body: JSON.stringify({'query': graphQlutilities.introspectionQuery}),
74+
})
75+
.then(res => res.json()).then(schemaJSON => {
76+
// verify that the schemaJSON is valid a graphQL Schema
77+
var graphQLSchema = graphQlutilities.buildClientSchema(schemaJSON.data);
78+
// Save relay compatible schema.json
79+
fs.writeFileSync(relay.schemaPath, JSON.stringify(schemaJSON, null, 2));
80+
81+
// Save user readable schema.graphql
82+
fs.writeFileSync(relay.schemaPath.replace('.json', '.graphql'), graphQlutilities.printSchema(graphQLSchema));
83+
console.log(chalk.green('Relay support - GraphQL schema successfully fetched'));
84+
});
85+
}
86+
87+
requireGraphQlConfig()
88+
.then(loadSchema)
89+
.catch(fetchRelaySchema)
90+
.then(validateSchemaJson)
91+
.then(() => {
92+
console.log(chalk.green('Relay support everything configured successfully!'));
93+
}, function(e){
94+
console.log(e.message);
95+
process.exit("Seomthing went wrong :D");
96+
});

examples/relay/package.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "relay-example",
3+
"version": "0.1.0",
4+
"private": true,
5+
"devDependencies": {
6+
"@svrcekmichal/react-scripts": "^0.5.0-rc.0",
7+
"babel-relay-plugin": "^0.10.0",
8+
"chalk": "^1.1.3",
9+
"dotenv": "^4.0.0",
10+
"enzyme": "^2.7.1",
11+
"graphql": "^0.9.1",
12+
"node-fetch": "^1.6.3",
13+
"react-addons-test-utils": "^15.4.2"
14+
},
15+
"dependencies": {
16+
"react": "^15.4.2",
17+
"react-dom": "^15.4.2",
18+
"react-relay": "^0.10.0",
19+
"react-router": "^3.0.2",
20+
"react-test-renderer": "^15.4.2",
21+
"relay-react-router": "^0.1.0"
22+
},
23+
"scripts": {
24+
"setupRelay": "node libs/setupRelay.js",
25+
"start": "react-scripts start",
26+
"build": "react-scripts build",
27+
"test": "react-scripts test --env=jsdom",
28+
"eject": "react-scripts eject"
29+
}
30+
}

examples/relay/public/favicon.ico

24.3 KB
Binary file not shown.

examples/relay/public/index.html

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
7+
<!--
8+
Notice the use of %PUBLIC_URL% in the tag above.
9+
It will be replaced with the URL of the `public` folder during the build.
10+
Only files inside the `public` folder can be referenced from the HTML.
11+
12+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
13+
work correctly both with client-side routing and a non-root public URL.
14+
Learn how to configure a non-root public URL by running `npm run build`.
15+
-->
16+
<title>React App</title>
17+
</head>
18+
<body>
19+
<div id="root"></div>
20+
<!--
21+
This HTML file is a template.
22+
If you open it directly in the browser, you will see an empty page.
23+
24+
You can add webfonts, meta tags, or analytics to this file.
25+
The build step will place the bundled scripts into the <body> tag.
26+
27+
To begin the development, run `npm start`.
28+
To create a production bundle, use `npm run build`.
29+
-->
30+
</body>
31+
</html>

examples/relay/src/App.css

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.App {
2+
text-align: center;
3+
}
4+
5+
.App-logo {
6+
animation: App-logo-spin infinite 20s linear;
7+
height: 80px;
8+
}
9+
10+
.App-header {
11+
background-color: #222;
12+
height: 150px;
13+
padding: 20px;
14+
color: white;
15+
}
16+
17+
.App-intro {
18+
font-size: large;
19+
}
20+
21+
@keyframes App-logo-spin {
22+
from { transform: rotate(0deg); }
23+
to { transform: rotate(360deg); }
24+
}

examples/relay/src/App.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React, { Component } from 'react';
2+
import logo from './logo.svg';
3+
import './App.css';
4+
5+
class App extends Component {
6+
render() {
7+
return (
8+
<div className="App">
9+
<div className="App-header ">
10+
<img src={logo} className="App-logo" alt="logo" />
11+
<h2>Welcome to Reactt</h2>
12+
</div>
13+
<p className="App-intro">
14+
To get started, edit <code>src/App.js</code> and save to reload.
15+
</p>
16+
</div>
17+
);
18+
}
19+
}
20+
21+
export default App;

examples/relay/src/App.test.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import App from './App';
4+
5+
it('renders without crashing', () => {
6+
const div = document.createElement('div');
7+
ReactDOM.render(<App />, div);
8+
});

examples/relay/src/index.css

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
body {
2+
margin: 0;
3+
padding: 0;
4+
font-family: sans-serif;
5+
}

examples/relay/src/index.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import App from './App';
4+
import './index.css';
5+
6+
ReactDOM.render(
7+
<App />,
8+
document.getElementById('root')
9+
);

examples/relay/src/logo.svg

+7
Loading

examples/relay/webpack.config.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var relayLib = require('./libs/relay');
2+
var fs = require('fs');
3+
4+
module.exports = function(webpackConfig, isDevelopment) {
5+
6+
/**
7+
* Relay setup
8+
*/
9+
10+
const babelRule = findRule(webpackConfig, function(rule){ return rule.loader === 'babel-loader' });
11+
babelRule.options.plugins = babelRule.options.plugins || [];
12+
babelRule.options.plugins.push(relayLib.getBabelRelayPlugin());
13+
babelRule.options.cacheDirectory = true;
14+
babelRule.options.cacheIdentifier = fs.statSync(relayLib.schemaPath).mtime;
15+
16+
return webpackConfig;
17+
}
18+
19+
function findRule(config, callback) {
20+
var index = config.module.rules.findIndex(callback);
21+
if(index === -1) throw Error('Rule now found');
22+
return config.module.rules[index];
23+
}

packages/react-scripts/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "@svrcekmichal/react-scripts",
3-
"version": "0.5.0",
2+
"name": "configurable-react-scripts",
3+
"version": "0.1.0",
44
"description": "Configuration and scripts for Create React App.",
55
"repository": "facebookincubator/create-react-app",
66
"license": "BSD-3-Clause",

packages/react-scripts/scripts/start.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function setupCompiler(host, port, protocol) {
8787
// "done" event fires when Webpack has finished recompiling the bundle.
8888
// Whether or not you have warnings or errors, you will get this event.
8989
compiler.plugin('done', function(stats) {
90-
if (isInteractive) {
90+
if (isInteractive && !isFirstCompile) {
9191
clearConsole();
9292
}
9393

@@ -287,9 +287,6 @@ function runDevServer(host, port, protocol) {
287287
return console.log(err);
288288
}
289289

290-
if (isInteractive) {
291-
clearConsole();
292-
}
293290
console.log(chalk.cyan('Starting the development server...'));
294291
console.log();
295292

0 commit comments

Comments
 (0)