'use strict'; const rollup = require('rollup').rollup; const babel = require('rollup-plugin-babel'); const commonjs = require('rollup-plugin-commonjs'); const alias = require('rollup-plugin-alias'); const uglify = require('rollup-plugin-uglify'); const replace = require('rollup-plugin-replace'); const chalk = require('chalk'); const escapeStringRegexp = require('escape-string-regexp'); const join = require('path').join; const resolve = require('path').resolve; const fs = require('fs'); const rimraf = require('rimraf'); const argv = require('minimist')(process.argv.slice(2)); const Modules = require('./modules'); const Bundles = require('./bundles'); const propertyMangleWhitelist = require('./mangle').propertyMangleWhitelist; const sizes = require('./plugins/sizes-plugin'); const Stats = require('./stats'); const syncReactDom = require('./sync').syncReactDom; const syncReactNative = require('./sync').syncReactNative; const Packaging = require('./packaging'); const Header = require('./header'); const closure = require('rollup-plugin-closure-compiler-js'); const UMD_DEV = Bundles.bundleTypes.UMD_DEV; const UMD_PROD = Bundles.bundleTypes.UMD_PROD; const NODE_DEV = Bundles.bundleTypes.NODE_DEV; const NODE_PROD = Bundles.bundleTypes.NODE_PROD; const FB_DEV = Bundles.bundleTypes.FB_DEV; const FB_PROD = Bundles.bundleTypes.FB_PROD; const RN_DEV = Bundles.bundleTypes.RN_DEV; const RN_PROD = Bundles.bundleTypes.RN_PROD; const reactVersion = require('../../package.json').version; const requestedBundleTypes = (argv.type || '') .split(',') .map(type => type.toUpperCase()); const requestedBundleNames = (argv._[0] || '') .split(',') .map(type => type.toLowerCase()); const syncFbsource = argv['sync-fbsource']; const syncWww = argv['sync-www']; // used for when we property mangle with uglify/gcc const mangleRegex = new RegExp( `^(?${propertyMangleWhitelist .map(prop => `!${escapeStringRegexp(prop)}`) .join('|')}$).*$`, 'g' ); function getHeaderSanityCheck(bundleType, hasteName) { switch (bundleType) { case FB_DEV: case FB_PROD: case RN_DEV: case RN_PROD: let hasteFinalName = hasteName; switch (bundleType) { case FB_DEV: case RN_DEV: hasteFinalName += '-dev'; break; case FB_PROD: case RN_PROD: hasteFinalName += '-prod'; break; } return hasteFinalName; case UMD_DEV: case UMD_PROD: return reactVersion; default: return null; } } function getBanner(bundleType, hasteName, filename) { switch (bundleType) { // UMDs are not wrapped in conditions. case UMD_DEV: case UMD_PROD: return Header.getHeader(filename, reactVersion); // CommonJS DEV bundle is guarded to help weak dead code elimination. case NODE_DEV: let banner = Header.getHeader(filename, reactVersion); // Wrap the contents of the if-DEV check with an IIFE. // Block-level function definitions can cause problems for strict mode. banner += `'use strict';\n\n\nif (process.env.NODE_ENV !== "production") {\n(function() {\n`; return banner; case NODE_PROD: return Header.getHeader(filename, reactVersion); // All FB and RN bundles need Haste headers. // DEV bundle is guarded to help weak dead code elimination. case FB_DEV: case FB_PROD: case RN_DEV: case RN_PROD: const isDev = bundleType === FB_DEV || bundleType === RN_DEV; const hasteFinalName = hasteName + (isDev ? '-dev' : '-prod'); // Wrap the contents of the if-DEV check with an IIFE. // Block-level function definitions can cause problems for strict mode. return ( Header.getProvidesHeader(hasteFinalName) + (isDev ? `\n\n'use strict';\n\n\nif (__DEV__) {\n(function() {\n` : '') ); default: throw new Error('Unknown type.'); } } function getFooter(bundleType) { // Only need a footer if getBanner() has an opening brace. switch (bundleType) { // Non-UMD DEV bundles need conditions to help weak dead code elimination. case NODE_DEV: case FB_DEV: case RN_DEV: return '\n})();\n}\n'; default: return ''; } } function updateBabelConfig(babelOpts, bundleType) { switch (bundleType) { case FB_DEV: case FB_PROD: case RN_DEV: case RN_PROD: return Object.assign({}, babelOpts, { plugins: babelOpts.plugins.concat([ // Wrap warning() calls in a __DEV__ check so they are stripped from production. require('./plugins/wrap-warning-with-env-check'), ]), }); case UMD_DEV: case UMD_PROD: case NODE_DEV: case NODE_PROD: return Object.assign({}, babelOpts, { plugins: babelOpts.plugins.concat([ // Use object-assign polyfill in open source resolve('./scripts/babel/transform-object-assign-require'), // Minify invariant messages require('../error-codes/replace-invariant-error-codes'), // Wrap warning() calls in a __DEV__ check so they are stripped from production. require('./plugins/wrap-warning-with-env-check'), ]), }); default: return babelOpts; } } function handleRollupWarnings(warning) { if (warning.code === 'UNRESOLVED_IMPORT') { console.error(warning.message); process.exit(1); } console.warn(warning.message || warning); } function updateBundleConfig(config, filename, format, bundleType, hasteName) { return Object.assign({}, config, { banner: getBanner(bundleType, hasteName, filename), dest: Packaging.getPackageDestination(config, bundleType, filename), footer: getFooter(bundleType), format, interop: false, }); } function stripEnvVariables(production) { return { __DEV__: production ? 'false' : 'true', 'process.env.NODE_ENV': production ? "'production'" : "'development'", }; } function getFormat(bundleType) { switch (bundleType) { case UMD_DEV: case UMD_PROD: return `umd`; case NODE_DEV: case NODE_PROD: case FB_DEV: case FB_PROD: case RN_DEV: case RN_PROD: return `cjs`; } } function getFilename(name, hasteName, bundleType) { // we do this to replace / to -, for react-dom/server name = name.replace('/', '-'); switch (bundleType) { case UMD_DEV: return `${name}.development.js`; case UMD_PROD: return `${name}.production.min.js`; case NODE_DEV: return `${name}.development.js`; case NODE_PROD: return `${name}.production.min.js`; case FB_DEV: case RN_DEV: return `${hasteName}-dev.js`; case FB_PROD: case RN_PROD: return `${hasteName}-prod.js`; } } function uglifyConfig(configs) { var mangle = configs.mangle; var manglePropertiesOnProd = configs.manglePropertiesOnProd; var preserveVersionHeader = configs.preserveVersionHeader; var removeComments = configs.removeComments; var headerSanityCheck = configs.headerSanityCheck; return { warnings: false, compress: { screw_ie8: true, dead_code: true, unused: true, drop_debugger: true, // we have a string literal