Issue #11257(Updated) - Change build process to include npm pack and unpacking (#11750)
* Change build process to include npm pack and unpacking generated packages to corresponding build directories. * Update function name, change to use os's default temp directory * appending uuid to temp npm packaging directory.
Yu Tian committed
Dec 6, 2017 at 00:53 UTC
6d242904cd5f2ee1255da54b14af700f1e3878f3
5 files changed
+160
-12
package.json
+2
@@ -89,9 +89,11 @@
89
"rollup-plugin-replace": "^1.1.1",
90
"rollup-plugin-strip-banner": "^0.2.0",
91
"run-sequence": "^1.1.4",
92
+ "targz": "^1.0.1",
93
"through2": "^2.0.0",
94
"tmp": "~0.0.28",
95
"typescript": "~1.8.10",
96
+ "uuid": "^3.1.0",
97
"yargs": "^6.3.0"
98
},
99
"devEngines": {
scripts/rollup/build.js
+21
-1
@@ -10,6 +10,7 @@ const stripBanner = require('rollup-plugin-strip-banner');
10
const chalk = require('chalk');
11
const path = require('path');
12
const resolve = require('rollup-plugin-node-resolve');
13
+const os = require('os');
14
const fs = require('fs');
15
const rimraf = require('rimraf');
16
const argv = require('minimist')(process.argv.slice(2));
@@ -26,6 +27,7 @@ const syncReactNativeCS = require('./sync').syncReactNativeCS;
27
const Packaging = require('./packaging');
28
const codeFrame = require('babel-code-frame');
29
const Wrappers = require('./wrappers');
30
+const uuidv1 = require('uuid/v1');
31
32
const UMD_DEV = Bundles.bundleTypes.UMD_DEV;
33
const UMD_PROD = Bundles.bundleTypes.UMD_PROD;
@@ -48,6 +50,10 @@ const shouldExtractErrors = argv['extract-errors'];
50
const errorCodeOpts = {
51
errorMapFilePath: 'scripts/error-codes/codes.json',
52
};
53
+const npmPackagesTmpDir = path.join(
54
+ os.tmpdir(),
55
+ `react-npm-packages-${uuidv1()}`
56
+);
57
58
const closureOptions = {
59
compilationLevel: 'SIMPLE',
@@ -397,7 +403,12 @@ async function createBundle(bundle, bundleType) {
403
bundle.moduleType
404
)
405
);
400
- await Packaging.createNodePackage(bundleType, packageName, filename);
406
+ await Packaging.createNodePackage(
407
+ bundleType,
408
+ packageName,
409
+ filename,
410
+ npmPackagesTmpDir
411
+ );
412
console.log(`${chalk.bgGreen.black(' COMPLETE ')} ${logKey}\n`);
413
} catch (error) {
414
if (error.code) {
@@ -435,6 +446,9 @@ rimraf('build', async () => {
446
try {
447
// create a new build directory
448
fs.mkdirSync('build');
449
+ // create the temp directory for local npm packing and unpacking
450
+ // in operating system's default temporary directory
451
+ fs.mkdirSync(npmPackagesTmpDir);
452
// create the packages folder for NODE+UMD bundles
453
fs.mkdirSync(path.join('build', 'packages'));
454
// create the dist folder for UMD bundles
@@ -476,6 +490,12 @@ rimraf('build', async () => {
490
'used when the error map needs to be rebuilt.\n'
491
);
492
}
493
+ rimraf(npmPackagesTmpDir, err => {
494
+ if (err) {
495
+ console.error(err);
496
+ process.exit(1);
497
+ }
498
+ });
499
} catch (err) {
500
console.error(err);
501
process.exit(1);
scripts/rollup/packaging.js
+45
-9
@@ -6,6 +6,8 @@ const join = require('path').join;
6
const resolve = require('path').resolve;
7
const Bundles = require('./bundles');
8
const asyncCopyTo = require('./utils').asyncCopyTo;
9
+const asyncExecuteCommand = require('./utils').asyncExecuteCommand;
10
+const asyncExtractTar = require('./utils').asyncExtractTar;
11
12
const UMD_DEV = Bundles.bundleTypes.UMD_DEV;
13
const UMD_PROD = Bundles.bundleTypes.UMD_PROD;
@@ -84,8 +86,13 @@ async function createFacebookWWWBuild() {
86
await asyncCopyTo(from, to);
87
}
88
87
-async function copyBundleIntoNodePackage(packageName, filename, bundleType) {
88
- const packageDirectory = resolve(`./build/packages/${packageName}`);
89
+async function copyBundleIntoNodePackage(
90
+ packageName,
91
+ filename,
92
+ bundleType,
93
+ npmPackagesTmpDir
94
+) {
95
+ const packageDirectory = resolve(`${npmPackagesTmpDir}/${packageName}`);
96
if (!fs.existsSync(packageDirectory)) {
97
return;
98
}
@@ -121,9 +128,9 @@ async function copyBundleIntoNodePackage(packageName, filename, bundleType) {
128
}
129
}
130
124
-async function copyNodePackageTemplate(packageName) {
131
+async function copyNodePackageTemplate(packageName, npmPackagesTmpDir) {
132
const from = resolve(`./packages/${packageName}`);
126
- const to = resolve(`./build/packages/${packageName}`);
133
+ const to = resolve(`${npmPackagesTmpDir}/${packageName}`);
134
const npmFrom = resolve(`${from}/npm`);
135
if (!fs.existsSync(npmFrom)) {
136
// The package is not meant for npm consumption.
@@ -133,21 +140,50 @@ async function copyNodePackageTemplate(packageName) {
140
// We already created this package (e.g. due to another entry point).
141
return;
142
}
136
- // TODO: verify that all copied files are either in the "files"
137
- // whitelist or implicitly published by npm.
143
await asyncCopyTo(npmFrom, to);
144
await asyncCopyTo(resolve(`${from}/package.json`), `${to}/package.json`);
145
await asyncCopyTo(resolve(`${from}/README.md`), `${to}/README.md`);
146
await asyncCopyTo(resolve('./LICENSE'), `${to}/LICENSE`);
147
}
148
144
-async function createNodePackage(bundleType, packageName, filename) {
149
+async function packForNpmAndUnpack(packageName, npmPackagesTmpDir) {
150
+ const packageTmpDir = resolve(`${npmPackagesTmpDir}/${packageName}`);
151
+ const extractTmpDir = resolve(`${packageTmpDir}/extract`);
152
+ const build = resolve(`./build/packages/${packageName}`);
153
+ const npmFrom = resolve(`./packages/${packageName}/npm`);
154
+ if (!fs.existsSync(npmFrom)) {
155
+ return;
156
+ }
157
+ let tgzName = await asyncExecuteCommand(`cd ${packageTmpDir} && npm pack`);
158
+ // In npm packages, files are grouped into a root directory(named 'package').
159
+ // We only copy the packed files instead of extract the root 'package' directly to build directory
160
+ await asyncExtractTar({
161
+ src: `${packageTmpDir}/${tgzName.trim()}`,
162
+ dest: extractTmpDir,
163
+ });
164
+ await asyncCopyTo(`${extractTmpDir}/package`, build);
165
+}
166
+
167
+async function createNodePackage(
168
+ bundleType,
169
+ packageName,
170
+ filename,
171
+ npmPackagesTmpDir
172
+) {
173
// the only case where we don't want to copy the package is for FB bundles
174
if (bundleType === FB_DEV || bundleType === FB_PROD) {
175
return;
176
}
149
- await copyNodePackageTemplate(packageName);
150
- await copyBundleIntoNodePackage(packageName, filename, bundleType);
177
+ await copyNodePackageTemplate(packageName, npmPackagesTmpDir);
178
+ await copyBundleIntoNodePackage(
179
+ packageName,
180
+ filename,
181
+ bundleType,
182
+ npmPackagesTmpDir
183
+ );
184
+ // Packing packages locally, simulate npm publish,
185
+ // Then unpacking generated packages to build directory
186
+ await packForNpmAndUnpack(packageName, npmPackagesTmpDir);
187
}
188
189
function getOutputPathRelativeToBuildFolder(bundleType, filename, hasteName) {
scripts/rollup/utils.js
+30
@@ -3,6 +3,8 @@
3
const ncp = require('ncp').ncp;
4
const join = require('path').join;
5
const resolve = require('path').resolve;
6
+const exec = require('child_process').exec;
7
+const targz = require('targz');
8
9
function asyncCopyTo(from, to) {
10
return new Promise(_resolve => {
@@ -24,7 +26,35 @@ function resolvePath(path) {
26
}
27
}
28
29
+function asyncExecuteCommand(command) {
30
+ return new Promise(_resolve =>
31
+ exec(command, (error, stdout) => {
32
+ if (!error) {
33
+ _resolve(stdout);
34
+ } else {
35
+ console.error(error);
36
+ process.exit(1);
37
+ }
38
+ })
39
+ );
40
+}
41
+
42
+function asyncExtractTar(options) {
43
+ return new Promise(_resolve =>
44
+ targz.decompress(options, error => {
45
+ if (!error) {
46
+ _resolve();
47
+ } else {
48
+ console.error(error);
49
+ process.exit(1);
50
+ }
51
+ })
52
+ );
53
+}
54
+
55
module.exports = {
56
asyncCopyTo: asyncCopyTo,
57
resolvePath: resolvePath,
58
+ asyncExecuteCommand: asyncExecuteCommand,
59
+ asyncExtractTar: asyncExtractTar,
60
};
yarn.lock
+62
-2
@@ -935,6 +935,12 @@ binary-extensions@^1.0.0:
935
version "1.8.0"
936
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774"
937
938
+bl@^1.0.0:
939
+ version "1.2.1"
940
+ resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e"
941
+ dependencies:
942
+ readable-stream "^2.0.5"
943
+
944
block-stream@*:
945
version "0.0.9"
946
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
@@ -1101,6 +1107,10 @@ chokidar@^1.0.0, chokidar@^1.6.1:
1107
optionalDependencies:
1108
fsevents "^1.0.0"
1109
1110
+chownr@^1.0.1:
1111
+ version "1.0.1"
1112
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
1113
+
1114
ci-info@^1.0.0:
1115
version "1.0.0"
1116
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534"
@@ -1529,7 +1539,7 @@ end-of-stream@1.0.0:
1539
dependencies:
1540
once "~1.3.0"
1541
1532
-end-of-stream@^1.1.0:
1542
+end-of-stream@^1.0.0, end-of-stream@^1.1.0:
1543
version "1.4.0"
1544
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
1545
dependencies:
@@ -2387,7 +2397,7 @@ inflight@^1.0.4:
2397
once "^1.3.0"
2398
wrappy "1"
2399
2390
-inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1:
2400
+inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
2401
version "2.0.3"
2402
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
2403
@@ -3868,6 +3878,18 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable
3878
string_decoder "~1.0.0"
3879
util-deprecate "~1.0.1"
3880
3881
+readable-stream@^2.0.5:
3882
+ version "2.3.3"
3883
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
3884
+ dependencies:
3885
+ core-util-is "~1.0.0"
3886
+ inherits "~2.0.3"
3887
+ isarray "~1.0.0"
3888
+ process-nextick-args "~1.0.6"
3889
+ safe-buffer "~5.1.1"
3890
+ string_decoder "~1.0.3"
3891
+ util-deprecate "~1.0.1"
3892
+
3893
readable-stream@~2.0.0:
3894
version "2.0.6"
3895
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
@@ -4227,6 +4249,10 @@ safe-buffer@^5.0.1:
4249
version "5.0.1"
4250
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
4251
4252
+safe-buffer@~5.1.0, safe-buffer@~5.1.1:
4253
+ version "5.1.1"
4254
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
4255
+
4256
sane@^2.0.0:
4257
version "2.0.0"
4258
resolved "https://registry.yarnpkg.com/sane/-/sane-2.0.0.tgz#99cb79f21f4a53a69d4d0cd957c2db04024b8eb2"
@@ -4445,6 +4471,12 @@ string_decoder@~1.0.0:
4471
dependencies:
4472
buffer-shims "~1.0.0"
4473
4474
+string_decoder@~1.0.3:
4475
+ version "1.0.3"
4476
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
4477
+ dependencies:
4478
+ safe-buffer "~5.1.0"
4479
+
4480
stringmap@~0.2.2:
4481
version "0.2.2"
4482
resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1"
@@ -4526,6 +4558,15 @@ table@^3.7.8:
4558
slice-ansi "0.0.4"
4559
string-width "^2.0.0"
4560
4561
+tar-fs@^1.8.1:
4562
+ version "1.16.0"
4563
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.0.tgz#e877a25acbcc51d8c790da1c57c9cf439817b896"
4564
+ dependencies:
4565
+ chownr "^1.0.1"
4566
+ mkdirp "^0.5.1"
4567
+ pump "^1.0.0"
4568
+ tar-stream "^1.1.2"
4569
+
4570
tar-pack@^3.4.0:
4571
version "3.4.0"
4572
resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984"
@@ -4539,6 +4580,15 @@ tar-pack@^3.4.0:
4580
tar "^2.2.1"
4581
uid-number "^0.0.6"
4582
4583
+tar-stream@^1.1.2:
4584
+ version "1.5.5"
4585
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55"
4586
+ dependencies:
4587
+ bl "^1.0.0"
4588
+ end-of-stream "^1.0.0"
4589
+ readable-stream "^2.0.0"
4590
+ xtend "^4.0.0"
4591
+
4592
tar@^2.2.1:
4593
version "2.2.1"
4594
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
@@ -4547,6 +4597,12 @@ tar@^2.2.1:
4597
fstream "^1.0.2"
4598
inherits "2"
4599
4600
+targz@^1.0.1:
4601
+ version "1.0.1"
4602
+ resolved "https://registry.yarnpkg.com/targz/-/targz-1.0.1.tgz#8f76a523694cdedfbb5d60a4076ff6eeecc5398f"
4603
+ dependencies:
4604
+ tar-fs "^1.8.1"
4605
+
4606
test-exclude@^4.1.1:
4607
version "4.1.1"
4608
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
@@ -4732,6 +4788,10 @@ uuid@^3.0.0:
4788
version "3.0.1"
4789
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
4790
4791
+uuid@^3.1.0:
4792
+ version "3.1.0"
4793
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
4794
+
4795
v8flags@^2.0.10:
4796
version "2.1.1"
4797
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"