Repository: lukejacksonn/es-react
Branch: master
Commit: c450874b4133
Files: 20
Total size: 12.7 KB
Directory structure:
gitextract_83v9dola/
├── .gitignore
├── .npmignore
├── README.md
├── index.d.ts
├── index.html
├── package.json
├── prop-types.d.ts
├── react-dom.d.ts
├── react-is.d.ts
├── react.d.ts
├── scripts/
│ ├── expand-exports-plugin.js
│ ├── replace-object-assign.js
│ ├── rollup.config.js
│ └── write-dev-pkgjson.js
└── src/
├── index.js
├── prop-types.js
├── react-dom-server-browser.js
├── react-dom.js
├── react-is.js
└── react.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
node_modules
/dev
/*.js
================================================
FILE: .npmignore
================================================
/*
!dev/*.js
!dev/package.json
!*.js
!README.md
!package.json
================================================
FILE: README.md
================================================
# es-react
> An ES6 module exposing the latest version of react, react-dom, react-is, and prop-types
Ever wanted to just import react into your project as a module **without** a build step or even script tags? Native browser support for module [imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) is [pretty good](https://caniuse.com/#feat=es6-module) so this should be an option for react developers now! Alas, there has not been an ES6 module compatible build released yet.
This package allows you import `react` and `react-dom` as ES6 modules from a CDN like [`unpkg`](https://unpkg.com):
```html
<script type="module">
import { React, ReactDOM, PropTypes } from 'https://unpkg.com/es-react';
ReactDOM.render(
React.createElement('h1', {}, 'Hello from es-react'),
document.body
);
</script>
```
By default es-react exports the **production build** of react. For the **development build** use the `/dev` subfolder:
```js
import { React, ReactDOM } from 'https://unpkg.com/es-react/dev';
```
You may also import any members of the React package directly:
```js
import React, {
Component,
useState /* ... */,
} from 'https://unpkg.com/es-react';
```
And every package is also being provided as a separate file:
- `es-react/index.js`: Exports all of `React` and exports `{ React, ReactDOM, ReactIs, PropTypes }`
- `es-react/react.js`: Exports all of `React` plus a default export
- `es-react/react-dom.js`: Exports all of `ReactDOM` plus a default export (but not `react-dom/server`)
- `es-react/react-is.js`: Exports all of `ReactIs` plus a default export
- `es-react/prop-types.js`: Exports all of `PropTypes` plus a default export
- `es-react/react-dom-server.js`: Exports all of `ReactDOMServerBrowser` plus a default export
All development-versions of these packages are also available under `es-react/dev/`.
## Features
- All the latest React features (hooks, suspense, lazy, memo etc.)
- Use React directly from any javascript file (no build step required)
- Compatible with [`htm`](https://github.com/developit/htm) (for JSX compilation at runtime)
## Usage
Import `React` and `ReactDOM` directly from any script with `type="module"`. The package is intended to be available from [`unpkg`](https://unpkg.com) (without having to append `?module` to the package name).
```js
import { React, ReactDOM } from 'https://unpkg.com/es-react@16.13.1';
```
It is strongly advised that you specify a version when requesting the module – this speeds up the request time and helps with caching. If you don't specify a number then unpkg will redirect and serve up the latest available version.
## Example
Create a new file, copy the code below into it and then open the file in a browser – or [try online](https://codepen.io/lukejacksonn/pen/EMxVWM).
> If you would like the browser to reload when you update the code, then you can use a dev server like [servor](https://github.com/lukejacksonn/servor) dependency free by running `npx servor --reload --browse`.
```js
<script type="module">
import { React, ReactDOM } from 'https://unpkg.com/es-react@16.13.1';
import htm from 'https://unpkg.com/htm?module'
const html = htm.bind(React.createElement)
const Counter = props => {
const [count, setCount] = React.useState(parseInt(props.count))
return html`
<div>
<h1>${count}</h1>
<button onClick=${e => setCount(count - 1)}>Decrement</button>
<button onClick=${e => setCount(count + 1)}>Increment</button>
</div>
`
}
ReactDOM.render(
html`
<h1>Look Ma! No script tags, no build step</h1>
<${Counter} count=0 />
`,
document.body
)
</script>
```
## Implementation
The latest versions of all packages are installed via (pinned) entries in `package.json` and built and bundled using Rollup with automatic code splitting.
The exports of each package are automatically expanded and `object-assign` is stripped from the output, since all browsers that support ESM will also support `Object.assign`
(See `scripts/expand-exports-plugin.js` and `scripts/replace-object-assign.js` for the Babel plugins that do this)
## Acknowledgements
Barely any of the code in this repo is written by myself. It is just a wrapper for React that is written and maintained by the team at Facebook. Thanks to my employer [Formidable](https://github.com/formidablelabs) for allowing me the time to think about and work on fun and experimental projects like this.
================================================
FILE: index.d.ts
================================================
import * as React from './react';
import * as ReactDOM from './react-dom';
import * as PropTypes from './prop-types';
export { React, ReactDOM, PropTypes };
export * from './react';
export default React;
================================================
FILE: index.html
================================================
<script type="module">
import { React, ReactDOM } from './index.js';
ReactDOM.render(React.createElement('h1', {}, 'Works!'), document.body);
</script>
================================================
FILE: package.json
================================================
{
"name": "es-react",
"version": "16.13.1",
"description": "An ES6 module exposing the latest version of react and react-dom",
"module": "index.js",
"types": "index.d.ts",
"keywords": [
"react",
"es",
"module",
"import",
"export"
],
"repository": "https://www.github.com/lukejacksonn/es-react",
"bugs": {
"url": "https://github.com/lukejacksonn/es-react/issues"
},
"scripts": {
"build": "rollup -c scripts/rollup.config.js",
"clean": "rimraf *.js dev",
"prepare-dev": "node ./scripts/write-dev-pkgjson.js",
"prepublishOnly": "run-s clean build prepare-dev"
},
"author": "@lukejacksonn",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.6.2",
"npm-run-all": "^4.1.5",
"prop-types": "15.7.2",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-is": "16.13.1",
"rimraf": "^3.0.0",
"rollup": "^1.21.4",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0"
},
"dependencies": {
"@types/prop-types": "^15.7.3",
"@types/react": "^16.9.19",
"@types/react-dom": "^16.9.5",
"@types/react-is": "^16.7.1"
}
}
================================================
FILE: prop-types.d.ts
================================================
export * from 'prop-types';
================================================
FILE: react-dom.d.ts
================================================
export * from 'react-dom';
================================================
FILE: react-is.d.ts
================================================
export * from 'react-is';
================================================
FILE: react.d.ts
================================================
export {
Children,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
cloneElement,
createContext,
createElement,
createFactory,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
useCallback,
useContext,
useDebugValue,
useEffect,
useImperativeHandle,
useLayoutEffect,
useMemo,
useReducer,
useRef,
useState,
version
} from 'react';
================================================
FILE: scripts/expand-exports-plugin.js
================================================
const toIdentifierName = str => str.replace(/[^\w]+/g, '');
/** expand-exports-plugin for Babel
* This plugin expands exports for CommonJS modules into granular
* export-default and export-all declarations.
*
* It takes a "map" option that must be an object from
* module names (e.g. 'react') to filenames.
* It then replaces export-all declarations (i.e. "export *") with
* granular exports that export all named keys and a default export.
*/
const expandExportsPlugin = ({ template, types: t }) => ({
visitor: {
ExportAllDeclaration(path, state) {
const { map } = state.opts;
const module = path.node.source.value;
const file = map[module];
// We retrieve the module name and filename from the map
if (typeof file === 'string') {
// We turn the module name to a safe identifier
const importId = t.identifier(toIdentifierName(module));
// We retrieve all exports via CommonJS in Node
const exportKeys = Object.keys(require(file));
// import %importId% from "%file%;
const importNode = t.importDeclaration(
[t.importDefaultSpecifier(importId)],
t.stringLiteral(file)
);
// export default %importId%;
const defaultExportNode = t.exportDefaultDeclaration(importId);
// export const { %exportKeys% } = %importId%;
const exportsNode = t.exportNamedDeclaration(
t.variableDeclaration(
'const',
[t.variableDeclarator(
t.objectPattern(
exportKeys.map(name => {
const identifier = t.identifier(name);
return t.objectProperty(
identifier,
identifier,
false,
true
);
})
),
importId
)]
),
[]
);
// Replace the export-all declaration with new nodes
path.replaceWithMultiple([
importNode,
defaultExportNode,
exportsNode
]);
}
}
}
});
export default expandExportsPlugin;
================================================
FILE: scripts/replace-object-assign.js
================================================
const replaceAssignPlugin = ({ types: t }) => ({
visitor: {
CallExpression(path, state) {
const { callee, arguments: args } = path.node;
if (
t.isIdentifier(callee) &&
callee.name === 'require' &&
t.isStringLiteral(args[0]) &&
args[0].value === 'object-assign'
) {
path.replaceWithSourceString('Object.assign');
}
}
}
});
export default replaceAssignPlugin;
================================================
FILE: scripts/rollup.config.js
================================================
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';
import expandExportsPlugin from './expand-exports-plugin';
import replaceAssignPlugin from './replace-object-assign';
const exportsMap = (isProduction = false) => ({
react: `react/cjs/react.${isProduction ? 'production.min' : 'development'}.js`,
'react-is': `react-is/cjs/react-is.${isProduction ? 'production.min' : 'development'}.js`,
'react-dom': `react-dom/cjs/react-dom.${isProduction ? 'production.min' : 'development'}.js`,
'react-dom-server-browser': `react-dom/cjs/react-dom-server.browser.${isProduction ? 'production.min' : 'development'}.js`,
'prop-types': 'prop-types/index.js',
});
const config = (isProduction = false) => ({
input: {
index: './src/index.js',
react: './src/react.js',
'react-is': './src/react-is.js',
'react-dom': './src/react-dom.js',
'react-dom-server-browser': './src/react-dom-server-browser.js',
'prop-types': './src/prop-types.js'
},
plugins: [
babel({
babelrc: false,
plugins: [
// This expands all our exports
[expandExportsPlugin, {
map: exportsMap(isProduction)
}],
// This replaces object-assign with native Object.assign
replaceAssignPlugin
],
}),
nodeResolve({
mainFields: ['module', 'jsnext', 'main'],
browser: true,
}),
commonjs({
ignoreGlobal: true,
include: /\/node_modules\//,
namedExports: {
react: Object.keys(require('react')),
'react-is': Object.keys(require('react-is')),
'react-dom': Object.keys(require('react-dom')),
'react-dom-server-browser': Object.keys(require('react-dom/server.browser')),
'prop-types': Object.keys(require('prop-types')),
},
}),
replace({
'process.env.NODE_ENV': JSON.stringify(
isProduction ? 'production' : 'development'
)
})
],
onwarn: () => {},
treeshake: {
moduleSideEffects: false,
propertyReadSideEffects: false
}
});
export default [
{
...config(true),
output: {
compact: true,
interop: false,
freeze: false,
dir: './',
entryFileNames: '[name].js',
chunkFileNames: '[name]-[hash].js',
format: 'esm'
}
},
{
...config(false),
output: {
compact: true,
interop: false,
freeze: false,
dir: './dev',
entryFileNames: '[name].js',
chunkFileNames: '[name]-[hash].js',
format: 'esm'
}
}
];
================================================
FILE: scripts/write-dev-pkgjson.js
================================================
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const dir = path.resolve(__dirname, '../dev');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
const pathToPkgJson = path.resolve(dir, 'package.json');
if (fs.existsSync(pathToPkgJson)) {
fs.unlinkSync(pathToPkgJson);
}
const mainPkgJson = require('../package.json');
const contents = JSON.stringify(
{
name: '@es-react/dev',
version: mainPkgJson.version,
license: mainPkgJson.license,
private: true,
module: 'index.js',
},
undefined,
2
);
fs.writeFileSync(pathToPkgJson, contents);
================================================
FILE: src/index.js
================================================
import React from './react';
import ReactDOM from './react-dom';
import ReactDOMServerBrowser from './react-dom';
import PropTypes from './prop-types';
export { React, ReactDOM, ReactDOMServerBrowser, PropTypes };
export * from './react';
export default React;
================================================
FILE: src/prop-types.js
================================================
export * from 'prop-types';
================================================
FILE: src/react-dom-server-browser.js
================================================
export { default } from 'react-dom/server.browser';
================================================
FILE: src/react-dom.js
================================================
export * from 'react-dom';
================================================
FILE: src/react-is.js
================================================
export * from 'react-is';
================================================
FILE: src/react.js
================================================
export * from 'react';
gitextract_83v9dola/
├── .gitignore
├── .npmignore
├── README.md
├── index.d.ts
├── index.html
├── package.json
├── prop-types.d.ts
├── react-dom.d.ts
├── react-is.d.ts
├── react.d.ts
├── scripts/
│ ├── expand-exports-plugin.js
│ ├── replace-object-assign.js
│ ├── rollup.config.js
│ └── write-dev-pkgjson.js
└── src/
├── index.js
├── prop-types.js
├── react-dom-server-browser.js
├── react-dom.js
├── react-is.js
└── react.js
SYMBOL INDEX (2 symbols across 2 files)
FILE: scripts/expand-exports-plugin.js
method ExportAllDeclaration (line 15) | ExportAllDeclaration(path, state) {
FILE: scripts/replace-object-assign.js
method CallExpression (line 3) | CallExpression(path, state) {
Condensed preview — 20 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
{
"path": ".gitignore",
"chars": 24,
"preview": "node_modules\n/dev\n/*.js\n"
},
{
"path": ".npmignore",
"chars": 62,
"preview": "/*\n!dev/*.js\n!dev/package.json\n!*.js\n!README.md\n!package.json\n"
},
{
"path": "README.md",
"chars": 4503,
"preview": "# es-react\n\n> An ES6 module exposing the latest version of react, react-dom, react-is, and prop-types\n\nEver wanted to ju"
},
{
"path": "index.d.ts",
"chars": 205,
"preview": "import * as React from './react';\nimport * as ReactDOM from './react-dom';\nimport * as PropTypes from './prop-types';\n\ne"
},
{
"path": "index.html",
"chars": 156,
"preview": "<script type=\"module\">\n import { React, ReactDOM } from './index.js';\n ReactDOM.render(React.createElement('h1', {}, '"
},
{
"path": "package.json",
"chars": 1237,
"preview": "{\n \"name\": \"es-react\",\n \"version\": \"16.13.1\",\n \"description\": \"An ES6 module exposing the latest version of react and"
},
{
"path": "prop-types.d.ts",
"chars": 28,
"preview": "export * from 'prop-types';\n"
},
{
"path": "react-dom.d.ts",
"chars": 27,
"preview": "export * from 'react-dom';\n"
},
{
"path": "react-is.d.ts",
"chars": 26,
"preview": "export * from 'react-is';\n"
},
{
"path": "react.d.ts",
"chars": 457,
"preview": "export {\n Children,\n Component,\n Fragment,\n Profiler,\n PureComponent,\n StrictMode,\n Suspense,\n c"
},
{
"path": "scripts/expand-exports-plugin.js",
"chars": 2164,
"preview": "\nconst toIdentifierName = str => str.replace(/[^\\w]+/g, '');\n\n/** expand-exports-plugin for Babel\n * This plugin expands"
},
{
"path": "scripts/replace-object-assign.js",
"chars": 436,
"preview": "const replaceAssignPlugin = ({ types: t }) => ({\n visitor: {\n CallExpression(path, state) {\n const { callee, ar"
},
{
"path": "scripts/rollup.config.js",
"chars": 2627,
"preview": "import commonjs from 'rollup-plugin-commonjs';\nimport nodeResolve from 'rollup-plugin-node-resolve';\nimport babel from '"
},
{
"path": "scripts/write-dev-pkgjson.js",
"chars": 597,
"preview": "#!/usr/bin/env node\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst dir = path.resolve(__dirname, '../de"
},
{
"path": "src/index.js",
"chars": 262,
"preview": "import React from './react';\nimport ReactDOM from './react-dom';\nimport ReactDOMServerBrowser from './react-dom';\nimport"
},
{
"path": "src/prop-types.js",
"chars": 28,
"preview": "export * from 'prop-types';\n"
},
{
"path": "src/react-dom-server-browser.js",
"chars": 52,
"preview": "export { default } from 'react-dom/server.browser';\n"
},
{
"path": "src/react-dom.js",
"chars": 27,
"preview": "export * from 'react-dom';\n"
},
{
"path": "src/react-is.js",
"chars": 26,
"preview": "export * from 'react-is';\n"
},
{
"path": "src/react.js",
"chars": 23,
"preview": "export * from 'react';\n"
}
]
About this extraction
This page contains the full source code of the lukejacksonn/es-react GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 20 files (12.7 KB), approximately 3.7k tokens, and a symbol index with 2 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.