tagging dev-only code (@remove-on-publish-begin/end) and pre-eject-only code (@remove-on-eject-begin/end) #257 (#257)

This commit is contained in:
Jiansen HE
2016-09-02 16:34:34 +01:00
committed by Dan Abramov
parent 2d99415fa0
commit 6c8713b7d1
23 changed files with 204 additions and 69 deletions

View File

@@ -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');

View File

@@ -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');

View File

@@ -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.

View File

@@ -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.

View File

@@ -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 = {};

View File

@@ -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";

View File

@@ -1,3 +1,4 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
@@ -5,6 +6,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
const babelDev = require('../babel.dev');
const babelJest = require('babel-jest');

View File

@@ -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())
);
// Are we developing create-react-app locally?
var isInCreateReactAppSource = (
process.argv.some(arg => arg.indexOf('--debug-template') > -1)
);
function resolveOwn(relativePath) {
return path.resolve(__dirname, relativePath);
}
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')
};
// 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
// @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

View File

@@ -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,

View File

@@ -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');

View File

@@ -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');

View File

@@ -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) {

View File

@@ -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 --env=jsdom"

View File

@@ -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';

View File

@@ -73,10 +73,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);
});

View File

@@ -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';

View File

@@ -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.
// Were not sure why this isn't Webpack's default behavior.

View File

@@ -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

View File

@@ -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 = {

View File

@@ -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
tasks/clean_pack.sh Executable file
View File

@@ -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

View File

@@ -17,16 +17,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
}
@@ -39,7 +40,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 ..
@@ -52,7 +53,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 ./

View File

@@ -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