mirror of https://github.com/facebook/jest.git
159 lines
4.5 KiB
JavaScript
159 lines
4.5 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
/**
|
|
* script to build (transpile) files.
|
|
* By default it transpiles js files for all packages and writes them
|
|
* into `build/` directory.
|
|
* Non-js files not matching IGNORE_PATTERN will be copied without transpiling.
|
|
*
|
|
* Example:
|
|
* node ./scripts/build.mjs
|
|
* node ./scripts/build.mjs /users/123/jest/packages/jest-111/src/111.js
|
|
*/
|
|
|
|
import {strict as assert} from 'assert';
|
|
import * as path from 'path';
|
|
import {fileURLToPath} from 'url';
|
|
import babel from '@babel/core';
|
|
import chalk from 'chalk';
|
|
import glob from 'glob';
|
|
import fs from 'graceful-fs';
|
|
import micromatch from 'micromatch';
|
|
import prettier from 'prettier';
|
|
import transformOptions from '../babel.config.js';
|
|
import {
|
|
OK,
|
|
PACKAGES_DIR,
|
|
adjustToTerminalWidth,
|
|
getPackages,
|
|
} from './buildUtils.mjs';
|
|
|
|
const SRC_DIR = 'src';
|
|
const BUILD_DIR = 'build';
|
|
const JS_FILES_PATTERN = '**/*.js';
|
|
const TS_FILES_PATTERN = '**/*.ts';
|
|
const IGNORE_PATTERN = '**/__{tests,mocks}__/**';
|
|
|
|
const INLINE_REQUIRE_EXCLUDE_LIST =
|
|
/packages\/expect|(jest-(circus|diff|get-type|jasmine2|matcher-utils|message-util|regex-util|snapshot))|pretty-format\//;
|
|
|
|
const prettierConfig = prettier.resolveConfig.sync(
|
|
fileURLToPath(import.meta.url),
|
|
);
|
|
prettierConfig.trailingComma = 'none';
|
|
prettierConfig.parser = 'babel';
|
|
|
|
function getPackageName(file) {
|
|
return path.relative(PACKAGES_DIR, file).split(path.sep)[0];
|
|
}
|
|
|
|
function getBuildPath(file, buildFolder) {
|
|
const pkgName = getPackageName(file);
|
|
const pkgSrcPath = path.resolve(PACKAGES_DIR, pkgName, SRC_DIR);
|
|
const pkgBuildPath = path.resolve(PACKAGES_DIR, pkgName, buildFolder);
|
|
const relativeToSrcPath = path.relative(pkgSrcPath, file);
|
|
return path.resolve(pkgBuildPath, relativeToSrcPath).replace(/\.ts$/, '.js');
|
|
}
|
|
|
|
function buildNodePackage({packageDir, pkg}) {
|
|
const srcDir = path.resolve(packageDir, SRC_DIR);
|
|
const files = glob.sync('**/*', {absolute: true, cwd: srcDir, nodir: true});
|
|
|
|
process.stdout.write(adjustToTerminalWidth(`${pkg.name}\n`));
|
|
|
|
files.forEach(file => buildFile(file, true));
|
|
|
|
assert.ok(
|
|
fs.existsSync(path.resolve(packageDir, pkg.main)),
|
|
`Main file "${pkg.main}" in ${pkg.name} should exist`,
|
|
);
|
|
|
|
process.stdout.write(`${OK}\n`);
|
|
}
|
|
|
|
function buildFile(file, silent) {
|
|
const destPath = getBuildPath(file, BUILD_DIR);
|
|
|
|
if (micromatch.isMatch(file, IGNORE_PATTERN)) {
|
|
silent ||
|
|
process.stdout.write(
|
|
`${
|
|
chalk.dim(' \u2022 ') + path.relative(PACKAGES_DIR, file)
|
|
} (ignore)\n`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
fs.mkdirSync(path.dirname(destPath), {recursive: true});
|
|
if (
|
|
!micromatch.isMatch(file, JS_FILES_PATTERN) &&
|
|
!micromatch.isMatch(file, TS_FILES_PATTERN)
|
|
) {
|
|
fs.createReadStream(file).pipe(fs.createWriteStream(destPath));
|
|
silent ||
|
|
process.stdout.write(
|
|
`${
|
|
chalk.red(' \u2022 ') +
|
|
path.relative(PACKAGES_DIR, file) +
|
|
chalk.red(' \u21D2 ') +
|
|
path.relative(PACKAGES_DIR, destPath)
|
|
} (copy)\n`,
|
|
);
|
|
} else {
|
|
const options = Object.assign({}, transformOptions);
|
|
options.plugins = options.plugins.slice();
|
|
|
|
if (INLINE_REQUIRE_EXCLUDE_LIST.test(file)) {
|
|
// The excluded modules are injected into the user's sandbox
|
|
// We need to guard some globals there.
|
|
options.plugins.push(
|
|
path.resolve(
|
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
'babel-plugin-jest-native-globals.js',
|
|
),
|
|
);
|
|
} else {
|
|
options.plugins = options.plugins.map(plugin => {
|
|
if (
|
|
Array.isArray(plugin) &&
|
|
plugin[0] === '@babel/plugin-transform-modules-commonjs'
|
|
) {
|
|
return [plugin[0], Object.assign({}, plugin[1], {lazy: true})];
|
|
}
|
|
|
|
return plugin;
|
|
});
|
|
}
|
|
|
|
const transformed = babel.transformFileSync(file, options).code;
|
|
const prettyCode = prettier.format(transformed, prettierConfig);
|
|
|
|
fs.writeFileSync(destPath, prettyCode);
|
|
|
|
silent ||
|
|
process.stdout.write(
|
|
`${
|
|
chalk.green(' \u2022 ') +
|
|
path.relative(PACKAGES_DIR, file) +
|
|
chalk.green(' \u21D2 ') +
|
|
path.relative(PACKAGES_DIR, destPath)
|
|
}\n`,
|
|
);
|
|
}
|
|
}
|
|
|
|
const files = process.argv.slice(2);
|
|
|
|
if (files.length) {
|
|
files.forEach(file => buildFile(file));
|
|
} else {
|
|
const packages = getPackages();
|
|
process.stdout.write(chalk.inverse(' Building packages \n'));
|
|
packages.forEach(buildNodePackage);
|
|
}
|