Last active
September 30, 2019 21:17
-
-
Save agwells/1606d1bc45dddb782ca8d336b6802e90 to your computer and use it in GitHub Desktop.
Executing code written for Create React App, as a CLI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This file is the "Launch" script for running Create React App code at the command | |
* line. It calls "@babel/register", which is a Babel utility that hijacks | |
* the normal node "require()" function and lets Babel pre-compile imported | |
* files into Node-compatible JS before they're executed. | |
* | |
* This bootstraps up the fancy CRA TypeScript/React configuration (using the | |
* Babel config imported from "babel-preset-react-app"). Then it simply "require()"s | |
* some other JS/TS/JSX/TSX file, and executes it. | |
* | |
* To execute: | |
* | |
* > node cracli.js | |
* | |
* NOTE: Another approach would be to rely on CRA's webpack configuration, modified | |
* to include your CLI script(s) as another entry point, and the "node" target. | |
*/ | |
// Ensure environment variables are read. | |
// We need to tell CRA to use the "test" environment so it will make everything | |
// command-line friendly. | |
// @ts-ignore | |
process.env.NODE_ENV = 'test'; | |
process.env.PUBLIC_URL = ''; | |
const defaultResolver = require('babel-plugin-module-resolver').resolvePath; | |
// Makes the script crash on unhandled rejections instead of silently | |
// ignoring them. In the future, promise rejections that are not handled will | |
// terminate the Node.js process with a non-zero exit code. | |
process.on('unhandledRejection', (err) => { | |
throw err; | |
}); | |
const config = { | |
// THIS LINE is the important one. "babel-preset-react-app" is the Babel | |
// configuration that Create React App uses! Importing this, while specifying | |
// that NODE_ENV = "test", automatically gives us the same Babel configuration | |
// that CRA uses when executing Jest tests in the CLI. | |
// | |
// NOTE we still have to tweak a couple of additional things, which CRA | |
// takes care of through Webpack on the browser-side, and through Jest configs | |
// on the CLI. | |
presets: ['babel-preset-react-app'], | |
// Tell Babel which file extensions to try to compile. (Note that it will | |
// by default ignore files imported from node_modules, which is good.) | |
extensions: ['.js', '.jsx', '.ts', '.tsx'], | |
plugins: [ | |
[ | |
'babel-plugin-module-resolver', | |
{ | |
// Simulate our "absolute" import paths, e.g. using | |
// "import 'components/base/button';" instead of | |
// "import '../../../../components/base/button';" | |
// CRA does this by examining our tsconfig.json file and then configuring | |
// Webpack (for browser) or a "--modules" flag (for Jest) | |
root: ['./src/'], | |
extensions: [ | |
// Code files | |
'.js', | |
'.jsx', | |
'.ts', | |
'.tsx', | |
// Files to replace with empty placeholders | |
'.scss', | |
'.css', | |
'.svg', | |
'.png', | |
], | |
// Ignore the CSS/SVG import syntax "import 'button.scss';" | |
// Specifically, the import is still there, but we rewrite it to import | |
// an empty file. | |
resolvePath(sourcePath, currentFile, opts) { | |
if (/\.(scss|css|svg|png)$/.test(sourcePath)) { | |
// NOTE: Need to make an empty file called "emptyfile.js" for this to work. | |
// TODO: Simulate CRA's ability to inline small image files as data URIs. | |
return defaultResolver('emptyfile', currentFile, opts); | |
} else { | |
return defaultResolver(sourcePath, currentFile, opts); | |
} | |
}, | |
}, | |
], | |
], | |
}; | |
// NOTE: Using @babel/register is convenient during development, because it recompiles | |
// things on the fly. But for production you would probably want to compile things | |
// and execute the compiled code. | |
require('@babel/register')(config); | |
require('./SOMEFILE.tsx'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment