@alexaegis/turbowatch 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +106 -0
- package/index.d.ts +2 -0
- package/index.js +106 -0
- package/index.spec.d.ts +2 -0
- package/index.spec.d.ts.map +1 -0
- package/internal/watch-local-node-modules.d.ts +5 -0
- package/internal/watch-local-node-modules.options.d.ts +69 -0
- package/license +21 -0
- package/local-node-modules.cjs +9 -0
- package/local-node-modules.d.ts +1 -0
- package/local-node-modules.js +9 -0
- package/package.json +96 -0
- package/readme.md +97 -0
package/index.cjs
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@alexaegis/common");
|
|
4
|
+
const workspaceTools = require("@alexaegis/workspace-tools");
|
|
5
|
+
const node_child_process = require("node:child_process");
|
|
6
|
+
const node_path = require("node:path");
|
|
7
|
+
const fs = require("@alexaegis/fs");
|
|
8
|
+
const normalizeTurbowatchLocalNodeModulesOptions = (options) => {
|
|
9
|
+
return {
|
|
10
|
+
...fs.normalizeCwdOption(options),
|
|
11
|
+
deep: options?.deep ?? true,
|
|
12
|
+
useGitIgnore: options?.useGitIgnore ?? false,
|
|
13
|
+
logChangedFiles: options?.logChangedFiles ?? false,
|
|
14
|
+
buildDependenciesScript: options?.buildDependenciesScript ?? "build:dependencies",
|
|
15
|
+
packageManagerCommand: options?.packageManagerCommand ?? "pnpm",
|
|
16
|
+
onFirstBuild: options?.onFirstBuild,
|
|
17
|
+
devScript: options?.devScript ?? "dev_"
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const turbowatchLocalNodeModules = async (rawOptions) => {
|
|
21
|
+
const options = normalizeTurbowatchLocalNodeModulesOptions(rawOptions);
|
|
22
|
+
console.log("turbowatch started in", options.cwd);
|
|
23
|
+
const currentPackagePath = workspaceTools.getCurrentPackageRoot(options.cwd);
|
|
24
|
+
if (!currentPackagePath) {
|
|
25
|
+
throw new Error("Not in a package!");
|
|
26
|
+
}
|
|
27
|
+
const currentPackagesNodeModulesPath = node_path.join(currentPackagePath, workspaceTools.NODE_MODULES_DIRECTORY_NAME);
|
|
28
|
+
const workspacePackages = await workspaceTools.collectWorkspacePackages({
|
|
29
|
+
...options,
|
|
30
|
+
skipWorkspaceRoot: true
|
|
31
|
+
});
|
|
32
|
+
const doNotMatchPackageJson = ["not", ["match", "package.json", "basename"]];
|
|
33
|
+
const matchInLocalPackageDirectories = [
|
|
34
|
+
"anyof",
|
|
35
|
+
...workspacePackages.map((workspacePackage) => workspacePackage.packageJson.name).filter(common.isNotNullish).map((packageName) => ["dirname", packageName])
|
|
36
|
+
];
|
|
37
|
+
const commonIgnoredDirs = [
|
|
38
|
+
["dirname", "dist"],
|
|
39
|
+
["dirname", ".turbo"],
|
|
40
|
+
["dirname", ".vercel"],
|
|
41
|
+
["dirname", ".cache"],
|
|
42
|
+
["dirname", "coverage"],
|
|
43
|
+
["dirname", "build"],
|
|
44
|
+
["match", "vite(st)?.config.*"]
|
|
45
|
+
];
|
|
46
|
+
if (!options.deep) {
|
|
47
|
+
commonIgnoredDirs.push(["dirname", "node_modules"]);
|
|
48
|
+
}
|
|
49
|
+
const doNotMatchCommonOutputs = ["not", ["anyof", ...commonIgnoredDirs]];
|
|
50
|
+
const watchExpression = [
|
|
51
|
+
"allof",
|
|
52
|
+
matchInLocalPackageDirectories,
|
|
53
|
+
doNotMatchCommonOutputs,
|
|
54
|
+
doNotMatchPackageJson
|
|
55
|
+
];
|
|
56
|
+
if (options.useGitIgnore) {
|
|
57
|
+
let ignoreEntries = await workspaceTools.collectIgnoreEntries(options);
|
|
58
|
+
if (options.deep) {
|
|
59
|
+
ignoreEntries = ignoreEntries.filter(
|
|
60
|
+
(entry) => !entry.includes(workspaceTools.NODE_MODULES_DIRECTORY_NAME)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const ignoreMatchEntries = ignoreEntries.map((ignoreEntry) => [
|
|
64
|
+
"match",
|
|
65
|
+
ignoreEntry
|
|
66
|
+
]);
|
|
67
|
+
const doNotMatchIgnored = ["not", ["anyof", ...ignoreMatchEntries]];
|
|
68
|
+
watchExpression.push(doNotMatchIgnored);
|
|
69
|
+
}
|
|
70
|
+
let changeCount = 0;
|
|
71
|
+
const startCommand = () => {
|
|
72
|
+
return node_child_process.spawn(options.packageManagerCommand, ["run", options.devScript], {
|
|
73
|
+
stdio: "inherit"
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
let spawnedOnFirstBuild;
|
|
77
|
+
return {
|
|
78
|
+
project: currentPackagesNodeModulesPath,
|
|
79
|
+
debounce: { wait: 50 },
|
|
80
|
+
triggers: [
|
|
81
|
+
{
|
|
82
|
+
expression: watchExpression,
|
|
83
|
+
name: "build",
|
|
84
|
+
retry: { retries: 0 },
|
|
85
|
+
onChange: async ({ spawn: spawn2, files }) => {
|
|
86
|
+
if (options.logChangedFiles) {
|
|
87
|
+
console.log("changed files:", files);
|
|
88
|
+
}
|
|
89
|
+
await spawn2`${options.packageManagerCommand} run ${options.buildDependenciesScript}`;
|
|
90
|
+
if (changeCount < 1) {
|
|
91
|
+
spawnedOnFirstBuild = options.onFirstBuild ? options.onFirstBuild() : startCommand();
|
|
92
|
+
}
|
|
93
|
+
changeCount++;
|
|
94
|
+
},
|
|
95
|
+
onTeardown: async () => {
|
|
96
|
+
if (spawnedOnFirstBuild) {
|
|
97
|
+
spawnedOnFirstBuild.kill();
|
|
98
|
+
}
|
|
99
|
+
await common.noopAsync();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
exports.normalizeTurbowatchLocalNodeModulesOptions = normalizeTurbowatchLocalNodeModulesOptions;
|
|
106
|
+
exports.turbowatchLocalNodeModules = turbowatchLocalNodeModules;
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { isNotNullish, noopAsync } from "@alexaegis/common";
|
|
2
|
+
import { getCurrentPackageRoot, NODE_MODULES_DIRECTORY_NAME, collectWorkspacePackages, collectIgnoreEntries } from "@alexaegis/workspace-tools";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { normalizeCwdOption } from "@alexaegis/fs";
|
|
6
|
+
const normalizeTurbowatchLocalNodeModulesOptions = (options) => {
|
|
7
|
+
return {
|
|
8
|
+
...normalizeCwdOption(options),
|
|
9
|
+
deep: options?.deep ?? true,
|
|
10
|
+
useGitIgnore: options?.useGitIgnore ?? false,
|
|
11
|
+
logChangedFiles: options?.logChangedFiles ?? false,
|
|
12
|
+
buildDependenciesScript: options?.buildDependenciesScript ?? "build:dependencies",
|
|
13
|
+
packageManagerCommand: options?.packageManagerCommand ?? "pnpm",
|
|
14
|
+
onFirstBuild: options?.onFirstBuild,
|
|
15
|
+
devScript: options?.devScript ?? "dev_"
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const turbowatchLocalNodeModules = async (rawOptions) => {
|
|
19
|
+
const options = normalizeTurbowatchLocalNodeModulesOptions(rawOptions);
|
|
20
|
+
console.log("turbowatch started in", options.cwd);
|
|
21
|
+
const currentPackagePath = getCurrentPackageRoot(options.cwd);
|
|
22
|
+
if (!currentPackagePath) {
|
|
23
|
+
throw new Error("Not in a package!");
|
|
24
|
+
}
|
|
25
|
+
const currentPackagesNodeModulesPath = join(currentPackagePath, NODE_MODULES_DIRECTORY_NAME);
|
|
26
|
+
const workspacePackages = await collectWorkspacePackages({
|
|
27
|
+
...options,
|
|
28
|
+
skipWorkspaceRoot: true
|
|
29
|
+
});
|
|
30
|
+
const doNotMatchPackageJson = ["not", ["match", "package.json", "basename"]];
|
|
31
|
+
const matchInLocalPackageDirectories = [
|
|
32
|
+
"anyof",
|
|
33
|
+
...workspacePackages.map((workspacePackage) => workspacePackage.packageJson.name).filter(isNotNullish).map((packageName) => ["dirname", packageName])
|
|
34
|
+
];
|
|
35
|
+
const commonIgnoredDirs = [
|
|
36
|
+
["dirname", "dist"],
|
|
37
|
+
["dirname", ".turbo"],
|
|
38
|
+
["dirname", ".vercel"],
|
|
39
|
+
["dirname", ".cache"],
|
|
40
|
+
["dirname", "coverage"],
|
|
41
|
+
["dirname", "build"],
|
|
42
|
+
["match", "vite(st)?.config.*"]
|
|
43
|
+
];
|
|
44
|
+
if (!options.deep) {
|
|
45
|
+
commonIgnoredDirs.push(["dirname", "node_modules"]);
|
|
46
|
+
}
|
|
47
|
+
const doNotMatchCommonOutputs = ["not", ["anyof", ...commonIgnoredDirs]];
|
|
48
|
+
const watchExpression = [
|
|
49
|
+
"allof",
|
|
50
|
+
matchInLocalPackageDirectories,
|
|
51
|
+
doNotMatchCommonOutputs,
|
|
52
|
+
doNotMatchPackageJson
|
|
53
|
+
];
|
|
54
|
+
if (options.useGitIgnore) {
|
|
55
|
+
let ignoreEntries = await collectIgnoreEntries(options);
|
|
56
|
+
if (options.deep) {
|
|
57
|
+
ignoreEntries = ignoreEntries.filter(
|
|
58
|
+
(entry) => !entry.includes(NODE_MODULES_DIRECTORY_NAME)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const ignoreMatchEntries = ignoreEntries.map((ignoreEntry) => [
|
|
62
|
+
"match",
|
|
63
|
+
ignoreEntry
|
|
64
|
+
]);
|
|
65
|
+
const doNotMatchIgnored = ["not", ["anyof", ...ignoreMatchEntries]];
|
|
66
|
+
watchExpression.push(doNotMatchIgnored);
|
|
67
|
+
}
|
|
68
|
+
let changeCount = 0;
|
|
69
|
+
const startCommand = () => {
|
|
70
|
+
return spawn(options.packageManagerCommand, ["run", options.devScript], {
|
|
71
|
+
stdio: "inherit"
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
let spawnedOnFirstBuild;
|
|
75
|
+
return {
|
|
76
|
+
project: currentPackagesNodeModulesPath,
|
|
77
|
+
debounce: { wait: 50 },
|
|
78
|
+
triggers: [
|
|
79
|
+
{
|
|
80
|
+
expression: watchExpression,
|
|
81
|
+
name: "build",
|
|
82
|
+
retry: { retries: 0 },
|
|
83
|
+
onChange: async ({ spawn: spawn2, files }) => {
|
|
84
|
+
if (options.logChangedFiles) {
|
|
85
|
+
console.log("changed files:", files);
|
|
86
|
+
}
|
|
87
|
+
await spawn2`${options.packageManagerCommand} run ${options.buildDependenciesScript}`;
|
|
88
|
+
if (changeCount < 1) {
|
|
89
|
+
spawnedOnFirstBuild = options.onFirstBuild ? options.onFirstBuild() : startCommand();
|
|
90
|
+
}
|
|
91
|
+
changeCount++;
|
|
92
|
+
},
|
|
93
|
+
onTeardown: async () => {
|
|
94
|
+
if (spawnedOnFirstBuild) {
|
|
95
|
+
spawnedOnFirstBuild.kill();
|
|
96
|
+
}
|
|
97
|
+
await noopAsync();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
export {
|
|
104
|
+
normalizeTurbowatchLocalNodeModulesOptions,
|
|
105
|
+
turbowatchLocalNodeModules
|
|
106
|
+
};
|
package/index.spec.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.d.ts","sourceRoot":"","sources":["../src/index.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type TurbowatchLocalNodeModulesOptions } from './watch-local-node-modules.options.js';
|
|
2
|
+
/**
|
|
3
|
+
* how about relying on CWD, and do the whole thing from a package?
|
|
4
|
+
*/
|
|
5
|
+
export declare const turbowatchLocalNodeModules: (rawOptions?: TurbowatchLocalNodeModulesOptions) => Promise<Parameters<typeof import('turbowatch').watch>[0]>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import type { Defined } from '@alexaegis/common';
|
|
3
|
+
import { type CwdOption } from '@alexaegis/fs';
|
|
4
|
+
import type { ChildProcess } from 'node:child_process';
|
|
5
|
+
export interface TurbowatchLocalNodeModulesOptions extends CwdOption {
|
|
6
|
+
/**
|
|
7
|
+
* If true, it will make sure ignore statements do not contain node_modules
|
|
8
|
+
* so the watcher can watch the entire dependency tree.
|
|
9
|
+
*
|
|
10
|
+
* If false deeper node_modules will be ignored.
|
|
11
|
+
*
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
deep?: boolean | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* If the default ignored files like
|
|
17
|
+
* - 'dist'
|
|
18
|
+
* - '.turbo'
|
|
19
|
+
* - '.vercel'
|
|
20
|
+
* - '.cache'
|
|
21
|
+
* - 'coverage'
|
|
22
|
+
* - 'build'
|
|
23
|
+
*
|
|
24
|
+
* Does not suffice, you can enable this and then it will read all the
|
|
25
|
+
* .gitignore files up your project root and include those too in the do
|
|
26
|
+
* not watch list. This could potentially ignore more than you actually
|
|
27
|
+
* want though!
|
|
28
|
+
*
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
useGitIgnore?: boolean | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Log out changed files on every change. Useful for debugging if you
|
|
34
|
+
* notice builds are getting triggered over and over again.
|
|
35
|
+
*
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
logChangedFiles?: boolean | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* The command used to build the dependencies of this package.
|
|
41
|
+
*
|
|
42
|
+
* @default 'build:dependencies'
|
|
43
|
+
*/
|
|
44
|
+
buildDependenciesScript?: string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Which package manager to invoke when running buildDependenciesScript
|
|
47
|
+
*
|
|
48
|
+
* @default 'pnpm'
|
|
49
|
+
*/
|
|
50
|
+
packageManagerCommand?: string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Called the first time buildDependenciesScript finished
|
|
53
|
+
* You can use this to start your app if the way devScript doesn't suffice.
|
|
54
|
+
* If this is defined, devScript will not be used!
|
|
55
|
+
*
|
|
56
|
+
* It can be async but it won't be awaited!
|
|
57
|
+
*/
|
|
58
|
+
onFirstBuild?: (() => ChildProcess | undefined) | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* What package.json script should be started once buildDependenciesScript
|
|
61
|
+
* is first finished. By default it's `dev_` with an underscore at the
|
|
62
|
+
* end as this turbowatch call should be named `dev`
|
|
63
|
+
*
|
|
64
|
+
* @default 'dev_'
|
|
65
|
+
*/
|
|
66
|
+
devScript?: string | undefined;
|
|
67
|
+
}
|
|
68
|
+
export type NormalizedTurbowatchLocalNodeModulesOptions = Defined<Omit<TurbowatchLocalNodeModulesOptions, 'onFirstBuild'>> & Pick<TurbowatchLocalNodeModulesOptions, 'onFirstBuild'>;
|
|
69
|
+
export declare const normalizeTurbowatchLocalNodeModulesOptions: (options?: TurbowatchLocalNodeModulesOptions) => NormalizedTurbowatchLocalNodeModulesOptions;
|
package/license
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Győri Sándor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const index = require("./index.cjs");
|
|
4
|
+
require("@alexaegis/common");
|
|
5
|
+
require("@alexaegis/workspace-tools");
|
|
6
|
+
require("node:child_process");
|
|
7
|
+
require("node:path");
|
|
8
|
+
require("@alexaegis/fs");
|
|
9
|
+
exports.turbowatchLocalNodeModules = index.turbowatchLocalNodeModules;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './internal/watch-local-node-modules.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alexaegis/turbowatch",
|
|
3
|
+
"description": "A turbowatch configuration to watch local dependencies through node_modules",
|
|
4
|
+
"version": "0.7.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"archetype": {
|
|
8
|
+
"platform": "node",
|
|
9
|
+
"language": "ts",
|
|
10
|
+
"kind": "lib"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"managed-by-autotool",
|
|
14
|
+
"turbowatch"
|
|
15
|
+
],
|
|
16
|
+
"author": {
|
|
17
|
+
"email": "alexaegis@gmail.com",
|
|
18
|
+
"name": "Alex Aegis",
|
|
19
|
+
"url": "https://github.com/AlexAegis"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/AlexAegis/js-tooling",
|
|
22
|
+
"repository": {
|
|
23
|
+
"url": "git+https://github.com/AlexAegis/js-tooling",
|
|
24
|
+
"type": "git",
|
|
25
|
+
"directory": "packages/turbowatch"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"email": "alexaegis@gmail.com",
|
|
29
|
+
"url": "https://github.com/AlexAegis/js-tooling/issues"
|
|
30
|
+
},
|
|
31
|
+
"type": "module",
|
|
32
|
+
"config": {
|
|
33
|
+
"engine-strict": true
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.10.0",
|
|
40
|
+
"pnpm": ">=8.0.0"
|
|
41
|
+
},
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./index.d.ts",
|
|
45
|
+
"import": "./index.js",
|
|
46
|
+
"require": "./index.cjs",
|
|
47
|
+
"default": "./index.js"
|
|
48
|
+
},
|
|
49
|
+
"./local-node-modules": {
|
|
50
|
+
"types": "./local-node-modules.d.ts",
|
|
51
|
+
"import": "./local-node-modules.js",
|
|
52
|
+
"require": "./local-node-modules.cjs",
|
|
53
|
+
"default": "./local-node-modules.js"
|
|
54
|
+
},
|
|
55
|
+
"./readme": "./readme.md"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@alexaegis/common": "^0.6.1",
|
|
59
|
+
"@alexaegis/fs": "^0.6.1",
|
|
60
|
+
"@alexaegis/workspace-tools": "^0.6.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@alexaegis/eslint-config-vitest": "^0.7.0",
|
|
64
|
+
"@alexaegis/ts": "^0.7.0",
|
|
65
|
+
"@alexaegis/vite": "^0.7.0",
|
|
66
|
+
"@alexaegis/vitest": "^0.7.0",
|
|
67
|
+
"@types/node": "^20.4.6",
|
|
68
|
+
"publint": "^0.2.0",
|
|
69
|
+
"turbowatch": "^2.29.4",
|
|
70
|
+
"typescript": "^5.1.6",
|
|
71
|
+
"vite": "^4.4.8",
|
|
72
|
+
"vitest": "^0.34.1"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "turbo run build-lib_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
76
|
+
"build-lib_": "vite build",
|
|
77
|
+
"lint:depcheck": "turbo run lint:depcheck_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
78
|
+
"lint:depcheck_": "depcheck",
|
|
79
|
+
"lint:es": "turbo run lint:es_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
80
|
+
"lint:es_": "eslint --max-warnings=0 --fix --no-error-on-unmatched-pattern .",
|
|
81
|
+
"lint:format": "turbo run lint:format_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
82
|
+
"lint:format_": "prettier --cache-location .cache/prettier --plugin prettier-plugin-svelte --plugin prettier-plugin-tailwindcss --check .",
|
|
83
|
+
"lint:md": "turbo run lint:md_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
84
|
+
"lint:md_": "remark --frail --no-stdout --silently-ignore .",
|
|
85
|
+
"lint:tsc": "turbo run lint:tsc_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
86
|
+
"lint:tsc_": "tsc --noEmit",
|
|
87
|
+
"publint": "BUILD_REASON='publish' turbo run publint_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
88
|
+
"publint_": "publint dist",
|
|
89
|
+
"all": "BUILD_REASON='publish' turbo run all_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
90
|
+
"format": "turbo run format_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
91
|
+
"format_": "prettier --cache-location .cache/prettier --plugin prettier-plugin-svelte --plugin prettier-plugin-tailwindcss --write .",
|
|
92
|
+
"test": "turbo run test_ --concurrency 16 --cache-dir .cache/turbo --filter @alexaegis/turbowatch",
|
|
93
|
+
"test_": "vitest --passWithNoTests --coverage --run",
|
|
94
|
+
"test:watch": "vitest --passWithNoTests --coverage"
|
|
95
|
+
}
|
|
96
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# [@alexaegis/turbowatch](https://github.com/AlexAegis/js-tooling/tree/master/packages/turbowatch)
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@alexaegis/turbowatch)
|
|
4
|
+
[](https://github.com/AlexAegis/js-tooling/actions/workflows/cicd.yml)
|
|
5
|
+
[](https://www.codacy.com/gh/AlexAegis/js-tooling/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AlexAegis/js-tooling&utm_campaign=Badge_Grade)
|
|
6
|
+
|
|
7
|
+
Holds a configuration for [`turbowatch`](https://github.com/gajus/turbowatch) to
|
|
8
|
+
watch local dependencies changing through `node_modules`.
|
|
9
|
+
|
|
10
|
+
It will first run `buildDependenciesScript`, then after that's finished the
|
|
11
|
+
first time, it will run `devScript`.
|
|
12
|
+
|
|
13
|
+
## Turbowatch configuration example
|
|
14
|
+
|
|
15
|
+
> `apps/my-app/dev.js`
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { turbowatchLocalNodeModules } from '@alexaegis/turbowatch';
|
|
19
|
+
import { watch } from 'turbowatch';
|
|
20
|
+
|
|
21
|
+
void (async () => {
|
|
22
|
+
await watch(
|
|
23
|
+
await turbowatchLocalNodeModules({
|
|
24
|
+
buildDependenciesScript: 'build:dependencies',
|
|
25
|
+
devScript: 'dev_',
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
28
|
+
})();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> It's using an IIFE because turbowatch does not understand top-level awaits
|
|
32
|
+
|
|
33
|
+
## Turbo example
|
|
34
|
+
|
|
35
|
+
When using with turbo, it's important that `turbo` cannot invoke itself. (In
|
|
36
|
+
older versions of turbo it was allowed but worked wonky, since then it's
|
|
37
|
+
actively prohibited) So when starting your app, start the invokation from
|
|
38
|
+
`turbowatch`
|
|
39
|
+
|
|
40
|
+
> `apps/my-app/package.json`
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build:dependencies": "turbo run build-lib_ --filter my-app",
|
|
46
|
+
"dev": "turbowatch dev.js",
|
|
47
|
+
"dev_": "vite"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
And then the interesting part of a `turbo.json`. For the `turbowatch` setup
|
|
53
|
+
specifically, only the `build-lib_` task is used. Since `turbowatch` through the
|
|
54
|
+
`"build:dependencies"` npm script already takes care of building the
|
|
55
|
+
dependencies of the app, there's no need to start the app through `turbo`. For a
|
|
56
|
+
more comprehensive `turbo.json` file, check the one in this package's
|
|
57
|
+
repository.
|
|
58
|
+
|
|
59
|
+
> `turbo.json`
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"$schema": "https://turborepo.org/schema.json",
|
|
64
|
+
"pipeline": {
|
|
65
|
+
"build-app_": {
|
|
66
|
+
"dependsOn": ["^build-lib_"],
|
|
67
|
+
"outputs": ["dist/**"]
|
|
68
|
+
},
|
|
69
|
+
"build-lib_": {
|
|
70
|
+
"dependsOn": ["^build-lib_"],
|
|
71
|
+
"outputs": ["dist/**"]
|
|
72
|
+
},
|
|
73
|
+
"dev_": {
|
|
74
|
+
"cache": false,
|
|
75
|
+
"dependsOn": ["^build-lib_"],
|
|
76
|
+
"persistent": true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
> I'm using separate build tasks for apps and libs, so I can skip building the
|
|
83
|
+
> app when I'm running `turbo run build-lib_ --filter my-app`, if they'd use the
|
|
84
|
+
> same script, the app would get built every time a dependency changes.
|
|
85
|
+
|
|
86
|
+
You then start your app using the `"dev"` script. You can put one in your root
|
|
87
|
+
`package.json` too, but do not forget that you can't use `turbo` for this!
|
|
88
|
+
|
|
89
|
+
> `package.json`
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"script": {
|
|
94
|
+
"dev": "pnpm run --dir apps/my-app dev"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|