@servicetitan/startup 27.3.0 → 27.4.0-canary.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/dist/cli/commands/get-branch-configs.d.ts +4 -0
- package/dist/cli/commands/get-branch-configs.d.ts.map +1 -0
- package/dist/cli/commands/get-branch-configs.js +13 -0
- package/dist/cli/commands/get-branch-configs.js.map +1 -0
- package/dist/cli/commands/get-command.d.ts.map +1 -1
- package/dist/cli/commands/get-command.js +4 -2
- package/dist/cli/commands/get-command.js.map +1 -1
- package/dist/cli/commands/init.d.ts +0 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +39 -9
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mfe-package-clean.d.ts +13 -0
- package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -0
- package/dist/cli/commands/mfe-package-clean.js +113 -0
- package/dist/cli/commands/mfe-package-clean.js.map +1 -0
- package/dist/cli/commands/mfe-package-publish.d.ts +20 -0
- package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -0
- package/dist/cli/commands/mfe-package-publish.js +153 -0
- package/dist/cli/commands/mfe-package-publish.js.map +1 -0
- package/dist/cli/commands/mfe-publish.d.ts +4 -29
- package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
- package/dist/cli/commands/mfe-publish.js +1 -213
- package/dist/cli/commands/mfe-publish.js.map +1 -1
- package/dist/cli/utils/assets-copy.d.ts.map +1 -1
- package/dist/cli/utils/assets-copy.js +3 -3
- package/dist/cli/utils/assets-copy.js.map +1 -1
- package/dist/cli/utils/bundle.d.ts.map +1 -1
- package/dist/cli/utils/bundle.js +10 -11
- package/dist/cli/utils/bundle.js.map +1 -1
- package/dist/cli/utils/cli-os.d.ts +9 -2
- package/dist/cli/utils/cli-os.d.ts.map +1 -1
- package/dist/cli/utils/cli-os.js +16 -8
- package/dist/cli/utils/cli-os.js.map +1 -1
- package/dist/cli/utils/styles-copy.d.ts.map +1 -1
- package/dist/cli/utils/styles-copy.js +3 -3
- package/dist/cli/utils/styles-copy.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/get-configuration.d.ts +2 -1
- package/dist/utils/get-configuration.d.ts.map +1 -1
- package/dist/utils/get-configuration.js +5 -0
- package/dist/utils/get-configuration.js.map +1 -1
- package/dist/utils/get-exposed-dependencies.d.ts +7 -0
- package/dist/utils/get-exposed-dependencies.d.ts.map +1 -0
- package/dist/utils/get-exposed-dependencies.js +10 -0
- package/dist/utils/get-exposed-dependencies.js.map +1 -0
- package/dist/utils/get-folders.js +2 -2
- package/dist/utils/get-folders.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
- package/dist/webpack/configs/dev-server-config.js +4 -1
- package/dist/webpack/configs/dev-server-config.js.map +1 -1
- package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.d.ts.map +1 -1
- package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.js +2 -9
- package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.js.map +1 -1
- package/dist/webpack/configs/plugins/virtual-modules-plugin.d.ts.map +1 -1
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js +15 -5
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
- package/dist/webpack/configs/types.d.ts +16 -0
- package/dist/webpack/configs/types.d.ts.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.js +3 -3
- package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
- package/package.json +9 -15
- package/src/cli/commands/__tests__/init.test.ts +108 -28
- package/src/cli/commands/__tests__/mfe-package-clean.test.ts +1 -1
- package/src/cli/commands/__tests__/mfe-package-publish.test.ts +77 -7
- package/src/cli/commands/get-branch-configs.ts +8 -0
- package/src/cli/commands/get-command.ts +3 -1
- package/src/cli/commands/init.ts +40 -10
- package/src/cli/commands/mfe-package-clean.ts +132 -0
- package/src/cli/commands/mfe-package-publish.ts +189 -0
- package/src/cli/commands/mfe-publish.ts +5 -294
- package/src/cli/utils/__tests__/assets-copy.test.ts +3 -7
- package/src/cli/utils/__tests__/bundle.test.ts +45 -6
- package/src/cli/utils/__tests__/cli-os.test.ts +41 -6
- package/src/cli/utils/__tests__/styles-copy.test.ts +3 -7
- package/src/cli/utils/assets-copy.ts +3 -3
- package/src/cli/utils/bundle.ts +14 -20
- package/src/cli/utils/cli-os.ts +20 -8
- package/src/cli/utils/styles-copy.ts +3 -3
- package/src/index.ts +2 -0
- package/src/utils/__tests__/get-configuration.test.ts +6 -0
- package/src/utils/get-configuration.ts +6 -1
- package/src/utils/get-exposed-dependencies.ts +19 -0
- package/src/utils/get-folders.ts +1 -1
- package/src/utils/index.ts +1 -0
- package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +47 -13
- package/src/webpack/__tests__/create-webpack-config.test.ts +10 -0
- package/src/webpack/configs/dev-server-config.ts +7 -2
- package/src/webpack/configs/plugins/define-exposed-dependencies-plugin.ts +6 -16
- package/src/webpack/configs/plugins/virtual-modules-plugin.ts +17 -5
- package/src/webpack/configs/types.ts +19 -0
- package/src/webpack/configs/utils/generate-metadata.ts +5 -5
- package/template/.eslintrc.json +0 -3
- package/template/.gitignore +0 -21
- package/template/.npmrc +0 -3
- package/template/.prettierrc +0 -9
- package/template/.stylelintignore +0 -1
- package/template/.stylelintrc.json +0 -3
- package/template/.vscode/extensions.json +0 -18
- package/template/.vscode/settings.json +0 -4
- package/template/lerna.json +0 -4
- package/template/package.json +0 -32
- package/template/packages/application/package.json +0 -35
- package/template/packages/application/src/__tests__/app.test.tsx +0 -33
- package/template/packages/application/src/app.css +0 -3
- package/template/packages/application/src/app.tsx +0 -45
- package/template/packages/application/src/design-system.css +0 -3
- package/template/packages/application/src/index.tsx +0 -8
- package/template/packages/application/src/main-page.tsx +0 -5
- package/template/packages/application/src/second-page.tsx +0 -5
- package/template/packages/application/tsconfig.json +0 -13
- package/template/packages/feature-a/package.json +0 -19
- package/template/packages/feature-a/src/index.ts +0 -0
- package/template/packages/feature-a/tsconfig.json +0 -9
- package/template/packages/feature-b/package.json +0 -19
- package/template/packages/feature-b/src/index.ts +0 -0
- package/template/packages/feature-b/tsconfig.json +0 -9
- package/template/packages/feature-c/package.json +0 -19
- package/template/packages/feature-c/src/index.ts +0 -0
- package/template/packages/feature-c/tsconfig.json +0 -9
- package/template/setupTests.ts +0 -27
- package/template/tsconfig.test.json +0 -5
- package/template-react18/packages/application/package.json +0 -35
- package/template-react18/packages/application/src/index.tsx +0 -9
- package/template-react18/packages/feature-a/package.json +0 -19
- package/template-react18/packages/feature-b/package.json +0 -19
- package/template-react18/packages/feature-c/package.json +0 -19
- package/tsconfig.json +0 -13
|
@@ -5,10 +5,7 @@ import { assetsCopy, assetsCopyWatch } from '../assets-copy';
|
|
|
5
5
|
import { assetExtensions } from '../index';
|
|
6
6
|
|
|
7
7
|
jest.mock('cpx2', () => ({
|
|
8
|
-
|
|
9
|
-
const callback = args[args.length - 1];
|
|
10
|
-
callback(null);
|
|
11
|
-
}),
|
|
8
|
+
copySync: jest.fn(),
|
|
12
9
|
watch: jest.fn(() => ({ on: (_eventName: string, listener: Function) => listener() })),
|
|
13
10
|
}));
|
|
14
11
|
jest.mock('../../../utils', () => ({
|
|
@@ -28,10 +25,9 @@ describe('[startup] Cli Utils (Assets)', () => {
|
|
|
28
25
|
test('copies assets from source to destination', async () => {
|
|
29
26
|
await subject();
|
|
30
27
|
|
|
31
|
-
expect(cpx.
|
|
28
|
+
expect(cpx.copySync).toHaveBeenCalledWith(
|
|
32
29
|
`${source}/**/*.{${assetExtensions.join()}}`,
|
|
33
|
-
destination
|
|
34
|
-
expect.anything()
|
|
30
|
+
destination
|
|
35
31
|
);
|
|
36
32
|
});
|
|
37
33
|
});
|
|
@@ -2,7 +2,12 @@ import { fs, vol } from 'memfs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import webpack from 'webpack';
|
|
4
4
|
import WebpackDevServer from 'webpack-dev-server';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getConfiguration,
|
|
7
|
+
getFolders,
|
|
8
|
+
getPackageData,
|
|
9
|
+
loadSharedDependencies,
|
|
10
|
+
} from '../../../utils';
|
|
6
11
|
import { createWebpackConfig } from '../../../webpack';
|
|
7
12
|
import { createPackage } from '../../../__mocks__';
|
|
8
13
|
|
|
@@ -44,12 +49,12 @@ describe('[startup] Cli Utils', () => {
|
|
|
44
49
|
return expect.stringContaining(name);
|
|
45
50
|
}
|
|
46
51
|
|
|
47
|
-
function packageFS() {
|
|
48
|
-
return { 'package.json': JSON.stringify(pkg) };
|
|
52
|
+
function packageFS(configuration: ReturnType<typeof getConfiguration> = {} as any) {
|
|
53
|
+
return { 'package.json': JSON.stringify({ ...pkg, cli: configuration }) };
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
function webComponentFS() {
|
|
52
|
-
return
|
|
56
|
+
function webComponentFS(configuration: ReturnType<typeof getConfiguration> = {} as any) {
|
|
57
|
+
return packageFS({ 'web-component': true, ...configuration });
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
describe(`${bundle.name}`, () => {
|
|
@@ -287,6 +292,19 @@ describe('[startup] Cli Utils', () => {
|
|
|
287
292
|
);
|
|
288
293
|
});
|
|
289
294
|
|
|
295
|
+
describe('when webpack.devServer is set to false in package.json', () => {
|
|
296
|
+
beforeEach(() => {
|
|
297
|
+
vol.fromJSON(packageFS({ webpack: { devServer: false } } as any));
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test('runs webpack and not webpack development server', async () => {
|
|
301
|
+
await subject();
|
|
302
|
+
|
|
303
|
+
expect(webpack).toHaveBeenCalledWith(createWebpackResult);
|
|
304
|
+
expect(WebpackDevServer).not.toHaveBeenCalled();
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
290
308
|
function itUsesConfig(params: { name: string; config: () => Record<string, any> }) {
|
|
291
309
|
test(`uses ${params.name}`, async () => {
|
|
292
310
|
const { devServer, ...config } = params.config();
|
|
@@ -351,7 +369,8 @@ describe('[startup] Cli Utils', () => {
|
|
|
351
369
|
...options,
|
|
352
370
|
embed: true,
|
|
353
371
|
});
|
|
354
|
-
expect(webpack).
|
|
372
|
+
expect(webpack).toHaveBeenNthCalledWith(1, createWebpackResult);
|
|
373
|
+
expect(webpack).toHaveBeenNthCalledWith(2, createWebpackResult);
|
|
355
374
|
expect(compiler.watch).toHaveBeenCalled();
|
|
356
375
|
expect(WebpackDevServer).toHaveBeenCalledWith(
|
|
357
376
|
{ host: 'localhost', port: 8080 },
|
|
@@ -359,6 +378,26 @@ describe('[startup] Cli Utils', () => {
|
|
|
359
378
|
);
|
|
360
379
|
});
|
|
361
380
|
|
|
381
|
+
describe('when webpack.devServer is set to false in package.json', () => {
|
|
382
|
+
beforeEach(() => {
|
|
383
|
+
vol.fromJSON(webComponentFS({ webpack: { devServer: false } } as any));
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
test('runs webpack and not webpack development server', async () => {
|
|
387
|
+
const options = { name: expectPackageName() };
|
|
388
|
+
const overrides = { configuration: { mode: 'development' } };
|
|
389
|
+
|
|
390
|
+
await subject();
|
|
391
|
+
|
|
392
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(overrides, options);
|
|
393
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(overrides, {
|
|
394
|
+
...options,
|
|
395
|
+
embed: true,
|
|
396
|
+
});
|
|
397
|
+
expect(WebpackDevServer).not.toHaveBeenCalled();
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
362
401
|
function itUsesConfig(params: { name: string; config: () => Record<string, any> }) {
|
|
363
402
|
test(`uses ${params.name}`, async () => {
|
|
364
403
|
const options = { name: expectPackageName() };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execSync, spawn } from 'child_process';
|
|
2
2
|
|
|
3
3
|
import { runCommand, runCommandOutput } from '../cli-os';
|
|
4
|
+
import { log } from '../../../utils';
|
|
4
5
|
|
|
5
6
|
jest.mock('child_process', () => ({ execSync: jest.fn(), spawn: jest.fn() }));
|
|
6
7
|
jest.mock('../../../utils', () => ({ log: { info: jest.fn() } })); // suppress log output
|
|
@@ -11,6 +12,7 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
11
12
|
let childProcess: ReturnType<typeof spawn>;
|
|
12
13
|
|
|
13
14
|
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
14
16
|
exitCode = 0;
|
|
15
17
|
childProcess = {
|
|
16
18
|
stderr: { pipe: jest.fn() },
|
|
@@ -25,7 +27,7 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
25
27
|
test('runs command', () => {
|
|
26
28
|
expect(subject('foo bar')).resolves.toBe(undefined);
|
|
27
29
|
|
|
28
|
-
expect(spawn).toHaveBeenCalledWith('foo', ['bar'],
|
|
30
|
+
expect(spawn).toHaveBeenCalledWith('foo', ['bar'], {});
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
test('runs command with options', async () => {
|
|
@@ -37,7 +39,7 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
37
39
|
test('runs command array', async () => {
|
|
38
40
|
await subject(['foo', 'bar', '--baz']);
|
|
39
41
|
|
|
40
|
-
expect(spawn).toHaveBeenCalledWith('foo', ['bar', '--baz'],
|
|
42
|
+
expect(spawn).toHaveBeenCalledWith('foo', ['bar', '--baz'], {});
|
|
41
43
|
});
|
|
42
44
|
|
|
43
45
|
test("pipes stdout and stderr to parent's streams", async () => {
|
|
@@ -60,10 +62,28 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
60
62
|
expect(subject(command)).rejects.toBeUndefined();
|
|
61
63
|
})
|
|
62
64
|
);
|
|
65
|
+
|
|
66
|
+
test('logs command and exit status', async () => {
|
|
67
|
+
const logInfoSpy = jest.spyOn(log, 'info');
|
|
68
|
+
await subject('foo');
|
|
69
|
+
|
|
70
|
+
expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
|
|
71
|
+
expect(logInfoSpy).toHaveBeenCalledWith('command finished with code 0', 'foo');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('quiet option suppresses output', async () => {
|
|
75
|
+
const logInfoSpy = jest.spyOn(log, 'info');
|
|
76
|
+
await subject('foo', { quiet: true });
|
|
77
|
+
|
|
78
|
+
expect(logInfoSpy).not.toHaveBeenCalled();
|
|
79
|
+
});
|
|
63
80
|
});
|
|
64
81
|
|
|
65
82
|
describe(`${runCommandOutput.name}`, () => {
|
|
66
|
-
beforeEach(() =>
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
jest.clearAllMocks();
|
|
85
|
+
jest.mocked(execSync).mockReturnValue('');
|
|
86
|
+
});
|
|
67
87
|
|
|
68
88
|
const subject = (...args: Parameters<typeof runCommandOutput>) => runCommandOutput(...args);
|
|
69
89
|
|
|
@@ -73,7 +93,7 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
73
93
|
|
|
74
94
|
expect(subject('foo bar')).toBe(result);
|
|
75
95
|
|
|
76
|
-
expect(execSync).toHaveBeenCalledWith('foo bar',
|
|
96
|
+
expect(execSync).toHaveBeenCalledWith('foo bar', {});
|
|
77
97
|
});
|
|
78
98
|
|
|
79
99
|
test('runs command with options', () => {
|
|
@@ -85,13 +105,13 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
85
105
|
test('runs command array', () => {
|
|
86
106
|
subject(['foo', 'bar']);
|
|
87
107
|
|
|
88
|
-
expect(execSync).toHaveBeenCalledWith('foo bar',
|
|
108
|
+
expect(execSync).toHaveBeenCalledWith('foo bar', {});
|
|
89
109
|
});
|
|
90
110
|
|
|
91
111
|
test('ignores false and "" array values', () => {
|
|
92
112
|
subject(['', 'foo', false, '', 'bar', false]);
|
|
93
113
|
|
|
94
|
-
expect(execSync).toHaveBeenCalledWith('foo bar',
|
|
114
|
+
expect(execSync).toHaveBeenCalledWith('foo bar', {});
|
|
95
115
|
});
|
|
96
116
|
|
|
97
117
|
['', [], ['']].forEach(command =>
|
|
@@ -99,5 +119,20 @@ describe('[startup] Cli Utils (OS)', () => {
|
|
|
99
119
|
expect(() => subject(command)).toThrow();
|
|
100
120
|
})
|
|
101
121
|
);
|
|
122
|
+
|
|
123
|
+
test('logs command and result', () => {
|
|
124
|
+
const logInfoSpy = jest.spyOn(log, 'info');
|
|
125
|
+
subject('foo');
|
|
126
|
+
|
|
127
|
+
expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
|
|
128
|
+
expect(logInfoSpy).toHaveBeenCalledWith('command finished', '');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('quiet option suppresses output', () => {
|
|
132
|
+
const logInfoSpy = jest.spyOn(log, 'info');
|
|
133
|
+
subject('foo', { quiet: true });
|
|
134
|
+
|
|
135
|
+
expect(logInfoSpy).not.toHaveBeenCalled();
|
|
136
|
+
});
|
|
102
137
|
});
|
|
103
138
|
});
|
|
@@ -5,10 +5,7 @@ import { stylesCopy, stylesCopyWatch } from '../styles-copy';
|
|
|
5
5
|
import { styleExtensions } from '../index';
|
|
6
6
|
|
|
7
7
|
jest.mock('cpx2', () => ({
|
|
8
|
-
|
|
9
|
-
const callback = args[args.length - 1];
|
|
10
|
-
callback(null);
|
|
11
|
-
}),
|
|
8
|
+
copySync: jest.fn(),
|
|
12
9
|
watch: jest.fn(() => ({ on: (_eventName: string, listener: Function) => listener() })),
|
|
13
10
|
}));
|
|
14
11
|
jest.mock('../../../utils', () => ({
|
|
@@ -28,10 +25,9 @@ describe('[startup] Cli Utils (Styles)', () => {
|
|
|
28
25
|
test('copies styles from source to destination', async () => {
|
|
29
26
|
await subject();
|
|
30
27
|
|
|
31
|
-
expect(cpx.
|
|
28
|
+
expect(cpx.copySync).toHaveBeenCalledWith(
|
|
32
29
|
`${source}/**/*.{${styleExtensions.join()}}`,
|
|
33
|
-
destination
|
|
34
|
-
expect.anything()
|
|
30
|
+
destination
|
|
35
31
|
);
|
|
36
32
|
});
|
|
37
33
|
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import cpx from 'cpx2';
|
|
2
|
-
import util from 'util';
|
|
3
2
|
|
|
4
3
|
import { getFolders, log } from '../../utils';
|
|
5
4
|
import { assetExtensions } from '.';
|
|
6
5
|
|
|
7
|
-
export
|
|
6
|
+
export function assetsCopy() {
|
|
8
7
|
const { source, destination } = getFolders();
|
|
9
8
|
|
|
10
9
|
log.info('Copying asset files...');
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
cpx.copySync(`${source}/**/*.{${assetExtensions.join()}}`, destination);
|
|
12
|
+
return Promise.resolve();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export async function assetsCopyWatch() {
|
package/src/cli/utils/bundle.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { getPortPromise } from 'portfinder';
|
|
|
6
6
|
import webpack, { Configuration } from 'webpack';
|
|
7
7
|
import WebpackDevServer from 'webpack-dev-server';
|
|
8
8
|
|
|
9
|
-
import { getPackageName, isWebComponent, log } from '../../utils';
|
|
9
|
+
import { getPackageName, isDevServerDisabled, isWebComponent, log } from '../../utils';
|
|
10
10
|
import { Overrides, createWebpackConfig } from '../../webpack';
|
|
11
11
|
|
|
12
12
|
interface Options {
|
|
@@ -62,6 +62,7 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
62
62
|
const mode = 'development';
|
|
63
63
|
const config = readWebpackConfig({ ...options, fallback: `./${webpackDevConfigFileName}` });
|
|
64
64
|
const { codeCoverage, esbuild, experimentalBundlers } = options;
|
|
65
|
+
const configOverrides = { codeCoverage, esbuild, experimentalBundlers, name };
|
|
65
66
|
|
|
66
67
|
if (isWebComponent()) {
|
|
67
68
|
const webpackConfig: Overrides = {
|
|
@@ -72,31 +73,24 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
72
73
|
return Promise.all([
|
|
73
74
|
runWatch(
|
|
74
75
|
createWebpackConfig(webpackConfig, {
|
|
75
|
-
codeCoverage,
|
|
76
76
|
embed: true,
|
|
77
|
-
|
|
78
|
-
esbuild,
|
|
79
|
-
experimentalBundlers,
|
|
80
|
-
})
|
|
81
|
-
),
|
|
82
|
-
runServe(
|
|
83
|
-
createWebpackConfig(webpackConfig, {
|
|
84
|
-
name,
|
|
85
|
-
codeCoverage,
|
|
86
|
-
esbuild,
|
|
87
|
-
experimentalBundlers,
|
|
77
|
+
...configOverrides,
|
|
88
78
|
})
|
|
89
79
|
),
|
|
80
|
+
isDevServerDisabled()
|
|
81
|
+
? runWatch(createWebpackConfig(webpackConfig, configOverrides))
|
|
82
|
+
: runServe(createWebpackConfig(webpackConfig, configOverrides)),
|
|
90
83
|
]);
|
|
91
84
|
}
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
config ??
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
86
|
+
const webpackConfig =
|
|
87
|
+
config ?? createWebpackConfig({ configuration: { mode } }, configOverrides);
|
|
88
|
+
|
|
89
|
+
if (isDevServerDisabled()) {
|
|
90
|
+
return runWatch(webpackConfig);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return runServe(webpackConfig);
|
|
100
94
|
}
|
|
101
95
|
|
|
102
96
|
function readWebpackConfig({ config, fallback }: Options & { fallback: string }) {
|
package/src/cli/utils/cli-os.ts
CHANGED
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
} from 'child_process';
|
|
7
7
|
import { log } from '../../utils';
|
|
8
8
|
|
|
9
|
+
type RunCommandOptions = SpawnOptionsWithoutStdio & { quiet?: boolean };
|
|
10
|
+
|
|
9
11
|
export const runCommand = (
|
|
10
12
|
command: string | (string | false)[],
|
|
11
|
-
|
|
13
|
+
{ quiet, ...spawnOptions }: RunCommandOptions = {}
|
|
12
14
|
): Promise<void> => {
|
|
13
15
|
return new Promise((resolve, reject) => {
|
|
14
16
|
const commandArray: string[] = Array.isArray(command)
|
|
@@ -28,15 +30,19 @@ export const runCommand = (
|
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
if (!quiet) {
|
|
34
|
+
log.info(`run command ${fullCommand}`);
|
|
35
|
+
}
|
|
32
36
|
|
|
33
|
-
const proc = spawn(commandName, commandArray,
|
|
37
|
+
const proc = spawn(commandName, commandArray, spawnOptions);
|
|
34
38
|
|
|
35
39
|
proc.stdout.pipe(process.stdout);
|
|
36
40
|
proc.stderr.pipe(process.stderr);
|
|
37
41
|
|
|
38
42
|
proc.on('exit', function (code: any) {
|
|
39
|
-
|
|
43
|
+
if (!quiet) {
|
|
44
|
+
log.info(`command finished with code ${code}`, fullCommand);
|
|
45
|
+
}
|
|
40
46
|
|
|
41
47
|
if (code) {
|
|
42
48
|
reject();
|
|
@@ -47,9 +53,11 @@ export const runCommand = (
|
|
|
47
53
|
});
|
|
48
54
|
};
|
|
49
55
|
|
|
56
|
+
type RunCommandOutputOptions = ExecSyncOptionsWithBufferEncoding & { quiet?: boolean };
|
|
57
|
+
|
|
50
58
|
export const runCommandOutput = (
|
|
51
59
|
command: string | (string | false)[],
|
|
52
|
-
|
|
60
|
+
{ quiet, ...execSyncOptions }: RunCommandOutputOptions = {}
|
|
53
61
|
): string => {
|
|
54
62
|
const commandArray: string[] = Array.isArray(command)
|
|
55
63
|
? command
|
|
@@ -66,11 +74,15 @@ export const runCommandOutput = (
|
|
|
66
74
|
throw new Error();
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
if (!quiet) {
|
|
78
|
+
log.info(`run command ${fullCommand}`);
|
|
79
|
+
}
|
|
70
80
|
|
|
71
|
-
const result = execSync(fullCommand,
|
|
81
|
+
const result = execSync(fullCommand, execSyncOptions).toString();
|
|
72
82
|
|
|
73
|
-
|
|
83
|
+
if (!quiet) {
|
|
84
|
+
log.info('command finished', result);
|
|
85
|
+
}
|
|
74
86
|
|
|
75
87
|
return result;
|
|
76
88
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import cpx from 'cpx2';
|
|
2
|
-
import util from 'util';
|
|
3
2
|
|
|
4
3
|
import { getFolders, log } from '../../utils';
|
|
5
4
|
import { styleExtensions } from '.';
|
|
6
5
|
|
|
7
|
-
export
|
|
6
|
+
export function stylesCopy() {
|
|
8
7
|
const { source, destination } = getFolders();
|
|
9
8
|
|
|
10
9
|
log.info('Copying style files...');
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
cpx.copySync(`${source}/**/*.{${styleExtensions.join()}}`, destination);
|
|
12
|
+
return Promise.resolve();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export async function stylesCopyWatch() {
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
getStylelintConfiguration,
|
|
9
9
|
isBundle,
|
|
10
10
|
isCustomStyleRules,
|
|
11
|
+
isDevServerDisabled,
|
|
11
12
|
isExposeSharedDependencies,
|
|
12
13
|
isLegacy,
|
|
13
14
|
isLegacyRoot,
|
|
@@ -193,6 +194,11 @@ describe('[startup] Utils', () => {
|
|
|
193
194
|
defaultValue: false,
|
|
194
195
|
trigger: { cli: { webpack: { 'custom-style-rules': true } } },
|
|
195
196
|
},
|
|
197
|
+
{
|
|
198
|
+
fn: isDevServerDisabled,
|
|
199
|
+
defaultValue: false,
|
|
200
|
+
trigger: { cli: { webpack: { devServer: false } } },
|
|
201
|
+
},
|
|
196
202
|
{
|
|
197
203
|
fn: isExposeSharedDependencies,
|
|
198
204
|
defaultValue: false,
|
|
@@ -30,7 +30,7 @@ export interface WebpackConfiguration
|
|
|
30
30
|
'contentBase'?: boolean | string | string[] | number; // deprecated 2024-07
|
|
31
31
|
'custom-style-rules'?: boolean;
|
|
32
32
|
'expose-shared-dependencies'?: boolean;
|
|
33
|
-
'devServer'?: WebpackDevServerConfiguration;
|
|
33
|
+
'devServer'?: false | WebpackDevServerConfiguration;
|
|
34
34
|
'disable-style-check'?: boolean;
|
|
35
35
|
'minify'?: MinifyOptions;
|
|
36
36
|
'proxy'?: WebpackDevServerConfiguration['proxy'] | string;
|
|
@@ -128,6 +128,11 @@ export function isCustomStyleRules() {
|
|
|
128
128
|
return getWebpackConfiguration()['custom-style-rules'] === true;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
export function isDevServerDisabled() {
|
|
132
|
+
const webpackConfiguration = getWebpackConfiguration();
|
|
133
|
+
return webpackConfiguration.devServer === false;
|
|
134
|
+
}
|
|
135
|
+
|
|
131
136
|
export function isExposeSharedDependencies() {
|
|
132
137
|
return getWebpackConfiguration()['expose-shared-dependencies'] === true;
|
|
133
138
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ExposedDependency {
|
|
2
|
+
version: string;
|
|
3
|
+
variable: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type ExposedDependencies = Record<string, ExposedDependency>;
|
|
7
|
+
|
|
8
|
+
export function getExposedDependencies(
|
|
9
|
+
sharedDependencies: Record<string, string>,
|
|
10
|
+
getVersion: (dependency: string) => string
|
|
11
|
+
) {
|
|
12
|
+
return Object.entries(sharedDependencies).reduce(
|
|
13
|
+
(result, [dependency, variable]) => ({
|
|
14
|
+
...result,
|
|
15
|
+
[dependency]: { version: getVersion(dependency), variable },
|
|
16
|
+
}),
|
|
17
|
+
{} as ExposedDependencies
|
|
18
|
+
);
|
|
19
|
+
}
|
package/src/utils/get-folders.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -67,16 +67,19 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
67
67
|
const indexCode = ({
|
|
68
68
|
embed = false,
|
|
69
69
|
legacyRoot = false,
|
|
70
|
-
|
|
70
|
+
designSystem,
|
|
71
|
+
}: { embed?: boolean; legacyRoot?: boolean; designSystem?: boolean } = {}) =>
|
|
71
72
|
[
|
|
72
|
-
...(
|
|
73
|
+
...(designSystem ? [`require('./design-system.css');`] : []),
|
|
73
74
|
`import { register } from '@servicetitan/web-components';`,
|
|
74
75
|
`import { App } from './app';`,
|
|
75
|
-
`register(App, ${embed}, { legacyRoot: ${legacyRoot}, sharedDependenciesNames:
|
|
76
|
+
`register(App, ${embed}, { legacyRoot: ${legacyRoot}, sharedDependenciesNames: ${JSON.stringify(Object.keys(sharedDependencies))} });`,
|
|
76
77
|
].join('\n');
|
|
77
78
|
|
|
78
79
|
let overrides: Parameters<typeof createWebpackConfig>[0];
|
|
79
80
|
let options: NonNullable<Parameters<typeof createWebpackConfig>[1]>;
|
|
81
|
+
let dependencies: Record<string, string>;
|
|
82
|
+
let sharedDependencies: Record<string, string>;
|
|
80
83
|
|
|
81
84
|
function mockPlugIn(name: string) {
|
|
82
85
|
return (options: Record<string, any>): any => ({ [name]: options });
|
|
@@ -85,6 +88,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
85
88
|
beforeEach(() => {
|
|
86
89
|
overrides = { plugins: { HtmlWebpackPlugin: { favicon: 'foo' } } };
|
|
87
90
|
options = { name: packageName };
|
|
91
|
+
dependencies = { '@servicetitan/design-system': '*' };
|
|
92
|
+
sharedDependencies = {
|
|
93
|
+
'@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
|
|
94
|
+
};
|
|
88
95
|
|
|
89
96
|
jest.resetAllMocks();
|
|
90
97
|
jest.mocked(MiniCssExtractPlugin).mockImplementation(mockPlugIn('MiniCssExtractPlugin'));
|
|
@@ -95,11 +102,11 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
95
102
|
|
|
96
103
|
jest.mocked(getCallerFile).mockReturnValue('');
|
|
97
104
|
jest.mocked(getFolders).mockReturnValue({ source, destination });
|
|
98
|
-
jest.mocked(getPackageData).
|
|
105
|
+
jest.mocked(getPackageData).mockImplementation(() => ({
|
|
99
106
|
name: packageName,
|
|
100
|
-
dependencies
|
|
101
|
-
sharedDependencies
|
|
102
|
-
});
|
|
107
|
+
dependencies,
|
|
108
|
+
sharedDependencies,
|
|
109
|
+
}));
|
|
103
110
|
jest.mocked(getPackages).mockReturnValue([]);
|
|
104
111
|
jest.mocked(getTsConfig).mockReturnValue(tsConfig);
|
|
105
112
|
jest.mocked(isLegacyRoot).mockReturnValue(false);
|
|
@@ -233,7 +240,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
233
240
|
expect(subject().plugins).toContainEqual(
|
|
234
241
|
new VirtualModulesPlugin({
|
|
235
242
|
[designSystemPath()]: designSystemCode,
|
|
236
|
-
[indexPath()]: indexCode(),
|
|
243
|
+
[indexPath()]: indexCode({ designSystem: true }),
|
|
237
244
|
})
|
|
238
245
|
);
|
|
239
246
|
});
|
|
@@ -245,7 +252,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
245
252
|
expect(subject().plugins).toContainEqual(
|
|
246
253
|
new VirtualModulesPlugin({
|
|
247
254
|
[designSystemPath()]: designSystemCode,
|
|
248
|
-
[indexPath()]: indexCode({ legacyRoot: true }),
|
|
255
|
+
[indexPath()]: indexCode({ designSystem: true, legacyRoot: true }),
|
|
249
256
|
})
|
|
250
257
|
);
|
|
251
258
|
});
|
|
@@ -262,7 +269,22 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
262
269
|
test('omits design system virtual module', () => {
|
|
263
270
|
expect(subject().plugins).toContainEqual(
|
|
264
271
|
new VirtualModulesPlugin({
|
|
265
|
-
[indexPath()]: indexCode(),
|
|
272
|
+
[indexPath()]: indexCode({ designSystem: true }),
|
|
273
|
+
})
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
describe('when package does not depend on design system', () => {
|
|
279
|
+
beforeEach(() => {
|
|
280
|
+
delete dependencies['@servicetitan/design-system'];
|
|
281
|
+
delete sharedDependencies['@servicetitan/design-system'];
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test('omits design system', () => {
|
|
285
|
+
expect(subject().plugins).toContainEqual(
|
|
286
|
+
new VirtualModulesPlugin({
|
|
287
|
+
[indexPath()]: indexCode({ designSystem: false }),
|
|
266
288
|
})
|
|
267
289
|
);
|
|
268
290
|
});
|
|
@@ -271,11 +293,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
271
293
|
describe('when embed option is set to true', () => {
|
|
272
294
|
beforeEach(() => (options.embed = true));
|
|
273
295
|
|
|
274
|
-
test(`
|
|
296
|
+
test(`omits design system and registers App with embed set to true`, () => {
|
|
275
297
|
expect(subject().plugins).toContainEqual(
|
|
276
298
|
new VirtualModulesPlugin({
|
|
277
|
-
[
|
|
278
|
-
[indexPath()]: indexCode({ embed: true }),
|
|
299
|
+
[indexPath()]: indexCode({ designSystem: false, embed: true }),
|
|
279
300
|
})
|
|
280
301
|
);
|
|
281
302
|
});
|
|
@@ -285,6 +306,19 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
285
306
|
expect.stringContaining(path.join(destination, 'bundle', 'light'))
|
|
286
307
|
);
|
|
287
308
|
});
|
|
309
|
+
|
|
310
|
+
describe('when package does not share design system', () => {
|
|
311
|
+
beforeEach(() => delete sharedDependencies['@servicetitan/design-system']);
|
|
312
|
+
|
|
313
|
+
test('includes design system', () => {
|
|
314
|
+
expect(subject().plugins).toContainEqual(
|
|
315
|
+
new VirtualModulesPlugin({
|
|
316
|
+
[designSystemPath()]: designSystemCode,
|
|
317
|
+
[indexPath()]: indexCode({ designSystem: true, embed: true }),
|
|
318
|
+
})
|
|
319
|
+
);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
288
322
|
});
|
|
289
323
|
|
|
290
324
|
describe.each([webpackDevConfigFileName, webpackProdConfigFileName])(
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
getTsConfig,
|
|
26
26
|
getWebpackConfiguration,
|
|
27
27
|
isCustomStyleRules,
|
|
28
|
+
isDevServerDisabled,
|
|
28
29
|
isWebComponent,
|
|
29
30
|
loadSharedDependencies,
|
|
30
31
|
log,
|
|
@@ -64,6 +65,7 @@ jest.mock('../../utils', () => ({
|
|
|
64
65
|
getTsConfig: jest.fn(),
|
|
65
66
|
getWebpackConfiguration: jest.fn(),
|
|
66
67
|
isCustomStyleRules: jest.fn(),
|
|
68
|
+
isDevServerDisabled: jest.fn(),
|
|
67
69
|
isExposeSharedDependencies: jest.fn(),
|
|
68
70
|
isWebComponent: jest.fn(),
|
|
69
71
|
loadSharedDependencies: jest.fn(),
|
|
@@ -220,6 +222,14 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
220
222
|
expect(subject().devServer).toEqual(defaultDefServerConfig);
|
|
221
223
|
});
|
|
222
224
|
|
|
225
|
+
describe('when "devServer" is disabled', () => {
|
|
226
|
+
beforeEach(() => jest.mocked(isDevServerDisabled).mockReturnValue(true));
|
|
227
|
+
|
|
228
|
+
test('omits "devServer" configuration', () => {
|
|
229
|
+
expect(subject().devServer).toBeUndefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
223
233
|
describe('with custom devServer options', () => {
|
|
224
234
|
const options: WebpackDevServer.Configuration = {
|
|
225
235
|
// allowed options
|