From 107b365f8de1cc64ae1683800a503494be5c28a7 Mon Sep 17 00:00:00 2001 From: PAUTHIER Jonas Date: Sun, 18 Nov 2018 15:52:43 +0100 Subject: [PATCH] feat(react-scripts): handle ejection Fix #13 --- README.md | 6 +++++- bin/cra-build-watch.js | 9 --------- package.json | 2 -- scripts/index.js | 12 ++++++++---- utils/index.js | 24 +++++++++++++++--------- yarn.lock | 4 ++-- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5b0ccfe..739abeb 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ This script is meant as a temporary workaround for `create-react-app` project ba This script is inspired by other work related such as: https://gist.github.com/jasonblanchard/ae0d2e304a647cd847c0b4493c2353d4. +## Ejection + +This tool handles ejected projects but it assumes you did not modify your `webpack.config.dev.js` file, `paths.js` and `env.js` utils. If you did I cannot guarantee that this tool will work. + # Why do I need this? As of now (20/04/2018), `create-react-app` (more precisely `react-scripts`) does not allow development builds to be written to the disk because it uses `webpackDevServer` to serve your build files and folders ([for good reasons](https://github.com/facebook/create-react-app/issues/1070#issuecomment-261812303)). The problem is that in some cases you need to have these files written to the disk i.e: @@ -78,7 +82,7 @@ If those defaults do not work for you, the script accepts some arguments: * `-b|--build-path`: expects either an absolute or relative path. If a relative path is given it will be prefixed by your project root path. * default: `yourProjectRoot/build`. -* `--react-scripts-version`: expects the `react-scripts` version you are using in your project i.e `2.0.3`. If not given it will be implied from your package.json and if it cannot be implied the version `2.0.4` will be the default. +* `--react-scripts-version`: expects the `react-scripts` version you are using in your project i.e `2.0.3`. If not given it will be implied from your package.json and if it cannot be implied the version `2.0.4` will be the default. Consider setting it if you ejected. * `-p|--public-path`: expects a relative URL where `/` is the root. If you serve your files using an external webserver this argument is to match with your web server configuration. More information can be found in [webpack configuration guide](https://webpack.js.org/configuration/output/#output-publicpath). * default: "". * `-v|--verbose`: display webpack build output. diff --git a/bin/cra-build-watch.js b/bin/cra-build-watch.js index 970fb84..e2e41a7 100755 --- a/bin/cra-build-watch.js +++ b/bin/cra-build-watch.js @@ -4,19 +4,10 @@ /* eslint-disable no-process-exit */ const spawn = require('cross-spawn'); -const chalk = require('chalk'); -const resolveCwd = require('resolve-cwd'); // require it here to handle --help before checking prerequisites require('../utils/cliHandler'); -// quick way of checking that react-scripts is installed in the current project -if (!resolveCwd.silent('react-scripts/bin/react-scripts')) { - console.log(); - console.log(chalk`[{redBright.bold ERROR}] react-scripts must be installed in your project`); - process.exit(1); -} - const [, , ...restArgs] = process.argv; const scriptPath = require.resolve('../scripts'); const scriptArgs = [scriptPath, ...restArgs]; diff --git a/package.json b/package.json index 84fb83d..833fd4d 100644 --- a/package.json +++ b/package.json @@ -64,14 +64,12 @@ "travis-deploy-once": "^4.4.1" }, "dependencies": { - "chalk": "2.4.0", "cross-spawn": "6.0.5", "fs-extra": "5.0.0", "html-webpack-plugin": "^3.2.0", "import-cwd": "2.1.0", "meow": "4.0.0", "ora": "2.0.0", - "resolve-cwd": "2.0.0", "semver": "^5.6.0" } } diff --git a/scripts/index.js b/scripts/index.js index 6f1ced9..d6299ce 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -10,13 +10,17 @@ const ora = require('ora'); const { flags: { buildPath, publicPath, reactScriptsVersion, verbose }, } = require('../utils/cliHandler'); -const { getReactScriptsVersion } = require('../utils'); -const paths = importCwd('react-scripts/config/paths'); +const { getReactScriptsVersion, isEjected } = require('../utils'); +const paths = isEjected ? importCwd('./config/paths') : importCwd('react-scripts/config/paths'); const webpack = importCwd('webpack'); -const config = importCwd('react-scripts/config/webpack.config.dev'); +const config = isEjected + ? importCwd('./config/webpack.config.dev') + : importCwd('react-scripts/config/webpack.config.dev'); const HtmlWebpackPlugin = importCwd('html-webpack-plugin'); const InterpolateHtmlPlugin = importCwd('react-dev-utils/InterpolateHtmlPlugin'); -const getClientEnvironment = importCwd('react-scripts/config/env'); +const getClientEnvironment = isEjected + ? importCwd('./config/env') + : importCwd('react-scripts/config/env'); console.log(); const spinner = ora('Update webpack configuration').start(); diff --git a/utils/index.js b/utils/index.js index 23a67cf..9b116d6 100644 --- a/utils/index.js +++ b/utils/index.js @@ -1,24 +1,30 @@ +'use strict'; + const importCwd = require('import-cwd'); const semver = require('semver'); +const fs = require('fs-extra'); +const path = require('path'); const DEFAULT_VERSION = { major: 2, minor: 0, - patch: 4 -} + patch: 4, +}; + +exports.isEjected = fs.pathExistsSync(path.join(process.cwd(), 'config/webpack.config.dev.js')); -exports.getReactScriptsVersion = function(cliVersion) { +exports.getReactScriptsVersion = function getReactScriptsVersion(cliVersion) { if (cliVersion) { const versions = { major: Number(semver.major(cliVersion)), minor: Number(semver.minor(cliVersion)), - patch: Number(semver.patch(cliVersion)) - } + patch: Number(semver.patch(cliVersion)), + }; return versions; } const packageJson = importCwd.silent('./package.json'); - if (!packageJson) { + if (!packageJson || !packageJson.dependencies['react-scripts']) { return DEFAULT_VERSION; } @@ -26,7 +32,7 @@ exports.getReactScriptsVersion = function(cliVersion) { const versions = { major: Number(semver.major(dependencies['react-scripts'])), minor: Number(semver.minor(dependencies['react-scripts'])), - patch: Number(semver.patch(dependencies['react-scripts'])) - } + patch: Number(semver.patch(dependencies['react-scripts'])), + }; return versions; -}; \ No newline at end of file +}; diff --git a/yarn.lock b/yarn.lock index 6994d16..832aa5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1278,7 +1278,7 @@ chalk@2.3.1: escape-string-regexp "^1.0.5" supports-color "^5.2.0" -chalk@2.4.0, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1: version "2.4.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52" integrity sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw== @@ -5528,7 +5528,7 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" -resolve-cwd@2.0.0, resolve-cwd@^2.0.0: +resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=