From e355de5ed7bd2afedccfb208ffeab732a4f58c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 14 Mar 2019 18:51:26 +0100 Subject: [PATCH] Scripts: use default babel if none is found in project (#14168) --- bin/packages/build.js | 4 +- bin/packages/get-babel-config.js | 96 +++++++++-------------- package.json | 2 +- packages/babel-preset-default/index.js | 74 ++++++++++++----- packages/scripts/config/webpack.config.js | 13 ++- packages/scripts/utils/config.js | 1 + 6 files changed, 104 insertions(+), 86 deletions(-) diff --git a/bin/packages/build.js b/bin/packages/build.js index 8a13f8f10b048d..bb6954b4102e7c 100755 --- a/bin/packages/build.js +++ b/bin/packages/build.js @@ -164,9 +164,7 @@ function buildScssFile( styleFile ) { function buildJsFileFor( file, silent, environment ) { const buildDir = BUILD_DIR[ environment ]; const destPath = getBuildPath( file, buildDir ); - const babelOptions = getBabelConfig( environment ); - babelOptions.sourceMaps = true; - babelOptions.sourceFileName = file.replace( PACKAGES_DIR, '@wordpress' ); + const babelOptions = getBabelConfig( environment, file.replace( PACKAGES_DIR, '@wordpress' ) ); mkdirp.sync( path.dirname( destPath ) ); const transformed = babel.transformFileSync( file, babelOptions ); diff --git a/bin/packages/get-babel-config.js b/bin/packages/get-babel-config.js index b2646da46955c2..d76e171d46b214 100644 --- a/bin/packages/get-babel-config.js +++ b/bin/packages/get-babel-config.js @@ -1,64 +1,38 @@ -/** - * External dependencies - */ -const { get, map } = require( 'lodash' ); -const babel = require( '@babel/core' ); - -/** - * WordPress dependencies - */ -const { options: babelDefaultConfig } = babel.loadPartialConfig( { - configFile: '@wordpress/babel-preset-default', -} ); -const { plugins, presets } = babelDefaultConfig; - -const overrideOptions = ( target, targetName, options ) => { - if ( get( target, [ 'file', 'request' ] ) === targetName ) { - return [ targetName, Object.assign( - {}, - target.options, - options - ) ]; +module.exports = function( environment = '', file ) { + /* + * Specific options to be passed using the caller config option: + * https://babeljs.io/docs/en/options#caller + * + * The caller options can only be 'boolean', 'string', or 'number' by design: + * https://github.com/babel/babel/blob/bd0c62dc0c30cf16a4d4ef0ddf21d386f673815c/packages/babel-core/src/config/validation/option-assertions.js#L122 + */ + const callerOpts = { caller: { + name: `WP_BUILD_${ environment.toUpperCase() }`, + } }; + switch ( environment ) { + case 'main': + // to be merged as a presetEnv option + callerOpts.caller.modules = 'commonjs'; + break; + case 'module': + // to be merged as a presetEnv option + callerOpts.caller.modules = false; + // to be merged as a pluginTransformRuntime option + callerOpts.caller.useESModules = true; + break; + default: + // preventing measure, this shouldn't happen ever + delete callerOpts.caller; } - return target; -}; -const babelConfigs = { - main: Object.assign( - {}, - babelDefaultConfig, - { - plugins, - presets: map( - presets, - ( preset ) => overrideOptions( preset, '@babel/preset-env', { - modules: 'commonjs', - } ) - ), - } - ), - module: Object.assign( - {}, - babelDefaultConfig, - { - plugins: map( - plugins, - ( plugin ) => overrideOptions( plugin, '@babel/plugin-transform-runtime', { - useESModules: true, - } ) - ), - presets: map( - presets, - ( preset ) => overrideOptions( preset, '@babel/preset-env', { - modules: false, - } ) - ), - } - ), -}; - -function getBabelConfig( environment ) { - return babelConfigs[ environment ]; -} + // Sourcemaps options + const sourceMapsOpts = { + sourceMaps: true, + sourceFileName: file, + }; -module.exports = getBabelConfig; + return { + ...callerOpts, + ...sourceMapsOpts, + }; +}; diff --git a/package.json b/package.json index f9ada126e5e1be..71bf946b7694ee 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ }, "scripts": { "prebuild": "npm run check-engines", - "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style", + "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style ./packages/*/node_modules", "prebuild:packages": "npm run clean:packages && lerna run build", "build:packages": "node ./bin/packages/build.js", "build": "npm run build:packages && wp-scripts build", diff --git a/packages/babel-preset-default/index.js b/packages/babel-preset-default/index.js index 8a893ee9c5ea73..5c7f22d98439a8 100644 --- a/packages/babel-preset-default/index.js +++ b/packages/babel-preset-default/index.js @@ -1,36 +1,72 @@ module.exports = function( api ) { + let wpBuildOpts = {}; + const isWPBuild = ( name ) => [ 'WP_BUILD_MAIN', 'WP_BUILD_MODULE' ].some( + ( buildName ) => name === buildName + ); + const isTestEnv = api.env() === 'test'; + api.caller( ( caller ) => { + if ( caller && isWPBuild( caller.name ) ) { + wpBuildOpts = { ...caller }; + return caller.name; + } + return undefined; + } ); + + const getPresetEnv = () => { + const opts = {}; + + if ( isTestEnv ) { + opts.useBuiltIns = 'usage'; + } else { + opts.modules = false; + opts.targets = { + browsers: require( '@wordpress/browserslist-config' ), + }; + } + + if ( isWPBuild( wpBuildOpts.name ) ) { + opts.modules = wpBuildOpts.modules; + } + + return [ require.resolve( '@babel/preset-env' ), opts ]; + }; + + const maybeGetPluginTransformRuntime = () => { + if ( isTestEnv ) { + return undefined; + } + + const opts = { + helpers: true, + useESModules: false, + }; + + if ( wpBuildOpts.name === 'WP_BUILD_MODULE' ) { + opts.useESModules = wpBuildOpts.useESModules; + } + + return [ require.resolve( '@babel/plugin-transform-runtime' ), opts ]; + }; + return { - presets: [ - ! isTestEnv && [ '@babel/preset-env', { - modules: false, - targets: { - browsers: [ 'extends @wordpress/browserslist-config' ], - }, - } ], - isTestEnv && [ '@babel/preset-env', { - useBuiltIns: 'usage', - } ], - ].filter( Boolean ), + presets: [ getPresetEnv() ], plugins: [ - '@babel/plugin-proposal-object-rest-spread', + require.resolve( '@babel/plugin-proposal-object-rest-spread' ), [ - '@wordpress/babel-plugin-import-jsx-pragma', + require.resolve( '@wordpress/babel-plugin-import-jsx-pragma' ), { scopeVariable: 'createElement', source: '@wordpress/element', isDefault: false, }, ], - [ '@babel/plugin-transform-react-jsx', { + [ require.resolve( '@babel/plugin-transform-react-jsx' ), { pragma: 'createElement', } ], - '@babel/plugin-proposal-async-generator-functions', - ! isTestEnv && [ '@babel/plugin-transform-runtime', { - helpers: true, - useESModules: false, - } ], + require.resolve( '@babel/plugin-proposal-async-generator-functions' ), + maybeGetPluginTransformRuntime(), ].filter( Boolean ), }; }; diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index 70fed30229ba4f..9a1daabf5d752e 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -8,7 +8,7 @@ const path = require( 'path' ); /** * Internal dependencies */ -const { camelCaseDash } = require( '../utils' ); +const { camelCaseDash, hasBabelConfig } = require( '../utils' ); /** * Converts @wordpress/* string request into request object. @@ -66,6 +66,12 @@ const externals = [ const isProduction = process.env.NODE_ENV === 'production'; const mode = isProduction ? 'production' : 'development'; +const getBabelLoaderOptions = () => hasBabelConfig() ? {} : { + babelrc: false, + configFile: false, + presets: [ require.resolve( '@wordpress/babel-preset-default' ) ], +}; + const config = { mode, entry: { @@ -91,7 +97,10 @@ const config = { { test: /\.js$/, exclude: /node_modules/, - use: require.resolve( 'babel-loader' ), + use: { + loader: require.resolve( 'babel-loader' ), + options: getBabelLoaderOptions(), + }, }, ], }, diff --git a/packages/scripts/utils/config.js b/packages/scripts/utils/config.js index 0c5ed70c293ce2..3ae98725e5fbc7 100644 --- a/packages/scripts/utils/config.js +++ b/packages/scripts/utils/config.js @@ -7,6 +7,7 @@ const { hasPackageProp } = require( './package' ); const hasBabelConfig = () => hasProjectFile( '.babelrc' ) || + hasProjectFile( '.babelrc.js' ) || hasProjectFile( 'babel.config.js' ) || hasPackageProp( 'babel' );