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 ``` 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 ``` ## 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 ================================================ ================================================ 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';