1 | const { logInfo, logError } = require('./log');
|
2 | const { query } = require('../configs/utils');
|
3 | const fs = require('fs');
|
4 | const path = require('path');
|
5 | const chokidar = require('chokidar');
|
6 | const glob = require('fast-glob');
|
7 |
|
8 | const rootDir = process.cwd();
|
9 |
|
10 | function getPackageJson(dir) {
|
11 | const packageJsonFile = path.resolve(dir, './package.json');
|
12 | if (!fs.existsSync(packageJsonFile)) { return; }
|
13 | return require(packageJsonFile);
|
14 | }
|
15 |
|
16 | function createWatcher(package, packageRootDir, isWatching) {
|
17 | return new Promise(resolve => {
|
18 | let isReady = false;
|
19 | const packageJson = getPackageJson(packageRootDir);
|
20 | if (!packageJson) { logError(`Unable to find the "package.json" file for "${package}".`); return; }
|
21 | const localRootDirsPattern = `${path.join(rootDir, './node_modules')}/**/${package}`.replace(/\\/g, '/');
|
22 | const localRootDirs = glob.sync(localRootDirsPattern, { absolute: true, onlyDirectories: true });
|
23 |
|
24 | const rootFiles = packageJson.files || ['dist'];
|
25 | const mandatoryFiles = [
|
26 | 'package.json',
|
27 | 'license.*',
|
28 | packageJson.main || '',
|
29 | ];
|
30 |
|
31 | const watchedItems = rootFiles.concat(mandatoryFiles)
|
32 | .filter(item => item != null)
|
33 | .map(file => path.join(packageRootDir, file));
|
34 |
|
35 | const watcher = chokidar.watch(watchedItems, {
|
36 | awaitWriteFinish: true,
|
37 | });
|
38 |
|
39 | const copyFile = file => {
|
40 | const relativeFile = path.relative(packageRootDir, file);
|
41 | localRootDirs.forEach(localRootDir => {
|
42 | const destFile = path.join(localRootDir, relativeFile);
|
43 | const destPath = path.dirname(destFile);
|
44 | if (!fs.existsSync(destPath)) { fs.mkdirSync(destPath); }
|
45 | if (fs.existsSync(destFile) && fs.statSync(destFile).mtime >= fs.statSync(file).mtime) { return; }
|
46 | fs.copyFileSync(file, destFile);
|
47 | });
|
48 | if (isReady) { logInfo(`\t${package}: Copied file "${relativeFile}"`); }
|
49 | };
|
50 |
|
51 | const removeFile = file => {
|
52 | const relativeFile = path.relative(packageRootDir, file);
|
53 | localRootDirs.forEach(localRootDir => {
|
54 | const destFile = path.join(localRootDir, relativeFile);
|
55 | if (!fs.existsSync(destFile)) { return; }
|
56 | fs.unlinkSync(destFile);
|
57 | });
|
58 | if (isReady) { logInfo(`\t${package}: Removed file "${relativeFile}"`); }
|
59 | };
|
60 |
|
61 | logInfo(`\t${isWatching ? 'Watching' : 'Copying'} files for package "${package}"`);
|
62 | watcher
|
63 | .on('add', copyFile)
|
64 | .on('change', copyFile)
|
65 | .on('unlink', removeFile)
|
66 | .on('ready', () => {
|
67 | isReady = true;
|
68 | resolve(watcher);
|
69 | });
|
70 | });
|
71 | }
|
72 |
|
73 | function stopWatcher(watcher) {
|
74 | if (!watcher) { return; }
|
75 | watcher.close();
|
76 | }
|
77 |
|
78 | module.exports = async (shouldWatchFiles) => {
|
79 | logInfo('Pulling in dependencies for this package...');
|
80 | const packageJson = getPackageJson(rootDir);
|
81 | if (!packageJson) { logError('Unable to find "package.json" for this package.'); return; }
|
82 | if (typeof (packageJson.pull) != 'object') { logError('There are no packages to pull for this package.'); return; }
|
83 | const watchers = await Promise.all(Object.keys(packageJson.pull).map(key => createWatcher(key, packageJson.pull[key], shouldWatchFiles)));
|
84 | if (shouldWatchFiles && watchers.every(watcher => watcher != null)) { await query('Press enter to stop...\n'); }
|
85 | watchers.map(stopWatcher);
|
86 | };
|