2018-10-30 18:57:48 +00:00
|
|
|
/**
|
|
|
|
* script to build packages into `build/` directory.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* node ./bin/packages/build.js
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
const fs = require( 'fs' );
|
|
|
|
const path = require( 'path' );
|
|
|
|
const glob = require( 'glob' );
|
|
|
|
const babel = require( '@babel/core' );
|
|
|
|
const chalk = require( 'chalk' );
|
|
|
|
const mkdirp = require( 'mkdirp' );
|
2021-06-02 03:54:00 +00:00
|
|
|
const sass = require( 'sass' );
|
2018-10-30 18:57:48 +00:00
|
|
|
const postcss = require( 'postcss' );
|
2020-10-14 20:50:57 +00:00
|
|
|
const rimraf = require( 'rimraf' );
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
const getPackages = require( './get-packages' );
|
|
|
|
const getBabelConfig = require( './get-babel-config' );
|
2020-10-14 20:50:57 +00:00
|
|
|
const { exit } = require( 'process' );
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Module Constants
|
|
|
|
*/
|
|
|
|
const PACKAGES_DIR = path.resolve( __dirname, '../../packages' );
|
|
|
|
const SRC_DIR = 'src';
|
|
|
|
const BUILD_DIR = {
|
|
|
|
main: 'build',
|
|
|
|
module: 'build-module',
|
|
|
|
style: 'build-style',
|
|
|
|
};
|
|
|
|
const DONE = chalk.reset.inverse.bold.green( ' DONE ' );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the package name for a specified file
|
|
|
|
*
|
|
|
|
* @param {string} file File name
|
|
|
|
* @return {string} Package name
|
|
|
|
*/
|
|
|
|
function getPackageName( file ) {
|
|
|
|
return path.relative( PACKAGES_DIR, file ).split( path.sep )[ 0 ];
|
|
|
|
}
|
|
|
|
|
|
|
|
const isJsFile = ( filepath ) => {
|
2021-04-15 01:32:46 +00:00
|
|
|
return /.\.(js|ts|tsx)$/.test( filepath );
|
2018-10-30 18:57:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const isScssFile = ( filepath ) => {
|
|
|
|
return /.\.scss$/.test( filepath );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get Build Path for a specified file
|
|
|
|
*
|
|
|
|
* @param {string} file File to build
|
|
|
|
* @param {string} buildFolder Output folder
|
|
|
|
* @return {string} Build path
|
|
|
|
*/
|
|
|
|
function getBuildPath( file, buildFolder ) {
|
2021-03-24 21:29:37 +00:00
|
|
|
// if the file has extension of ts, replace with js
|
|
|
|
const fileName = file.replace( '.ts', '.js' );
|
|
|
|
const pkgName = getPackageName( fileName );
|
2018-10-30 18:57:48 +00:00
|
|
|
const pkgSrcPath = path.resolve( PACKAGES_DIR, pkgName, SRC_DIR );
|
|
|
|
const pkgBuildPath = path.resolve( PACKAGES_DIR, pkgName, buildFolder );
|
2021-03-24 21:29:37 +00:00
|
|
|
const relativeToSrcPath = path.relative( pkgSrcPath, fileName );
|
2018-10-30 18:57:48 +00:00
|
|
|
return path.resolve( pkgBuildPath, relativeToSrcPath );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a list of scss and js filepaths, divide them into sets them and rebuild.
|
|
|
|
*
|
|
|
|
* @param {Array} files list of files to rebuild
|
|
|
|
*/
|
|
|
|
function buildFiles( files ) {
|
|
|
|
// Reduce files into a unique sets of javaScript files and scss packages.
|
2020-05-07 18:24:12 +00:00
|
|
|
const buildPaths = files.reduce(
|
|
|
|
( accumulator, filePath ) => {
|
|
|
|
if ( isJsFile( filePath ) ) {
|
|
|
|
accumulator.jsFiles.add( filePath );
|
|
|
|
} else if ( isScssFile( filePath ) ) {
|
|
|
|
const pkgName = getPackageName( filePath );
|
|
|
|
const pkgPath = path.resolve( PACKAGES_DIR, pkgName );
|
|
|
|
accumulator.scssPackagePaths.add( pkgPath );
|
|
|
|
}
|
|
|
|
return accumulator;
|
|
|
|
},
|
|
|
|
{ jsFiles: new Set(), scssPackagePaths: new Set() }
|
|
|
|
);
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
buildPaths.jsFiles.forEach( buildJsFile );
|
|
|
|
buildPaths.scssPackagePaths.forEach( buildPackageScss );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a javaScript file for the required environments (node and ES5)
|
|
|
|
*
|
|
|
|
* @param {string} file File path to build
|
|
|
|
* @param {boolean} silent Show logs
|
|
|
|
*/
|
|
|
|
function buildJsFile( file, silent ) {
|
|
|
|
buildJsFileFor( file, silent, 'main' );
|
|
|
|
buildJsFileFor( file, silent, 'module' );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a package's scss styles
|
|
|
|
*
|
|
|
|
* @param {string} packagePath The path to the package.
|
|
|
|
*/
|
2020-11-23 20:21:16 +00:00
|
|
|
async function buildPackageScss( packagePath ) {
|
2018-10-30 18:57:48 +00:00
|
|
|
const srcDir = path.resolve( packagePath, SRC_DIR );
|
2021-05-26 19:35:46 +00:00
|
|
|
const scssFiles = glob.sync( `${ srcDir }/**/*.scss` );
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
// Build scss files individually.
|
2020-11-23 20:21:16 +00:00
|
|
|
return Promise.all( scssFiles.map( ( file ) => buildScssFile( file ) ) );
|
2018-10-30 18:57:48 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 20:21:16 +00:00
|
|
|
async function buildScssFile( styleFile ) {
|
2020-05-07 18:24:12 +00:00
|
|
|
const outputFile = getBuildPath(
|
|
|
|
styleFile.replace( '.scss', '.css' ),
|
|
|
|
BUILD_DIR.style
|
|
|
|
);
|
|
|
|
const outputFileRTL = getBuildPath(
|
|
|
|
styleFile.replace( '.scss', '-rtl.css' ),
|
|
|
|
BUILD_DIR.style
|
|
|
|
);
|
2020-11-23 20:21:16 +00:00
|
|
|
|
|
|
|
await mkdirp.sync( path.dirname( outputFile ) );
|
|
|
|
const builtSass = await sass.renderSync( {
|
2018-10-30 18:57:48 +00:00
|
|
|
file: styleFile,
|
2020-05-07 18:24:12 +00:00
|
|
|
includePaths: [
|
|
|
|
path.resolve( __dirname, '../../client/stylesheets/abstracts' ),
|
2021-06-02 03:54:00 +00:00
|
|
|
path.resolve( __dirname, '../../node_modules' ),
|
2020-05-07 18:24:12 +00:00
|
|
|
],
|
|
|
|
data:
|
2021-06-10 09:09:27 +00:00
|
|
|
'@forward "sass:math"; @use "sass:math";' +
|
2020-05-07 18:24:12 +00:00
|
|
|
[ 'colors', 'variables', 'breakpoints', 'mixins' ]
|
|
|
|
.map( ( imported ) => `@import "_${ imported }";` )
|
2021-06-10 09:09:27 +00:00
|
|
|
.join( ' ' ) +
|
|
|
|
fs.readFileSync( styleFile, 'utf8' ),
|
2018-10-30 18:57:48 +00:00
|
|
|
} );
|
|
|
|
|
2020-06-15 02:00:25 +00:00
|
|
|
const postCSSConfig = require( '@wordpress/postcss-plugins-preset' );
|
2020-11-23 20:21:16 +00:00
|
|
|
const ltrCSS = await postcss( postCSSConfig ).process( builtSass.css, {
|
|
|
|
from: 'src/app.css',
|
|
|
|
to: 'dest/app.css',
|
|
|
|
} );
|
|
|
|
fs.writeFileSync( outputFile, ltrCSS.css );
|
|
|
|
|
|
|
|
const rtlCSS = await postcss( [ require( 'rtlcss' )() ] ).process( ltrCSS, {
|
|
|
|
from: 'src/app.css',
|
|
|
|
to: 'dest/app.css',
|
|
|
|
} );
|
|
|
|
fs.writeFileSync( outputFileRTL, rtlCSS.css );
|
2018-10-30 18:57:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a file for a specific environment
|
|
|
|
*
|
|
|
|
* @param {string} file File path to build
|
|
|
|
* @param {boolean} silent Show logs
|
|
|
|
* @param {string} environment Dist environment (node or es5)
|
|
|
|
*/
|
|
|
|
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;
|
|
|
|
|
|
|
|
mkdirp.sync( path.dirname( destPath ) );
|
|
|
|
const transformed = babel.transformFileSync( file, babelOptions );
|
|
|
|
fs.writeFileSync( destPath + '.map', JSON.stringify( transformed.map ) );
|
2020-05-07 18:24:12 +00:00
|
|
|
fs.writeFileSync(
|
|
|
|
destPath,
|
|
|
|
transformed.code +
|
|
|
|
'\n//# sourceMappingURL=' +
|
|
|
|
path.basename( destPath ) +
|
|
|
|
'.map'
|
|
|
|
);
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
if ( ! silent ) {
|
|
|
|
process.stdout.write(
|
|
|
|
chalk.green( ' \u2022 ' ) +
|
|
|
|
path.relative( PACKAGES_DIR, file ) +
|
|
|
|
chalk.green( ' \u21D2 ' ) +
|
|
|
|
path.relative( PACKAGES_DIR, destPath ) +
|
|
|
|
'\n'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build the provided package path
|
|
|
|
*
|
|
|
|
* @param {string} packagePath absolute package path
|
|
|
|
*/
|
2020-11-23 20:21:16 +00:00
|
|
|
async function buildPackage( packagePath ) {
|
2018-10-30 18:57:48 +00:00
|
|
|
const srcDir = path.resolve( packagePath, SRC_DIR );
|
2021-03-24 21:29:37 +00:00
|
|
|
const jsFiles = glob.sync( `${ srcDir }/**/*.{ts,tsx,js}`, {
|
2018-10-30 18:57:48 +00:00
|
|
|
ignore: [
|
|
|
|
`${ srcDir }/**/test/**/*.js`,
|
|
|
|
`${ srcDir }/**/__mocks__/**/*.js`,
|
|
|
|
],
|
|
|
|
nodir: true,
|
|
|
|
} );
|
|
|
|
|
2020-11-23 20:21:16 +00:00
|
|
|
// Build package CSS files
|
|
|
|
await buildPackageScss( packagePath );
|
|
|
|
|
2018-10-30 18:57:48 +00:00
|
|
|
process.stdout.write( `${ path.basename( packagePath ) }\n` );
|
|
|
|
|
|
|
|
// Build js files individually.
|
2021-03-24 21:29:37 +00:00
|
|
|
jsFiles.forEach( ( file ) => {
|
|
|
|
buildJsFile( file, true );
|
|
|
|
} );
|
2018-10-30 18:57:48 +00:00
|
|
|
|
|
|
|
process.stdout.write( `${ DONE }\n` );
|
|
|
|
}
|
|
|
|
|
|
|
|
const files = process.argv.slice( 2 );
|
|
|
|
|
|
|
|
if ( files.length ) {
|
|
|
|
buildFiles( files );
|
|
|
|
} else {
|
|
|
|
process.stdout.write( chalk.inverse( '>> Building packages \n' ) );
|
2020-11-12 09:31:18 +00:00
|
|
|
getPackages()
|
|
|
|
.filter(
|
|
|
|
( package ) =>
|
|
|
|
! /dependency-extraction-webpack-plugin/.test( package )
|
|
|
|
)
|
|
|
|
.forEach( buildPackage );
|
2018-10-30 18:57:48 +00:00
|
|
|
process.stdout.write( '\n' );
|
|
|
|
}
|