-
Notifications
You must be signed in to change notification settings - Fork 622
/
Copy pathcompile.js
131 lines (113 loc) · 4.37 KB
/
compile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* script to build (transpile) files.
* By default it transpiles all files for all packages and writes them
* into `lib/` directory.
* Non-js or files matching IGNORE_PATTERN will be copied without transpiling.
*
* Example:
* compile all packages: node ./scripts/compile.js
* watch compile some packages: node ./scripts/compile.js --watch --packages rax,rax-cli
*/
'use strict';
const fs = require('fs');
const path = require('path');
const spawnSync = require('child_process').spawnSync;
const babel = require('@babel/core');
const chalk = require('chalk');
const glob = require('glob');
const minimatch = require('minimatch');
const parseArgs = require('minimist');
const chokidar = require('chokidar');
const SRC_DIR = 'src';
const JS_FILES_PATTERN = '**/*.js';
const IGNORE_PATTERN = '**/{__tests__,__mocks__}/**';
// Don't need compile packages
const IGNORE_COMPILE_PACKAGES = ['rax'];
const args = parseArgs(process.argv);
const customPackages = args.packages;
const getBabelConfig = require('./config/getBabelConfig');
const fixedWidth = str => {
const WIDTH = 80;
const strs = str.match(new RegExp(`(.{1,${WIDTH}})`, 'g'));
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 buildPackage(packagesDir, p, isBuildEs) {
const srcDir = path.resolve(p, SRC_DIR);
const pattern = path.resolve(srcDir, '**/*');
const files = glob.sync(pattern, {nodir: true});
const dirName = path.basename(p);
process.stdout.write(
fixedWidth(`${dirName}\n`)
);
files.forEach(file => buildFile(packagesDir, file, isBuildEs));
process.stdout.write(`[ ${chalk.green('OK')} ]\n`);
}
function getPackages(packagesDir, customPackages) {
return fs.readdirSync(packagesDir)
.filter(file => !IGNORE_COMPILE_PACKAGES.includes(file)) // Exclude compile rax
.map(file => path.resolve(packagesDir, file))
.filter(f => {
if (customPackages) {
const packageName = path.relative(packagesDir, f).split(path.sep)[0];
return packageName.indexOf(customPackages) !== -1;
} else {
return true;
}
})
.filter(f => fs.lstatSync(path.resolve(f)).isDirectory());
}
function buildFile(packagesDir, file, isBuildEs) {
const BUILD_DIR = isBuildEs ? 'es' : 'lib';
const packageName = path.relative(packagesDir, file).split(path.sep)[0];
const packageSrcPath = path.resolve(packagesDir, packageName, SRC_DIR);
const packageBuildPath = path.resolve(packagesDir, packageName, BUILD_DIR);
const relativeToSrcPath = path.relative(packageSrcPath, file);
const destPath = path.resolve(packageBuildPath, relativeToSrcPath);
let babelOptions;
if (isBuildEs) {
babelOptions = getBabelConfig(true);
} else {
babelOptions = getBabelConfig();
}
spawnSync('mkdir', ['-p', path.dirname(destPath)]);
if (!minimatch(file, IGNORE_PATTERN)) {
if (!minimatch(file, JS_FILES_PATTERN)) {
fs.createReadStream(file).pipe(fs.createWriteStream(destPath));
} else {
const transformed = babel.transformFileSync(file, babelOptions).code;
spawnSync('mkdir', ['-p', path.dirname(destPath)]);
fs.writeFileSync(destPath, transformed);
}
}
}
// const packagesDir = path.resolve(__dirname, '../packages');
module.exports = function compile(packagesName, isBuildEs) {
const packagesDir = path.resolve(__dirname, `../${packagesName}`);
const packages = getPackages(packagesDir, customPackages);
if (args.watch) {
// watch packages
const watchPackagesDir = packages.map(dir => path.resolve(dir, SRC_DIR));
console.log(chalk.green('watch packages compile', packages));
chokidar.watch(watchPackagesDir, {
ignored: IGNORE_PATTERN
}).on('change', (filePath) => {
const packageName = filePath.match( new RegExp(`\/${packagesName}\/([^\/]*)`))[1];
const packagePath = path.resolve(__dirname, `../${packagesName}/`, packageName);
process.stdout.write(chalk.bold.inverse(`Compiling package ${packageName} \n`));
try {
buildPackage(packagesDir, packagePath, isBuildEs);
} catch (e) {}
process.stdout.write('\n');
});
} else {
process.stdout.write(chalk.bold.inverse('Compiling packages\n'));
packages.forEach((v) => {
buildPackage(packagesDir, v, isBuildEs);
});
process.stdout.write('\n');
}
};