-
Notifications
You must be signed in to change notification settings - Fork 0
Add Component Build Command #3
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
// @remove-on-eject-begin | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
// @remove-on-eject-end | ||
'use strict'; | ||
|
||
// Do this as the first thing so that any code reading it knows the right env. | ||
process.env.BABEL_ENV = 'production'; | ||
process.env.NODE_ENV = 'production'; | ||
|
||
// 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; | ||
}); | ||
|
||
// Ensure environment variables are read. | ||
require('../config/env'); | ||
// @remove-on-eject-begin | ||
// Do the preflight checks (only happens before eject). | ||
const verifyPackageTree = require('./utils/verifyPackageTree'); | ||
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') { | ||
verifyPackageTree(); | ||
} | ||
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup'); | ||
verifyTypeScriptSetup(); | ||
// @remove-on-eject-end | ||
|
||
const path = require('path'); | ||
const chalk = require('react-dev-utils/chalk'); | ||
const fs = require('fs-extra'); | ||
const webpack = require('webpack'); | ||
const configFactory = require('../config/webpack.config'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this part might be slightly tricky, but basically we will need to change the it could be as simple as reassigning some of the properties and values inside the object. |
||
const paths = require('../config/paths'); | ||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); | ||
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); | ||
const printHostingInstructions = require('react-dev-utils/printHostingInstructions'); | ||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); | ||
const printBuildError = require('react-dev-utils/printBuildError'); | ||
|
||
const measureFileSizesBeforeBuild = | ||
FileSizeReporter.measureFileSizesBeforeBuild; | ||
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; | ||
const useYarn = fs.existsSync(paths.yarnLockFile); | ||
|
||
// These sizes are pretty large. We'll warn for bundles exceeding them. | ||
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024; | ||
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; | ||
|
||
const isInteractive = process.stdout.isTTY; | ||
|
||
// Warn and crash if required files are missing | ||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { | ||
process.exit(1); | ||
} | ||
|
||
// Generate configuration | ||
const config = configFactory('production'); | ||
|
||
config.optimization.runtimeChunk = false; | ||
config.optimization.splitChunks = { | ||
cacheGroups: { | ||
default: false, | ||
}, | ||
}; | ||
config.output.filename = 'main.js'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just making a note here we will eventually want to declare external dependencies here. |
||
|
||
// We require that you explicitly set browsers and do not fall back to | ||
// browserslist defaults. | ||
const { checkBrowsers } = require('react-dev-utils/browsersHelper'); | ||
checkBrowsers(paths.appPath, isInteractive) | ||
.then(() => { | ||
// First, read the current file sizes in build directory. | ||
// This lets us display how much they changed later. | ||
return measureFileSizesBeforeBuild(paths.appBuild); | ||
}) | ||
.then(previousFileSizes => { | ||
// Remove all content but keep the directory so that | ||
// if you're in it, you don't end up in Trash | ||
fs.emptyDirSync(paths.appBuild); | ||
// Merge with the public folder | ||
copyPublicFolder(); | ||
// Start the webpack build | ||
return build(previousFileSizes); | ||
}) | ||
.then( | ||
({ stats, previousFileSizes, warnings }) => { | ||
if (warnings.length) { | ||
console.log(chalk.yellow('Compiled with warnings.\n')); | ||
console.log(warnings.join('\n\n')); | ||
console.log( | ||
'\nSearch for the ' + | ||
chalk.underline(chalk.yellow('keywords')) + | ||
' to learn more about each warning.' | ||
); | ||
console.log( | ||
'To ignore, add ' + | ||
chalk.cyan('// eslint-disable-next-line') + | ||
' to the line before.\n' | ||
); | ||
} else { | ||
console.log(chalk.green('Compiled successfully.\n')); | ||
} | ||
|
||
console.log('File sizes after gzip:\n'); | ||
printFileSizesAfterBuild( | ||
stats, | ||
previousFileSizes, | ||
paths.appBuild, | ||
WARN_AFTER_BUNDLE_GZIP_SIZE, | ||
WARN_AFTER_CHUNK_GZIP_SIZE | ||
); | ||
console.log(); | ||
|
||
const appPackage = require(paths.appPackageJson); | ||
const publicUrl = paths.publicUrl; | ||
const publicPath = config.output.publicPath; | ||
const buildFolder = path.relative(process.cwd(), paths.appBuild); | ||
printHostingInstructions( | ||
appPackage, | ||
publicUrl, | ||
publicPath, | ||
buildFolder, | ||
useYarn | ||
); | ||
}, | ||
err => { | ||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; | ||
if (tscCompileOnError) { | ||
console.log( | ||
chalk.yellow( | ||
'Compiled with the following type errors (you may want to check these before deploying your app):\n' | ||
) | ||
); | ||
printBuildError(err); | ||
} else { | ||
console.log(chalk.red('Failed to compile.\n')); | ||
printBuildError(err); | ||
process.exit(1); | ||
} | ||
} | ||
) | ||
.catch(err => { | ||
if (err && err.message) { | ||
console.log(err.message); | ||
} | ||
process.exit(1); | ||
}); | ||
|
||
// Create the production build and print the deployment instructions. | ||
function build(previousFileSizes) { | ||
// We used to support resolving modules according to `NODE_PATH`. | ||
// This now has been deprecated in favor of jsconfig/tsconfig.json | ||
// This lets you use absolute paths in imports inside large monorepos: | ||
if (process.env.NODE_PATH) { | ||
console.log( | ||
chalk.yellow( | ||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.' | ||
) | ||
); | ||
console.log(); | ||
} | ||
|
||
console.log('Creating an optimized production component build...'); | ||
|
||
const compiler = webpack(config); | ||
return new Promise((resolve, reject) => { | ||
compiler.run((err, stats) => { | ||
let messages; | ||
if (err) { | ||
if (!err.message) { | ||
return reject(err); | ||
} | ||
|
||
let errMessage = err.message; | ||
|
||
// Add additional information for postcss errors | ||
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) { | ||
errMessage += | ||
'\nCompileError: Begins at CSS selector ' + | ||
err['postcssNode'].selector; | ||
} | ||
|
||
messages = formatWebpackMessages({ | ||
errors: [errMessage], | ||
warnings: [], | ||
}); | ||
} else { | ||
messages = formatWebpackMessages( | ||
stats.toJson({ | ||
all: false, | ||
warnings: true, | ||
errors: true, | ||
}) | ||
); | ||
} | ||
if (messages.errors.length) { | ||
// Only keep the first error. Others are often indicative | ||
// of the same problem, but confuse the reader with noise. | ||
if (messages.errors.length > 1) { | ||
messages.errors.length = 1; | ||
} | ||
return reject(new Error(messages.errors.join('\n\n'))); | ||
} | ||
if ( | ||
process.env.CI && | ||
(typeof process.env.CI !== 'string' || | ||
process.env.CI.toLowerCase() !== 'false') && | ||
messages.warnings.length | ||
) { | ||
console.log( | ||
chalk.yellow( | ||
'\nTreating warnings as errors because process.env.CI = true.\n' + | ||
'Most CI servers set it automatically.\n' | ||
) | ||
); | ||
return reject(new Error(messages.warnings.join('\n\n'))); | ||
} | ||
|
||
return resolve({ | ||
stats, | ||
previousFileSizes, | ||
warnings: messages.warnings, | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
function copyPublicFolder() { | ||
fs.copySync(paths.appPublic, paths.appBuild, { | ||
dereference: true, | ||
filter: file => file !== paths.appHtml, | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like you're on the right path here. i don't know all the places you have to declare this new
build-component
script exists, but we could probably just grep forbuild
or whatever to find out.