Skip to content

Clean publish and eject #257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 2, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/babel.dev.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

module.exports = {
// Don't try to find .babelrc because we want to force this configuration.
2 changes: 2 additions & 0 deletions config/babel.prod.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

module.exports = {
// Don't try to find .babelrc because we want to force this configuration.
2 changes: 2 additions & 0 deletions config/env.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
2 changes: 2 additions & 0 deletions config/eslint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

// Inspired by https://github.com/airbnb/javascript but less opinionated.

2 changes: 2 additions & 0 deletions config/jest/CSSStub.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
@@ -7,5 +8,6 @@
*
* @flow
*/
// @remove-on-eject-end

module.exports = {};
2 changes: 2 additions & 0 deletions config/jest/FileStub.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
@@ -7,5 +8,6 @@
*
* @flow
*/
// @remove-on-eject-end

module.exports = "test-file-stub";
2 changes: 2 additions & 0 deletions config/jest/transform.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

const babelDev = require('../babel.dev');
const babelJest = require('babel-jest');
84 changes: 36 additions & 48 deletions config/paths.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,60 +7,47 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

// TODO: we can split this file into several files (pre-eject, post-eject, test)
// and use those instead. This way we don't need to branch here.
// @remove-on-eject-end

var path = require('path');

// True after ejecting, false when used as a dependency
var isEjected = (
path.resolve(path.join(__dirname, '..')) ===
path.resolve(process.cwd())
);
function resolveApp(relativePath) {
return path.resolve(relativePath);
}

// Are we developing create-react-app locally?
var isInCreateReactAppSource = (
process.argv.some(arg => arg.indexOf('--debug-template') > -1)
);
// config after eject: we're in ./config/
module.exports = {
appBuild: resolveApp('build'),
appHtml: resolveApp('index.html'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appNodeModules: resolveApp('node_modules'),
ownNodeModules: resolveApp('node_modules')
};

// @remove-on-eject-begin
function resolveOwn(relativePath) {
return path.resolve(__dirname, relativePath);
}
// config before eject: we're in ./node_modules/react-scripts/config/
module.exports = {
appBuild: resolveApp('build'),
appHtml: resolveApp('index.html'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appNodeModules: resolveApp('node_modules'),
// this is empty with npm3 but node resolution searches higher anyway:
ownNodeModules: resolveOwn('../node_modules')
};
// @remove-on-eject-end

function resolveApp(relativePath) {
return path.resolve(relativePath);
}

if (isInCreateReactAppSource) {
// create-react-app development: we're in ./config/
module.exports = {
appBuild: resolveOwn('../build'),
appHtml: resolveOwn('../template/index.html'),
appPackageJson: resolveOwn('../package.json'),
appSrc: resolveOwn('../template/src'),
appNodeModules: resolveOwn('../node_modules'),
ownNodeModules: resolveOwn('../node_modules')
};
} else if (!isEjected) {
// before eject: we're in ./node_modules/react-scripts/config/
module.exports = {
appBuild: resolveApp('build'),
appHtml: resolveApp('index.html'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appNodeModules: resolveApp('node_modules'),
// this is empty with npm3 but node resolution searches higher anyway:
ownNodeModules: resolveOwn('../node_modules')
};
} else {
// after eject: we're in ./config/
module.exports = {
appBuild: resolveApp('build'),
appHtml: resolveApp('index.html'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appNodeModules: resolveApp('node_modules'),
ownNodeModules: resolveApp('node_modules')
};
}
// @remove-on-publish-begin
module.exports = {
appBuild: resolveOwn('../build'),
appHtml: resolveOwn('../template/index.html'),
appPackageJson: resolveOwn('../package.json'),
appSrc: resolveOwn('../template/src'),
appNodeModules: resolveOwn('../node_modules'),
ownNodeModules: resolveOwn('../node_modules')
};
// @remove-on-publish-end
11 changes: 11 additions & 0 deletions config/polyfills.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

if (typeof Promise === 'undefined') {
// Rejection tracking prevents a common issue where React gets into an
// inconsistent state due to an error, but it gets swallowed by a Promise,
2 changes: 2 additions & 0 deletions config/webpack.config.dev.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

var path = require('path');
var autoprefixer = require('autoprefixer');
2 changes: 2 additions & 0 deletions config/webpack.config.prod.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

var path = require('path');
var autoprefixer = require('autoprefixer');
2 changes: 1 addition & 1 deletion global-cli/index.js
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ var pathExists = require('path-exists');
* Example of valid values:
* - a specific npm version: "0.22.0-rc1"
* - a .tgz archive from any npm repo: "https://registry.npmjs.org/react-scripts/-/react-scripts-0.20.0.tgz"
* - a package prepared with `npm pack`: "/Users/home/vjeux/create-react-app/react-scripts-0.22.0.tgz"
* - a package prepared with `tasks/clean_pack.sh`: "/Users/home/vjeux/create-react-app/react-scripts-0.22.0.tgz"
*/
var commands = argv._;
if (commands.length === 0) {
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
},
"scripts": {
"build": "node scripts/build.js --debug-template",
"create-react-app": "node global-cli/index.js --scripts-version \"$PWD/`npm pack`\"",
"create-react-app": "node global-cli/index.js --scripts-version \"$PWD/`tasks/clean_pack.sh`\"",
"e2e": "tasks/e2e.sh",
"start": "node scripts/start.js --debug-template",
"test": "node scripts/test.js --debug-template"
2 changes: 2 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

// Do this as the first thing so that any code reading it knows the right env.
process.env.NODE_ENV = 'production';
8 changes: 4 additions & 4 deletions scripts/eject.js
Original file line number Diff line number Diff line change
@@ -74,10 +74,10 @@ prompt(
console.log('Copying ' + file + ' to ' + appPath);
var content = fs
.readFileSync(path.join(ownPath, file), 'utf8')
// Remove license header from JS
.replace(/^\/\*\*(\*(?!\/)|[^*])*\*\//, '')
// Remove license header from AppleScript
.replace(/^--.*\n/gm, '')
// Remove dead code from .js files on eject
.replace(/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg, '')
// Remove dead code from .applescript files on eject
.replace(/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg, '')
.trim() + '\n';
fs.writeFileSync(path.join(appPath, file), content);
});
2 changes: 2 additions & 0 deletions scripts/start.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

process.env.NODE_ENV = 'development';

2 changes: 2 additions & 0 deletions scripts/utils/WatchMissingNodeModulesPlugin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

// This Webpack plugin ensures `npm install <library>` forces a project rebuild.
// We’re not sure why this isn't Webpack's default behavior.
15 changes: 10 additions & 5 deletions scripts/utils/chrome.applescript
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
-- Copyright (c) 2015-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- @remove-on-eject-begin
(*
Copyright (c) 2015-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
of patent rights can be found in the PATENTS file in the same directory.
*)
-- @remove-on-eject-end

on run argv
set theURL to item 1 of argv

2 changes: 2 additions & 0 deletions scripts/utils/createJestConfig.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

module.exports = (resolve, rootDir) => {
const config = {
2 changes: 2 additions & 0 deletions scripts/utils/prompt.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,6 +7,7 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end

var rl = require('readline');

78 changes: 78 additions & 0 deletions tasks/clean_pack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

# In success case, the only output to stdout is the packagename,
# which might be used by the caller of `tasks/clean_pack.sh`

# Start even if run from root directory
cd "$(dirname "$0")"

# print error messages to stderr
# the cleanup function is optionally defined in caller script
function handle_error {
echo "$(basename $0): \033[31mERROR!\033[m An error was encountered executing \033[36mline $1\033[m." 1>&2;
cleanup
echo 'Exiting with error.' 1>&2;
exit 1
}

function handle_exit {
cleanup
echo 'Exiting without error.' 1>&2;
exit
}

function cleanup {
cd $initial_path
# remove Jest snap test file from local dev project if exists
rm ../template/src/__tests__/__snapshots__/App-test.js.snap
rm -rf ../$clean_path
}

# Exit the script with a helpful error message when any error is encountered
trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR

# Cleanup before exit on any termination signal
trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP

# `tasks/clean_pack.sh` the two directories to make sure they are valid npm modules
initial_path=$PWD

# Go to root
cd ..
# create a temporary clean folder that contains production only code
# do not overwrite any files in the current folder
clean_path=`mktemp -d clean_XXXX`

# copy files to folder .clean-pack
# `npm publish` looks package.json, if it has a files field, only pack listed files
# follwoing folders, although not listed in the files field, are not copied
# - .git : contains lot of small files
# - $clean_path : the destination folder
# - node_modules : contains lots of small files
# - build : .gitignored folder used in local development
rsync -av --exclude='.git' --exclude=$clean_path\
--exclude='node_modules' --exclude='build'\
'./' $clean_path >/dev/null

cd $clean_path

# remove dev-only code
files="$(find -L . -name "*.js" -type f)"
for file in $files; do
sed -i.bak '/\/\/ @remove-on-publish-begin/,/\/\/ @remove-on-publish-end/d' $file
rm $file.bak
done

# Pack!
packname=`npm pack`

# copy package to current folder
cd ..
cp -f $clean_path/$packname ./
cleanup
echo $packname
11 changes: 6 additions & 5 deletions tasks/e2e.sh
Original file line number Diff line number Diff line change
@@ -16,16 +16,17 @@ function cleanup {
rm -rf $temp_cli_path $temp_app_path
}

# error messages are redirected to stderr
function handle_error {
echo "$(basename $0): \033[31mERROR!\033[m An error was encountered executing \033[36mline $1\033[m."
echo "$(basename $0): \033[31mERROR!\033[m An error was encountered executing \033[36mline $1\033[m." 1>&2;
cleanup
echo 'Exiting with error.'
echo 'Exiting with error.' 1>&2;
exit 1
}

function handle_exit {
cleanup
echo 'Exiting without error.'
echo 'Exiting without error.' 1>&2;
exit
}

@@ -38,7 +39,7 @@ trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
# Echo every command being executed
set -x

# npm pack the two directories to make sure they are valid npm modules
# `tasks/clean_pack.sh` the two directories to make sure they are valid npm modules
initial_path=$PWD

cd ..
@@ -51,7 +52,7 @@ perl -i -p0e 's/bundledDependencies.*?]/bundledDependencies": []/s' package.json

# Pack react-scripts
npm install
scripts_path=$PWD/`npm pack`
scripts_path=$PWD/`tasks/clean_pack.sh`

# lint
./node_modules/.bin/eslint --ignore-path .gitignore ./
32 changes: 28 additions & 4 deletions tasks/release.sh
Original file line number Diff line number Diff line change
@@ -31,6 +31,30 @@ if [ -n "$(git status --porcelain)" ]; then
exit 1;
fi

# create a temporary clean folder that contains production only code
# do not overwrite any files in the current folder
clean_path=`mktemp -d clean_XXXX`

# copy files to folder .clean-pack
# `npm publish` looks package.json, if it has a files field, only pack listed files
# follwoing folders, although not listed in the files field, are not copied
# - .git : contains lot of small files
# - $clean_path : the destination folder
# - node_modules : contains lots of small files
# - build : .gitignored folder used in local development
rsync -av --exclude='.git' --exclude=$clean_path\
--exclude='node_modules' --exclude='build'\
'./' '$clean_path' >/dev/null

cd $clean_path

# remove dev-only code
files="$(find -L . -name "*.js" -type f)"
for file in $files; do
sed -i.bak '/\/\/ @remove-on-publish-begin/,/\/\/ @remove-on-publish-end/d' $file
rm $file.bak
done

# Update deps
rm -rf node_modules
rm -rf ~/.npm
@@ -44,12 +68,12 @@ npm dedupe
# Since it's in optionalDependencies, it will attempt install outside bundle
rm -rf node_modules/fsevents

# This modifies package.json to copy all dependencies to bundledDependencies
# We will revert package.json back after release to avoid doing it every time
# This modifies $clean_path/package.json to copy all dependencies to bundledDependencies
node ./node_modules/.bin/bundle-deps

# Go!
npm publish "$@"

# Discard changes to package.json
git checkout -- .
# cleanup
cd ..
rm -rf $clean_path