diff --git a/package.json b/package.json index 4b42bb5ebdf26..d8d77c57ee4a6 100644 --- a/package.json +++ b/package.json @@ -83,13 +83,12 @@ "rollup-plugin-commonjs": "^8.2.6", "rollup-plugin-inject": "^2.0.0", "rollup-plugin-node-resolve": "^2.0.0", + "rollup-plugin-prettier": "^0.3.0", "rollup-plugin-replace": "^1.1.1", - "rollup-plugin-uglify": "^1.0.1", "run-sequence": "^1.1.4", "through2": "^2.0.0", "tmp": "~0.0.28", "typescript": "~1.8.10", - "uglify-js": "^2.5.0", "yargs": "^6.3.0" }, "devEngines": { diff --git a/scripts/rollup/build.js b/scripts/rollup/build.js index e1756d717b165..e5f5328a1b34b 100644 --- a/scripts/rollup/build.js +++ b/scripts/rollup/build.js @@ -2,9 +2,10 @@ const rollup = require('rollup').rollup; const babel = require('rollup-plugin-babel'); +const closure = require('rollup-plugin-closure-compiler-js'); const commonjs = require('rollup-plugin-commonjs'); const alias = require('rollup-plugin-alias'); -const uglify = require('rollup-plugin-uglify'); +const prettier = require('rollup-plugin-prettier'); const replace = require('rollup-plugin-replace'); const chalk = require('chalk'); const join = require('path').join; @@ -24,7 +25,6 @@ const syncReactNativeRT = require('./sync').syncReactNativeRT; const syncReactNativeCS = require('./sync').syncReactNativeCS; 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; @@ -51,31 +51,16 @@ const errorCodeOpts = { errorMapFilePath: 'scripts/error-codes/codes.json', }; -function getHeaderSanityCheck(bundleType, globalName) { - switch (bundleType) { - case FB_DEV: - case FB_PROD: - case RN_DEV: - case RN_PROD: - let hasteFinalName = globalName; - 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; - } -} +const closureOptions = { + compilationLevel: 'SIMPLE', + languageIn: 'ECMASCRIPT5_STRICT', + languageOut: 'ECMASCRIPT5_STRICT', + env: 'CUSTOM', + warningLevel: 'QUIET', + applyInputSourceMaps: false, + useTypesForOptimization: false, + processCommonJsModules: false, +}; function getBanner(bundleType, globalName, filename, moduleType) { if (moduleType === RECONCILER) { @@ -261,7 +246,6 @@ function getRollupOutputOptions( return Object.assign( {}, { - banner: getBanner(bundleType, globalName, filename, moduleType), destDir: 'build/', file: 'build/' + @@ -270,7 +254,6 @@ function getRollupOutputOptions( filename, globalName ), - footer: getFooter(bundleType, filename, moduleType), format, globals, interop: false, @@ -323,55 +306,6 @@ function getFilename(name, globalName, bundleType) { } } -function getUglifyConfig(configs) { - var mangle = configs.mangle; - 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 <script> that we don't want to evaluate - // for FB prod bundles (where we disable mangling) - evaluate: mangle, - booleans: true, - // Our www inline transform combined with Jest resetModules is confused - // in some rare cases unless we keep all requires at the top: - hoist_funs: mangle, - }, - output: { - beautify: !mangle, - comments(node, comment) { - if (preserveVersionHeader && comment.pos === 0 && comment.col === 0) { - // Keep the very first comment (the bundle header) in prod bundles. - if ( - headerSanityCheck && - comment.value.indexOf(headerSanityCheck) === -1 - ) { - // Sanity check: this doesn't look like the bundle header! - throw new Error( - 'Expected the first comment to be the file header but got: ' + - comment.value - ); - } - return true; - } - return !removeComments; - }, - }, - mangle: mangle - ? { - toplevel: true, - screw_ie8: true, - } - : false, - }; -} - // FB uses require('React') instead of require('react'). // We can't set up a forwarding module due to case sensitivity issues. function rewriteFBReactImport() { @@ -405,6 +339,19 @@ function writeErrorCodes() { }; } +// Add custom intro and outro. This is intentionally a custom plugin +// rather than expressed via Rollup output options because we want them +// to be applied *after* the build. +function wrapBundle(bundleType, globalName, filename, moduleType) { + return { + transformBundle(source) { + const banner = getBanner(bundleType, globalName, filename, moduleType); + const footer = getFooter(bundleType, filename, moduleType); + return banner + '\n' + source + '\n' + footer; + }, + }; +} + function getPlugins( entry, externals, @@ -431,7 +378,6 @@ function getPlugins( stripUseStrict(), ].filter(Boolean); - const headerSanityCheck = getHeaderSanityCheck(bundleType, globalName); switch (bundleType) { case UMD_DEV: case NODE_DEV: @@ -442,43 +388,40 @@ function getPlugins( plugins.push( replace(stripEnvVariables(true)), commonjs(), - closure({ - compilationLevel: 'SIMPLE', - languageIn: 'ECMASCRIPT5_STRICT', - languageOut: 'ECMASCRIPT5_STRICT', - env: 'CUSTOM', - warningLevel: 'QUIET', - // Don't let it create global variables in the browser. - // https://github.com/facebook/react/issues/10909 - assumeFunctionWrapper: bundleType !== UMD_PROD, - applyInputSourceMaps: false, - useTypesForOptimization: false, - processCommonJsModules: false, - }) + closure( + Object.assign({}, closureOptions, { + // Don't let it create global variables in the browser. + // https://github.com/facebook/react/issues/10909 + assumeFunctionWrapper: bundleType !== UMD_PROD, + }) + ) ); break; case FB_DEV: plugins.push( replace(stripEnvVariables(false)), commonjs(), - rewriteFBReactImport() + rewriteFBReactImport(), + prettier() ); break; case FB_PROD: plugins.push( replace(stripEnvVariables(true)), commonjs(), - uglify( - getUglifyConfig({ - mangle: bundleType !== FB_PROD, - preserveVersionHeader: bundleType === UMD_PROD, - // leave comments in for source map debugging purposes - // they will be stripped as part of FB's build process - removeComments: bundleType !== FB_PROD, - headerSanityCheck, + closure( + Object.assign({}, closureOptions, { + assumeFunctionWrapper: true, + // Disable renaming so we have readable FB bundles. + // Works because `google-closure-compiler-js` is forked in the Yarn lockfile. + // We can remove this if GCC merges my PR: + // https://github.com/google/closure-compiler/pull/2707 + // and then the compiled version is released via `google-closure-compiler-js`. + renaming: false, }) ), - rewriteFBReactImport() + rewriteFBReactImport(), + prettier() ); break; case RN_DEV: @@ -486,17 +429,24 @@ function getPlugins( plugins.push( replace(stripEnvVariables(bundleType === RN_PROD)), commonjs(), - uglify( - getUglifyConfig({ - mangle: false, - preserveVersionHeader: true, - removeComments: true, - headerSanityCheck, + closure( + Object.assign({}, closureOptions, { + assumeFunctionWrapper: true, + // <hack> + // Disable renaming so we have readable FB bundles. + // Works because `google-closure-compiler-js` is forked in the Yarn lockfile. + // We can remove this if GCC merges my PR: + // https://github.com/google/closure-compiler/pull/2707 + // and then the compiled version is released via `google-closure-compiler-js`. + renaming: false, + // </hack> }) - ) + ), + prettier() ); break; } + plugins.push(wrapBundle(bundleType, globalName, filename, moduleType)); plugins.push( sizes({ getSize: (size, gzip) => { diff --git a/yarn.lock b/yarn.lock index 8b42751657a85..af68ffad9dc7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1437,7 +1437,7 @@ detective@^4.3.1: acorn "^4.0.3" defined "^1.0.0" -diff@^3.2.0: +diff@3.3.0, diff@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" @@ -2150,8 +2150,8 @@ glogg@^1.0.0: sparkles "^1.0.0" google-closure-compiler-js@>20170000: - version "20170626.0.0" - resolved "https://registry.yarnpkg.com/google-closure-compiler-js/-/google-closure-compiler-js-20170626.0.0.tgz#5df265b277d1ec6fdea12eed131d1491cd8a8d71" + version "20170910.0.1" + resolved "https://registry.yarnpkg.com/@gaearon/google-closure-compiler-js/-/google-closure-compiler-js-20170910.0.1.tgz#b0cf7ef408219a19c390375a76bf0a82ccf65eea" dependencies: minimist "^1.2.0" vinyl "^2.0.1" @@ -3208,6 +3208,12 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +magic-string@0.22.4, magic-string@^0.22.4: + version "0.22.4" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff" + dependencies: + vlq "^0.2.1" + magic-string@^0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.15.2.tgz#0681d7388741bbc3addaa65060992624c6c09e9c" @@ -3220,12 +3226,6 @@ magic-string@^0.16.0: dependencies: vlq "^0.2.1" -magic-string@^0.22.4: - version "0.22.4" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff" - dependencies: - vlq "^0.2.1" - makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -3671,7 +3671,7 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.8.1: +prettier@1.8.1, prettier@^1.0.0: version "1.8.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.1.tgz#91064d778c08c85ac1cbe6b23195c34310d039f9" @@ -4104,6 +4104,14 @@ rollup-plugin-node-resolve@^2.0.0: builtin-modules "^1.1.0" resolve "^1.1.6" +rollup-plugin-prettier@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-prettier/-/rollup-plugin-prettier-0.3.0.tgz#1000df8a2914d367b79507c1caa582fdbed8b0f3" + dependencies: + diff "3.3.0" + magic-string "0.22.4" + prettier "^1.0.0" + rollup-plugin-replace@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/rollup-plugin-replace/-/rollup-plugin-replace-1.1.1.tgz#396315ded050a6ce43b9518a886a3f60efb1ea33" @@ -4112,12 +4120,6 @@ rollup-plugin-replace@^1.1.1: minimatch "^3.0.2" rollup-pluginutils "^1.5.0" -rollup-plugin-uglify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-uglify/-/rollup-plugin-uglify-1.0.2.tgz#d4aa6f5df13522eae1ba17780c7c4c7096038359" - dependencies: - uglify-js "^2.6.1" - rollup-pluginutils@^1.2.0, rollup-pluginutils@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" @@ -4600,7 +4602,7 @@ ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" -uglify-js@^2.5.0, uglify-js@^2.6, uglify-js@^2.6.1: +uglify-js@^2.6: version "2.8.22" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0" dependencies: