mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Codegen: Add prepublish script to build Flow files (#28827)
Summary: *This is a follow-up to https://github.com/facebook/react-native/issues/28645, redone using a build script based off of Metro's build script instead of using `flow-remove-types` and `flow-copy-source`.* This pull request adds a build step to `react-native-codegen` that builds the Flow-annotated JS files so that users of the NPM module `react-native-codegen` do not need to use require hooks to be able to import it. A new build script, `scripts/build.js` is added that builds every JS file in `src/` into a `lib/` folder, and also copies over the original Flow annotated files to `lib/` with a `.js.flow` extension, so users of `react-native-codegen` can still typecheck against it using Flow. The shell scripts in `src` are also copied over. It is based off of the [build script from Metro](https://github.com/facebook/metro/blob/00867816eb9b2f69c8af9cebb523e9e4d280671a/scripts/build.js) ## Changelog [General] [Added] - Codegen: Add prepublish script to build Flow files Pull Request resolved: https://github.com/facebook/react-native/pull/28827 Test Plan: I am able to make use of the Codegen scripts without needing to use the `flow-node` CLI or the `flow-remove-types/register` require hook. Reviewed By: cpojer Differential Revision: D21412173 Pulled By: hramos fbshipit-source-id: 26ae67cdd04652ca4700a069a234a25558773cb1
This commit is contained in:
committed by
Facebook GitHub Bot
parent
69ce9c21d4
commit
c67e1fe42f
@@ -10,3 +10,4 @@ Libraries/vendor/**/*
|
||||
packages/*/node_modules
|
||||
pr-inactivity-bookmarklet.js
|
||||
question-bookmarklet.js
|
||||
packages/react-native-codegen/lib
|
||||
|
||||
+2
-1
@@ -94,9 +94,10 @@ RNTester/Pods/*
|
||||
!RNTester/Pods/__offline_mirrors
|
||||
|
||||
# react-native-codegen
|
||||
/packages/react-native-codegen/lib
|
||||
/ReactCommon/fabric/components/rncore/
|
||||
/schema-rncore.json
|
||||
/schema-native-modules.json
|
||||
/schema-rncore.json
|
||||
|
||||
# Visual studio
|
||||
.vscode
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-transform-async-to-generator",
|
||||
"@babel/plugin-transform-destructuring",
|
||||
"@babel/plugin-transform-flow-strip-types",
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"@babel/plugin-proposal-optional-chaining"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"requirePragma": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": false,
|
||||
"jsxBracketSameLine": true
|
||||
}
|
||||
@@ -7,13 +7,33 @@
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/react-native.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn clean && node scripts/build.js --verbose",
|
||||
"clean": "rm -rf lib",
|
||||
"prepublish": "yarn run build"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"src"
|
||||
"lib"
|
||||
],
|
||||
"dependencies": {
|
||||
"flow-parser": "^0.121.0",
|
||||
"jscodeshift": "^0.9.0",
|
||||
"nullthrows": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.0.0",
|
||||
"@babel/plugin-transform-destructuring": "^7.0.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"micromatch": "^4.0.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"prettier": "1.19.1"
|
||||
}
|
||||
}
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* script to build (transpile) files.
|
||||
*
|
||||
* Based off of the build script from Metro, and tweaked to run in just one
|
||||
* package instead of in a monorepo. Just run `build.js` and the JS files in
|
||||
* `src/` will be built in `lib/`, and the original source files will be copied
|
||||
* over as `Example.js.flow`, so consumers of this module can still make use of
|
||||
* type checking.
|
||||
*
|
||||
* Call this script with the `--verbose` flag to show the full output of this
|
||||
* script.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const babel = require('@babel/core');
|
||||
const chalk = require('chalk');
|
||||
const fs = require('fs');
|
||||
const glob = require('glob');
|
||||
const micromatch = require('micromatch');
|
||||
const mkdirp = require('mkdirp');
|
||||
const path = require('path');
|
||||
const prettier = require('prettier');
|
||||
const prettierConfig = JSON.parse(
|
||||
fs.readFileSync(path.resolve(__dirname, '..', '.prettierrc'), 'utf8'),
|
||||
);
|
||||
|
||||
const SRC_DIR = 'src';
|
||||
const BUILD_DIR = 'lib';
|
||||
const JS_FILES_PATTERN = '**/*.js';
|
||||
const IGNORE_PATTERN = '**/__tests__/**';
|
||||
const PACKAGE_DIR = path.resolve(__dirname, '../');
|
||||
|
||||
const fixedWidth = str => {
|
||||
const WIDTH = 80;
|
||||
const strs = str.match(new RegExp(`(.{1,${WIDTH}})`, 'g')) || [str];
|
||||
let lastString = strs[strs.length - 1];
|
||||
if (lastString.length < WIDTH) {
|
||||
lastString += Array(WIDTH - lastString.length).join(chalk.dim('.'));
|
||||
}
|
||||
return strs
|
||||
.slice(0, -1)
|
||||
.concat(lastString)
|
||||
.join('\n');
|
||||
};
|
||||
|
||||
function getBuildPath(file, buildFolder) {
|
||||
const pkgSrcPath = path.resolve(PACKAGE_DIR, SRC_DIR);
|
||||
const pkgBuildPath = path.resolve(PACKAGE_DIR, BUILD_DIR);
|
||||
const relativeToSrcPath = path.relative(pkgSrcPath, file);
|
||||
return path.resolve(pkgBuildPath, relativeToSrcPath);
|
||||
}
|
||||
|
||||
function buildFile(file, silent) {
|
||||
const destPath = getBuildPath(file, BUILD_DIR);
|
||||
|
||||
mkdirp.sync(path.dirname(destPath));
|
||||
if (micromatch.isMatch(file, IGNORE_PATTERN)) {
|
||||
silent ||
|
||||
process.stdout.write(
|
||||
chalk.dim(' \u2022 ') +
|
||||
path.relative(PACKAGE_DIR, file) +
|
||||
' (ignore)\n',
|
||||
);
|
||||
} else if (!micromatch.isMatch(file, JS_FILES_PATTERN)) {
|
||||
fs.createReadStream(file).pipe(fs.createWriteStream(destPath));
|
||||
silent ||
|
||||
process.stdout.write(
|
||||
chalk.red(' \u2022 ') +
|
||||
path.relative(PACKAGE_DIR, file) +
|
||||
chalk.red(' \u21D2 ') +
|
||||
path.relative(PACKAGE_DIR, destPath) +
|
||||
' (copy)' +
|
||||
'\n',
|
||||
);
|
||||
} else {
|
||||
const transformed = prettier.format(
|
||||
babel.transformFileSync(file, {}).code,
|
||||
{
|
||||
...prettierConfig,
|
||||
parser: 'babel',
|
||||
},
|
||||
);
|
||||
fs.writeFileSync(destPath, transformed);
|
||||
const source = fs.readFileSync(file).toString('utf-8');
|
||||
if (/\@flow/.test(source)) {
|
||||
fs.createReadStream(file).pipe(fs.createWriteStream(destPath + '.flow'));
|
||||
}
|
||||
silent ||
|
||||
process.stdout.write(
|
||||
chalk.green(' \u2022 ') +
|
||||
path.relative(PACKAGE_DIR, file) +
|
||||
chalk.green(' \u21D2 ') +
|
||||
path.relative(PACKAGE_DIR, destPath) +
|
||||
'\n',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const srcDir = path.resolve(__dirname, '..', SRC_DIR);
|
||||
const pattern = path.resolve(srcDir, '**/*');
|
||||
const files = glob.sync(pattern, {nodir: true});
|
||||
|
||||
process.stdout.write(fixedWidth(`${path.basename(PACKAGE_DIR)}\n`));
|
||||
|
||||
files.forEach(file => buildFile(file, !process.argv.includes('--verbose')));
|
||||
|
||||
process.stdout.write(`[ ${chalk.green('OK')} ]\n`);
|
||||
Reference in New Issue
Block a user