Merge pull request #262 from bvaughn/gatsby-remark-code-repls

Migrate to new Gatbsy plug-in: gatsby-remark-code-repls
This commit is contained in:
Brian Vaughn
2017-11-09 22:38:45 +00:00
committed by GitHub
14 changed files with 50 additions and 184 deletions

View File

@@ -31,4 +31,4 @@ The next few sections will gradually introduce you to using React. We will exami
React is a JavaScript library, and so it assumes you have a basic understanding of the JavaScript language. If you don't feel very confident, we recommend [refreshing your JavaScript knowledge](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) so you can follow along more easily.
We also use some of the ES6 syntax in the examples. We try to use it sparingly because it's still relatively new, but we encourage you to get familiar with [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [template literals](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals), [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), and [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statements. You can use the [Babel REPL](babel-repl://es5-syntax-example) to check what ES6 code compiles to.
We also use some of the ES6 syntax in the examples. We try to use it sparingly because it's still relatively new, but we encourage you to get familiar with [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [template literals](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals), [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), and [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statements. You can use the [Babel REPL](babel://es5-syntax-example) to check what ES6 code compiles to.

View File

@@ -47,7 +47,7 @@ React.createElement(
)
```
If you want to test out how some specific JSX is converted into JavaScript, you can try out [the online Babel compiler](babel-repl://jsx-simple-example).
If you want to test out how some specific JSX is converted into JavaScript, you can try out [the online Babel compiler](babel://jsx-simple-example).
## Specifying The React Element Type

View File

@@ -38,7 +38,7 @@ ReactDOM.render(
);
```
If you're curious to see more examples of how JSX is converted to JavaScript, you can try out [the online Babel compiler](babel-repl://jsx-simple-example).
If you're curious to see more examples of how JSX is converted to JavaScript, you can try out [the online Babel compiler](babel://jsx-simple-example).
The component can either be provided as a string, or as a subclass of `React.Component`, or a plain function for stateless components.

View File

@@ -5,4 +5,4 @@ order: 0
React components implement a `render()` method that takes input data and returns what to display. This example uses an XML-like syntax called JSX. Input data that is passed into the component can be accessed by `render()` via `this.props`.
**JSX is optional and not required to use React.** Try the [Babel REPL](babel-repl://es5-syntax-example) to see the raw JavaScript code produced by the JSX compilation step.
**JSX is optional and not required to use React.** Try the [Babel REPL](babel://es5-syntax-example) to see the raw JavaScript code produced by the JSX compilation step.

View File

@@ -28,7 +28,7 @@ Once you get a little familiar with the game, feel free to close that tab, as we
We'll assume some familiarity with HTML and JavaScript, but you should be able to follow along even if you haven't used them before.
If you need a refresher on JavaScript, we recommend reading [this guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript). Note that we're also using some features from ES6, a recent version of JavaScript. In this tutorial, we're using [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), and [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statements. You can use the [Babel REPL](babel-repl://es5-syntax-example) to check what ES6 code compiles to.
If you need a refresher on JavaScript, we recommend reading [this guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript). Note that we're also using some features from ES6, a recent version of JavaScript. In this tutorial, we're using [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), and [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statements. You can use the [Babel REPL](babel://es5-syntax-example) to check what ES6 code compiles to.
### How to Follow Along
@@ -129,7 +129,7 @@ return React.createElement('div', {className: 'shopping-list'},
);
```
[See full expanded version.](babel-repl://tutorial-expanded-version)
[See full expanded version.](babel://tutorial-expanded-version)
If you're curious, `createElement()` is described in more detail in the [API reference](/docs/react-api.html#createelement), but we won't be using it directly in this tutorial. Instead, we will keep using JSX.

View File

@@ -6,6 +6,8 @@
'use strict';
const {join} = require('path');
module.exports = {
siteMetadata: {
title: 'React: A JavaScript library for building user interfaces',
@@ -57,15 +59,16 @@ module.exports = {
},
'gatsby-remark-autolink-headers',
{
resolve: 'gatsby-remark-codepen-examples',
resolve: 'gatsby-remark-code-repls',
options: {
directory: 'examples',
},
},
{
resolve: 'gatsby-remark-babel-repl-link',
options: {
directory: 'examples',
defaultText: 'Try it on CodePen',
directory: `${__dirname}/examples/`,
externals: [
`//unpkg.com/react/umd/react.development.js`,
`//unpkg.com/react-dom/umd/react-dom.development.js`,
],
redirectTemplate: `${__dirname}/src/templates/codepen-example.js`,
target: '_blank',
},
},
'gatsby-remark-use-jsx',

View File

@@ -167,24 +167,6 @@ exports.createPages = async ({graphql, boundActionCreators}) => {
redirectInBrowser: true,
toPath: newestBlogNode.fields.slug,
});
// Create Codepen redirects.
// These use the Codepen prefill API to JIT-create Pens.
// https://blog.codepen.io/documentation/api/prefill/
const files = await recursiveReaddir('./examples');
files.forEach(file => {
const slug = file.substring(0, file.length - 3); // Trim extension
const code = readFileSync(file, 'utf8');
createPage({
path: slug,
component: resolve('./src/templates/codepen-example.js'),
context: {
code,
slug,
},
});
});
};
// Parse date information out of blog post filename.

View File

@@ -40,6 +40,7 @@
"gatsby-plugin-sharp": "^1.6.2",
"gatsby-plugin-twitter": "^1.0.10",
"gatsby-remark-autolink-headers": "^1.4.4",
"gatsby-remark-code-repls": "^1.0.2",
"gatsby-remark-copy-linked-files": "^1.5.2",
"gatsby-remark-images": "^1.5.11",
"gatsby-remark-prismjs": "^1.2.1",

View File

@@ -1,68 +0,0 @@
const {existsSync, readFileSync} = require('fs');
const LZString = require('lz-string');
const {join} = require('path');
const map = require('unist-util-map');
const PROTOCOL = 'babel-repl://';
// Matches compression used in Babel REPL
// https://github.com/babel/website/blob/master/js/repl/UriUtils.js
const compress = string =>
LZString.compressToBase64(string)
.replace(/\+/g, '-') // Convert '+' to '-'
.replace(/\//g, '_') // Convert '/' to '_'
.replace(/=+$/, ''); // Remove ending '='
module.exports = ({markdownAST}, {directory}) => {
map(markdownAST, (node, index, parent) => {
if (!directory.endsWith('/')) {
directory += '/';
}
if (node.type === 'link' && node.url.startsWith(PROTOCOL)) {
let filePath = node.url.replace(PROTOCOL, directory);
if (!filePath.endsWith('.js')) {
filePath += '.js';
}
filePath = join(__dirname, '../..', filePath);
// Verify that the specified example file exists.
if (!existsSync(filePath)) {
console.error(
`Invalid Babel REPL link specified; no such file "${filePath}"`,
);
process.exit(1);
}
const code = compress(readFileSync(filePath, 'utf8'));
const href = `https://babeljs.io/repl/#?presets=react&code_lz=${code}`;
const text = node.children[0].value;
const anchorOpenNode = {
type: 'html',
value: `<a href="${href}" target="_blank">`,
};
const textNode = {
type: 'text',
value: text,
};
const anchorCloseNode = {
type: 'html',
value: '</a>',
};
parent.children.splice(
index,
1,
anchorOpenNode,
textNode,
anchorCloseNode,
);
}
// No change
return node;
});
};

View File

@@ -1,4 +0,0 @@
{
"name": "gatsby-remark-babel-repl-link",
"version": "0.0.1"
}

View File

@@ -1,64 +0,0 @@
const {existsSync} = require('fs');
const {join} = require('path');
const map = require('unist-util-map');
const CODEPEN_PROTOCOL = 'codepen://';
const DEFAULT_LINK_TEXT = 'Try it on CodePen';
module.exports = ({markdownAST}, {directory}) => {
map(markdownAST, (node, index, parent) => {
if (!directory.startsWith('/')) {
directory = `/${directory}`;
}
if (!directory.endsWith('/')) {
directory = `${directory}/`;
}
// eg convert
// from: [](codepen:introducing-jsx)
// to: <a href="/<directory>/introducing-jsx" target="_blank">Try it on CodePen</a>
// from: [Try the Hello World example on CodePen](codepen:hello-world)
// to: <a href="/<directory>/hello-world" target="_blank">Try the Hello World example on CodePen</a>
if (node.type === 'link' && node.url.startsWith(CODEPEN_PROTOCOL)) {
const href = node.url.replace(CODEPEN_PROTOCOL, directory);
const text =
node.children.length === 0 ? DEFAULT_LINK_TEXT : node.children[0].value;
// Verify that the specified example file exists.
const filePath = join(__dirname, `../../${href}.js`);
if (!existsSync(filePath)) {
console.error(
`Invalid Codepen link specified; no such file "${filePath}"`,
);
process.exit(1);
}
const anchorOpenNode = {
type: 'html',
value: `<a href="${href}" target="_blank">`,
};
const textNode = {
type: 'text',
value: text,
};
const anchorCloseNode = {
type: 'html',
value: '</a>',
};
parent.children.splice(
index,
1,
anchorOpenNode,
textNode,
anchorCloseNode,
);
}
// No change
return node;
});
};

View File

@@ -1,4 +0,0 @@
{
"name": "gatsby-remark-codepen-examples",
"version": "0.0.1"
}

View File

@@ -34,17 +34,7 @@ class CodepenExample extends Component {
}
render() {
// Codepen configuration.
// https://blog.codepen.io/documentation/api/prefill/
const payload = JSON.stringify({
editors: '0010',
html: '<div id="root"></div>',
js: this.props.pathContext.code,
js_external: EXTERNALS.join(';'),
js_pre_processor: 'babel',
layout: 'left',
title: 'reactjs.org example',
});
const {action, payload} = this.props.pathContext;
return (
<Container>
@@ -54,7 +44,7 @@ class CodepenExample extends Component {
ref={form => {
this.codepenForm = form;
}}
action="https://codepen.io/pen/define"
action={action}
method="POST">
<input type="hidden" name="data" value={payload} />

View File

@@ -4052,6 +4052,15 @@ gatsby-remark-autolink-headers@^1.4.4:
mdast-util-to-string "^1.0.2"
unist-util-visit "^1.1.1"
gatsby-remark-code-repls@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/gatsby-remark-code-repls/-/gatsby-remark-code-repls-1.0.2.tgz#2a6df584d4c60388aa4c1140d9693c40b3d8d561"
dependencies:
babel-runtime "^6.26.0"
lz-string "^1.4.4"
recursive-readdir-synchronous "^0.0.3"
unist-util-map "^1.0.3"
gatsby-remark-copy-linked-files@^1.5.2:
version "1.5.18"
resolved "https://registry.yarnpkg.com/gatsby-remark-copy-linked-files/-/gatsby-remark-copy-linked-files-1.5.18.tgz#ff7932922fd1b1696695bb174f8ecc743097d9a0"
@@ -6174,6 +6183,10 @@ lpad-align@^1.0.1:
longest "^1.0.0"
meow "^3.3.0"
lru-cache@2:
version "2.7.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
@@ -6485,6 +6498,13 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
minimatch@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd"
dependencies:
lru-cache "2"
sigmund "~1.0.0"
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -8257,6 +8277,12 @@ rechoir@^0.6.2:
dependencies:
resolve "^1.1.6"
recursive-readdir-synchronous@^0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/recursive-readdir-synchronous/-/recursive-readdir-synchronous-0.0.3.tgz#d5e5a096ad56cf9666241c22a30b4f338bb7ed88"
dependencies:
minimatch "0.3.0"
recursive-readdir@2.2.1, recursive-readdir@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99"
@@ -9096,6 +9122,10 @@ sift@^3.2.6:
version "3.3.12"
resolved "https://registry.yarnpkg.com/sift/-/sift-3.3.12.tgz#4f5cdf16af3db32afa04ab25297b0e20ad98294a"
sigmund@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"