@servicetitan/startup 31.0.0 → 31.1.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/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +1 -7
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/prepare-package.d.ts +1 -2
- package/dist/cli/commands/prepare-package.d.ts.map +1 -1
- package/dist/cli/commands/prepare-package.js +4 -6
- package/dist/cli/commands/prepare-package.js.map +1 -1
- package/dist/cli/commands/run-task.test.js +59 -0
- package/dist/cli/commands/run-task.test.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +2 -11
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/tasks/swc-cli.d.js +3 -0
- package/dist/cli/tasks/swc-cli.d.js.map +1 -0
- package/dist/cli/tasks/swc-compile-package.d.ts.map +1 -1
- package/dist/cli/tasks/swc-compile-package.js +22 -19
- package/dist/cli/tasks/swc-compile-package.js.map +1 -1
- package/dist/cli/types/cpx2.d.js +3 -0
- package/dist/cli/types/cpx2.d.js.map +1 -0
- package/dist/cli/utils/bundle.d.ts +2 -2
- package/dist/cli/utils/bundle.d.ts.map +1 -1
- package/dist/cli/utils/bundle.js +18 -4
- package/dist/cli/utils/bundle.js.map +1 -1
- package/dist/cli/utils/copy-files.d.ts +1 -1
- package/dist/cli/utils/copy-files.d.ts.map +1 -1
- package/dist/cli/utils/copy-files.js +18 -11
- package/dist/cli/utils/copy-files.js.map +1 -1
- package/dist/cli/utils/get-module-type.d.ts.map +1 -1
- package/dist/cli/utils/get-module-type.js +2 -16
- package/dist/cli/utils/get-module-type.js.map +1 -1
- package/dist/cli/utils/index.d.ts +1 -1
- package/dist/cli/utils/index.d.ts.map +1 -1
- package/dist/cli/utils/index.js +1 -1
- package/dist/cli/utils/index.js.map +1 -1
- package/dist/cli/utils/ts-config.d.ts +11 -0
- package/dist/cli/utils/ts-config.d.ts.map +1 -0
- package/dist/cli/utils/ts-config.js +80 -0
- package/dist/cli/utils/ts-config.js.map +1 -0
- package/dist/utils/get-configuration.d.ts +1 -0
- package/dist/utils/get-configuration.d.ts.map +1 -1
- package/dist/utils/get-configuration.js +14 -0
- package/dist/utils/get-configuration.js.map +1 -1
- package/dist/webpack/configs/index.d.ts +0 -1
- package/dist/webpack/configs/index.d.ts.map +1 -1
- package/dist/webpack/configs/index.js +0 -1
- package/dist/webpack/configs/index.js.map +1 -1
- package/dist/webpack/configs/optimization-config.js +6 -6
- package/dist/webpack/configs/optimization-config.js.map +1 -1
- package/dist/webpack/configs/output-config.d.ts.map +1 -1
- package/dist/webpack/configs/output-config.js +3 -2
- package/dist/webpack/configs/output-config.js.map +1 -1
- package/dist/webpack/configs/plugins/html-plugin.d.ts +1 -1
- package/dist/webpack/configs/plugins/html-plugin.d.ts.map +1 -1
- package/dist/webpack/configs/plugins/html-plugin.js +2 -2
- package/dist/webpack/configs/plugins/html-plugin.js.map +1 -1
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js +14 -4
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.js +4 -0
- package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
- package/dist/webpack/create-webpack-config.d.ts.map +1 -1
- package/dist/webpack/create-webpack-config.js +0 -1
- package/dist/webpack/create-webpack-config.js.map +1 -1
- package/dist/webpack/types.d.ts +1 -0
- package/dist/webpack/types.d.ts.map +1 -1
- package/dist/webpack/utils/index.d.ts +0 -1
- package/dist/webpack/utils/index.d.ts.map +1 -1
- package/dist/webpack/utils/index.js +0 -1
- package/dist/webpack/utils/index.js.map +1 -1
- package/package.json +7 -8
- package/src/cli/commands/__tests__/build.test.ts +2 -4
- package/src/cli/commands/__tests__/prepare-package.test.ts +5 -28
- package/src/cli/commands/__tests__/start.test.ts +3 -5
- package/src/cli/commands/build.ts +0 -2
- package/src/cli/commands/prepare-package.ts +4 -7
- package/src/cli/commands/start.ts +1 -3
- package/src/cli/tasks/__tests__/swc-compile-package.test.ts +71 -12
- package/src/cli/tasks/swc-compile-package.ts +21 -20
- package/src/cli/utils/__tests__/bundle.test.ts +48 -7
- package/src/cli/utils/__tests__/copy-files.test.ts +5 -5
- package/src/cli/utils/bundle.ts +27 -5
- package/src/cli/utils/copy-files.ts +16 -6
- package/src/cli/utils/get-module-type.ts +2 -18
- package/src/cli/utils/index.ts +1 -1
- package/src/cli/utils/ts-config.ts +64 -0
- package/src/utils/__tests__/get-configuration.test.ts +20 -0
- package/src/utils/get-configuration.ts +12 -0
- package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +0 -1
- package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +17 -28
- package/src/webpack/__tests__/create-webpack-config.test.ts +27 -38
- package/src/webpack/configs/index.ts +0 -1
- package/src/webpack/configs/optimization-config.ts +6 -6
- package/src/webpack/configs/output-config.ts +4 -2
- package/src/webpack/configs/plugins/html-plugin.ts +5 -2
- package/src/webpack/configs/plugins/virtual-modules-plugin.ts +15 -2
- package/src/webpack/configs/utils/__tests__/generate-metadata.test.ts +3 -1
- package/src/webpack/configs/utils/generate-metadata.ts +6 -1
- package/src/webpack/create-webpack-config.ts +0 -2
- package/src/webpack/types.ts +1 -0
- package/src/webpack/utils/index.ts +0 -1
- package/dist/__mocks__/create-package.d.ts +0 -3
- package/dist/__mocks__/create-package.d.ts.map +0 -1
- package/dist/__mocks__/index.d.ts +0 -2
- package/dist/__mocks__/index.d.ts.map +0 -1
- package/dist/cli/commands/review/__mocks__/expect-calls.d.ts +0 -23
- package/dist/cli/commands/review/__mocks__/expect-calls.d.ts.map +0 -1
- package/dist/cli/commands/review/__mocks__/index.d.ts +0 -2
- package/dist/cli/commands/review/__mocks__/index.d.ts.map +0 -1
- package/dist/cli/commands/review/rules/__mocks__/index.d.ts +0 -4
- package/dist/cli/commands/review/rules/__mocks__/index.d.ts.map +0 -1
- package/dist/cli/commands/review/rules/__mocks__/mock-config.d.ts +0 -7
- package/dist/cli/commands/review/rules/__mocks__/mock-config.d.ts.map +0 -1
- package/dist/cli/commands/review/rules/__mocks__/mock-packages.d.ts +0 -21
- package/dist/cli/commands/review/rules/__mocks__/mock-packages.d.ts.map +0 -1
- package/dist/cli/commands/review/rules/__mocks__/mock-project.d.ts +0 -3
- package/dist/cli/commands/review/rules/__mocks__/mock-project.d.ts.map +0 -1
- package/dist/cli/utils/style-extensions.d.ts +0 -2
- package/dist/cli/utils/style-extensions.d.ts.map +0 -1
- package/dist/cli/utils/style-extensions.js +0 -17
- package/dist/cli/utils/style-extensions.js.map +0 -1
- package/dist/cli/utils/tcm.d.ts +0 -6
- package/dist/cli/utils/tcm.d.ts.map +0 -1
- package/dist/cli/utils/tcm.js +0 -72
- package/dist/cli/utils/tcm.js.map +0 -1
- package/dist/webpack/__mocks__/file-rules.d.ts +0 -3
- package/dist/webpack/__mocks__/file-rules.d.ts.map +0 -1
- package/dist/webpack/__mocks__/index.d.ts +0 -3
- package/dist/webpack/__mocks__/index.d.ts.map +0 -1
- package/dist/webpack/__mocks__/style-rules.d.ts +0 -8
- package/dist/webpack/__mocks__/style-rules.d.ts.map +0 -1
- package/dist/webpack/configs/cache-config.d.ts +0 -6
- package/dist/webpack/configs/cache-config.d.ts.map +0 -1
- package/dist/webpack/configs/cache-config.js +0 -34
- package/dist/webpack/configs/cache-config.js.map +0 -1
- package/dist/webpack/utils/feature-cohort.d.ts +0 -5
- package/dist/webpack/utils/feature-cohort.d.ts.map +0 -1
- package/dist/webpack/utils/feature-cohort.js +0 -26
- package/dist/webpack/utils/feature-cohort.js.map +0 -1
- package/dist/webpack/utils/hash-mod.d.ts +0 -9
- package/dist/webpack/utils/hash-mod.d.ts.map +0 -1
- package/dist/webpack/utils/hash-mod.js +0 -39
- package/dist/webpack/utils/hash-mod.js.map +0 -1
- package/src/cli/utils/__tests__/tcm.test.ts +0 -195
- package/src/cli/utils/style-extensions.ts +0 -1
- package/src/cli/utils/tcm.ts +0 -66
- package/src/webpack/configs/cache-config.ts +0 -25
- package/src/webpack/utils/feature-cohort.ts +0 -19
- package/src/webpack/utils/hash-mod.ts +0 -32
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getConfiguration,
|
|
8
8
|
getFolders,
|
|
9
9
|
getPackageData,
|
|
10
|
+
hasHeadlessBundle,
|
|
10
11
|
loadSharedDependencies,
|
|
11
12
|
} from '../../../utils';
|
|
12
13
|
import { createWebpackConfig } from '../../../webpack';
|
|
@@ -27,6 +28,7 @@ jest.mock('../../../utils', () => ({
|
|
|
27
28
|
...jest.requireActual('../../../utils'),
|
|
28
29
|
getFolders: jest.fn(),
|
|
29
30
|
getPackageData: jest.fn(),
|
|
31
|
+
hasHeadlessBundle: jest.fn(),
|
|
30
32
|
loadSharedDependencies: jest.fn(),
|
|
31
33
|
log: { info: jest.fn() }, // suppress test output
|
|
32
34
|
}));
|
|
@@ -174,6 +176,8 @@ describe('[startup] Cli Utils', () => {
|
|
|
174
176
|
const destination = 'dist';
|
|
175
177
|
const dependencies = { foo: '1.0.1' };
|
|
176
178
|
const sharedDependencies = { react: 'SharedDependencies.React' };
|
|
179
|
+
let defaultCreateOverrides: Parameters<typeof createWebpackConfig>[0];
|
|
180
|
+
let defaultCreateOptions: Parameters<typeof createWebpackConfig>[1];
|
|
177
181
|
|
|
178
182
|
beforeEach(() => {
|
|
179
183
|
vol.fromJSON(webComponentFS());
|
|
@@ -184,22 +188,42 @@ describe('[startup] Cli Utils', () => {
|
|
|
184
188
|
dependencies,
|
|
185
189
|
});
|
|
186
190
|
jest.mocked(loadSharedDependencies).mockReturnValue(sharedDependencies);
|
|
191
|
+
defaultCreateOverrides = { configuration: { mode: 'production' } };
|
|
192
|
+
defaultCreateOptions = {
|
|
193
|
+
buildStat: options?.buildStat,
|
|
194
|
+
name: expectPackageName(),
|
|
195
|
+
};
|
|
187
196
|
});
|
|
188
197
|
|
|
189
198
|
test('builds full and "embed" packages', async () => {
|
|
190
|
-
const createOptions = { buildStat: options?.buildStat, name: expectPackageName() };
|
|
191
|
-
const overrides = { configuration: { mode: 'production' } };
|
|
192
|
-
|
|
193
199
|
await subject();
|
|
194
200
|
|
|
195
|
-
expect(createWebpackConfig).toHaveBeenCalledWith(
|
|
196
|
-
|
|
197
|
-
|
|
201
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(
|
|
202
|
+
defaultCreateOverrides,
|
|
203
|
+
defaultCreateOptions
|
|
204
|
+
);
|
|
205
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(defaultCreateOverrides, {
|
|
206
|
+
...defaultCreateOptions,
|
|
198
207
|
embed: true,
|
|
199
208
|
});
|
|
200
209
|
expect(compiler.run).toHaveBeenCalledTimes(2);
|
|
201
210
|
});
|
|
202
211
|
|
|
212
|
+
describe('when headless file exists', () => {
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
jest.mocked(hasHeadlessBundle).mockReturnValue(true);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test('builds headless package', async () => {
|
|
218
|
+
await subject();
|
|
219
|
+
|
|
220
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(defaultCreateOverrides, {
|
|
221
|
+
...defaultCreateOptions,
|
|
222
|
+
headless: true,
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
203
227
|
function itUsesConfig(params: { config: () => Record<string, any>; name: string }) {
|
|
204
228
|
test(`uses ${params.name}`, async () => {
|
|
205
229
|
const { configuration, plugins } = params.config();
|
|
@@ -384,13 +408,30 @@ describe('[startup] Cli Utils', () => {
|
|
|
384
408
|
});
|
|
385
409
|
expect(webpack).toHaveBeenNthCalledWith(1, createWebpackResult);
|
|
386
410
|
expect(webpack).toHaveBeenNthCalledWith(2, createWebpackResult);
|
|
387
|
-
expect(compiler.watch).
|
|
411
|
+
expect(compiler.watch).toHaveBeenCalledTimes(1);
|
|
388
412
|
expect(WebpackDevServer).toHaveBeenCalledWith(
|
|
389
413
|
{ host: 'localhost', port: 8080 },
|
|
390
414
|
compiler
|
|
391
415
|
);
|
|
392
416
|
});
|
|
393
417
|
|
|
418
|
+
describe('when headless file exists', () => {
|
|
419
|
+
beforeEach(() => {
|
|
420
|
+
jest.mocked(hasHeadlessBundle).mockReturnValue(true);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test('runs watch on headless bundle', async () => {
|
|
424
|
+
await subject();
|
|
425
|
+
|
|
426
|
+
expect(createWebpackConfig).toHaveBeenCalledWith(
|
|
427
|
+
expect.any(Object),
|
|
428
|
+
expect.objectContaining({ headless: true })
|
|
429
|
+
);
|
|
430
|
+
expect(webpack).toHaveBeenNthCalledWith(3, createWebpackResult);
|
|
431
|
+
expect(compiler.watch).toHaveBeenCalledTimes(2);
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
|
|
394
435
|
describe('when webpack.devServer is set to false in package.json', () => {
|
|
395
436
|
beforeEach(() => {
|
|
396
437
|
vol.fromJSON(webComponentFS({ webpack: { devServer: false } } as any));
|
|
@@ -6,10 +6,10 @@ import fs from 'fs';
|
|
|
6
6
|
import { getFolders, log } from '../../../utils';
|
|
7
7
|
import * as compileSassModule from '../compile-sass';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { copyFiles, styleExtensions, supportedExtensions } from '../copy-files';
|
|
10
10
|
|
|
11
11
|
jest.mock('cpx2', () => ({
|
|
12
|
-
|
|
12
|
+
copySync: jest.fn(),
|
|
13
13
|
watch: jest.fn(),
|
|
14
14
|
}));
|
|
15
15
|
jest.mock('../../../utils', () => ({
|
|
@@ -27,7 +27,7 @@ jest.mock('../../../utils', () => ({
|
|
|
27
27
|
describe(`[startup] cli utils (${copyFiles.name})`, () => {
|
|
28
28
|
const source = fs.mkdtempSync('src');
|
|
29
29
|
const destination = 'dist';
|
|
30
|
-
const files = `${source}/**/*.{${
|
|
30
|
+
const files = `${source}/**/*.{${supportedExtensions.join()}}`;
|
|
31
31
|
let options: Parameters<typeof copyFiles>[0];
|
|
32
32
|
|
|
33
33
|
beforeEach(() => {
|
|
@@ -72,7 +72,7 @@ describe(`[startup] cli utils (${copyFiles.name})`, () => {
|
|
|
72
72
|
test('copies assets and styles from source to destination', async () => {
|
|
73
73
|
await subject();
|
|
74
74
|
|
|
75
|
-
expect(cpx.
|
|
75
|
+
expect(cpx.copySync).toHaveBeenCalledWith(files, destination);
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
describe.each(styleExtensions)('with %s module', extension => {
|
|
@@ -151,7 +151,7 @@ describe(`[startup] cli utils (${copyFiles.name})`, () => {
|
|
|
151
151
|
test('does not copy files', async () => {
|
|
152
152
|
await subject();
|
|
153
153
|
|
|
154
|
-
expect(cpx.
|
|
154
|
+
expect(cpx.copySync).not.toHaveBeenCalledWith();
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
157
|
});
|
package/src/cli/utils/bundle.ts
CHANGED
|
@@ -6,7 +6,13 @@ import { getPortPromise } from 'portfinder';
|
|
|
6
6
|
import webpack, { Configuration } from 'webpack';
|
|
7
7
|
import WebpackDevServer from 'webpack-dev-server';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getPackageName,
|
|
11
|
+
hasHeadlessBundle,
|
|
12
|
+
isDevServerDisabled,
|
|
13
|
+
isWebComponent,
|
|
14
|
+
log,
|
|
15
|
+
} from '../../utils';
|
|
10
16
|
import { Overrides, createWebpackConfig } from '../../webpack';
|
|
11
17
|
|
|
12
18
|
interface Options {
|
|
@@ -43,10 +49,18 @@ export async function bundle(options: Options = {}) {
|
|
|
43
49
|
plugins: config?.plugins,
|
|
44
50
|
};
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
const bundles = [
|
|
47
53
|
run(createWebpackConfig(webpackConfig, { embed: true, ...webpackOptions })),
|
|
48
54
|
run(createWebpackConfig(webpackConfig, webpackOptions)),
|
|
49
|
-
]
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
if (hasHeadlessBundle()) {
|
|
58
|
+
bundles.push(
|
|
59
|
+
run(createWebpackConfig(webpackConfig, { ...webpackOptions, headless: true }))
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return Promise.all(bundles);
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
return run(config ?? createWebpackConfig({ configuration: { mode } }, webpackOptions));
|
|
@@ -66,12 +80,20 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
66
80
|
plugins: config?.plugins,
|
|
67
81
|
};
|
|
68
82
|
|
|
69
|
-
|
|
83
|
+
const bundles = [
|
|
70
84
|
runWatch(createWebpackConfig(webpackConfig, { embed: true, ...configOverrides })),
|
|
71
85
|
isDevServerDisabled()
|
|
72
86
|
? runWatch(createWebpackConfig(webpackConfig, configOverrides))
|
|
73
87
|
: runServe(createWebpackConfig(webpackConfig, configOverrides)),
|
|
74
|
-
]
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
if (hasHeadlessBundle()) {
|
|
91
|
+
bundles.push(
|
|
92
|
+
runWatch(createWebpackConfig(webpackConfig, { ...configOverrides, headless: true }))
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return Promise.all(bundles);
|
|
75
97
|
}
|
|
76
98
|
|
|
77
99
|
const webpackConfig =
|
|
@@ -7,8 +7,17 @@ import { getFolders, log } from '../../utils';
|
|
|
7
7
|
import { compileLess } from './compile-less';
|
|
8
8
|
import { compileSass } from './compile-sass';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const assetExtensions = ['eot', 'gif', 'jpg', 'otf', 'png', 'svg', 'ttf', 'woff', 'woff2'];
|
|
11
|
+
const resourceExtensions = ['json'];
|
|
11
12
|
export const styleExtensions = ['css', 'less', 'scss'];
|
|
13
|
+
const styleTypeDefinitionExtensions = styleExtensions.map(ext => `${ext}.d.ts`);
|
|
14
|
+
|
|
15
|
+
export const supportedExtensions = [
|
|
16
|
+
assetExtensions,
|
|
17
|
+
resourceExtensions,
|
|
18
|
+
styleExtensions,
|
|
19
|
+
styleTypeDefinitionExtensions,
|
|
20
|
+
].flat();
|
|
12
21
|
|
|
13
22
|
const styleModuleRegex = new RegExp(`\\.module\\.(${styleExtensions.join('|')})$`);
|
|
14
23
|
|
|
@@ -22,7 +31,7 @@ export async function copyFiles({ watch }: CopyFilesOptions) {
|
|
|
22
31
|
return;
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
const filesPattern = `${source}/**/*.{${
|
|
34
|
+
const filesPattern = `${source}/**/*.{${supportedExtensions.join()}}`;
|
|
26
35
|
const creator = new DtsCreator({ camelCase: true, namedExports: true });
|
|
27
36
|
const generateDefinitions = async (file: string) => {
|
|
28
37
|
try {
|
|
@@ -35,13 +44,14 @@ export async function copyFiles({ watch }: CopyFilesOptions) {
|
|
|
35
44
|
};
|
|
36
45
|
|
|
37
46
|
if (!watch) {
|
|
38
|
-
log.info(`Copying ${filesPattern} -> ${destination}`);
|
|
39
|
-
cpx.copy(filesPattern, destination);
|
|
40
|
-
|
|
41
47
|
const modulesPattern = `${source}/**/*.module.{${styleExtensions.join()}}`;
|
|
42
48
|
log.info(`Generating types for ${modulesPattern}`);
|
|
43
49
|
const modules = await glob(modulesPattern);
|
|
44
50
|
await Promise.all(modules.map(generateDefinitions));
|
|
51
|
+
|
|
52
|
+
log.info(`Copying ${filesPattern} -> ${destination}`);
|
|
53
|
+
cpx.copySync(filesPattern, destination);
|
|
54
|
+
|
|
45
55
|
return;
|
|
46
56
|
}
|
|
47
57
|
|
|
@@ -49,7 +59,7 @@ export async function copyFiles({ watch }: CopyFilesOptions) {
|
|
|
49
59
|
cpx.watch(filesPattern, destination, {
|
|
50
60
|
initialCopy: false,
|
|
51
61
|
// Optimization so cpx2 doesn't waste resources watching irrelevant files
|
|
52
|
-
ignore: ['__tests__', '__mocks__', '
|
|
62
|
+
ignore: ['__tests__', '__mocks__', '*.*', ...supportedExtensions.map(ext => `!*.${ext}`)],
|
|
53
63
|
})
|
|
54
64
|
.on('copy', async ({ srcPath, dstPath }: { srcPath: string; dstPath: string }) => {
|
|
55
65
|
log.info(`Copied ${srcPath} -> ${dstPath}`);
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { readJson } from '../../utils';
|
|
1
|
+
import { TSConfig } from './ts-config';
|
|
4
2
|
|
|
5
3
|
export function getModuleType(configPath: string): string {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (config.compilerOptions?.module) {
|
|
9
|
-
return config.compilerOptions.module.toLowerCase();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (config.extends) {
|
|
13
|
-
return getModuleType(
|
|
14
|
-
/^\.?\.\//.test(config.extends)
|
|
15
|
-
? path.join(path.dirname(configPath), config.extends)
|
|
16
|
-
: require.resolve(config.extends)
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return 'commonjs';
|
|
4
|
+
return new TSConfig(configPath).getValue('compilerOptions.module', 'commonjs');
|
|
21
5
|
}
|
package/src/cli/utils/index.ts
CHANGED
|
@@ -11,6 +11,6 @@ export * from './lerna-exec';
|
|
|
11
11
|
export * from './pipe-stdout';
|
|
12
12
|
export * from './process-tree';
|
|
13
13
|
export * from './set-node-options';
|
|
14
|
-
export * from './
|
|
14
|
+
export * from './ts-config';
|
|
15
15
|
export * from './type-check';
|
|
16
16
|
export * from './watch-stdout';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { readJson } from '../../utils';
|
|
4
|
+
|
|
5
|
+
export class TSConfig {
|
|
6
|
+
private readonly json: Map<string, any>;
|
|
7
|
+
|
|
8
|
+
constructor(private readonly configPath: string) {
|
|
9
|
+
this.json = new Map();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Overload signatures
|
|
13
|
+
getValue<T>(key: string, defaultValue: T): NoInfer<T>;
|
|
14
|
+
getValue<T>(key: string, defaultValue?: T): T | undefined;
|
|
15
|
+
|
|
16
|
+
// Implementation signature
|
|
17
|
+
getValue<T>(key: string, defaultValue?: T) {
|
|
18
|
+
return this.getValueInternal<T>(this.configPath, key.split('.'), defaultValue);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private getValueInternal<T>(configPath: string, key: string[], defaultValue?: T): T {
|
|
22
|
+
const config = this.getJson<{ extends?: string }>(configPath);
|
|
23
|
+
const value = key.reduce<any>((result, el) => {
|
|
24
|
+
return result && typeof result === 'object' ? result[el] : undefined;
|
|
25
|
+
}, config);
|
|
26
|
+
|
|
27
|
+
if (value !== undefined) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const extendsPath = this.getExtendsPath(configPath, config);
|
|
32
|
+
if (extendsPath) {
|
|
33
|
+
return this.getValueInternal(extendsPath, key, defaultValue);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return defaultValue as T;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private getExtendsPath(configPath: string, config: { extends?: string }) {
|
|
40
|
+
if (!config.extends) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!/^\.?\.\//.test(config.extends)) {
|
|
45
|
+
return require.resolve(config.extends);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const dir = path.dirname(configPath);
|
|
49
|
+
return [config.extends, `${config.extends}.json`]
|
|
50
|
+
.map(name => path.join(dir, name))
|
|
51
|
+
.find(fs.existsSync);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private getJson<T>(configPath: string): T {
|
|
55
|
+
let result: T = this.json.get(configPath);
|
|
56
|
+
|
|
57
|
+
if (!result) {
|
|
58
|
+
result = readJson<T>(configPath);
|
|
59
|
+
this.json.set(configPath, result);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getStylelintConfiguration,
|
|
11
11
|
getWebComponentBranchConfigs,
|
|
12
12
|
getWebComponentConfiguration,
|
|
13
|
+
hasHeadlessBundle,
|
|
13
14
|
isBundle,
|
|
14
15
|
isCustomStyleRules,
|
|
15
16
|
isDevServerDisabled,
|
|
@@ -332,6 +333,25 @@ describe('[startup] Utils', () => {
|
|
|
332
333
|
});
|
|
333
334
|
});
|
|
334
335
|
|
|
336
|
+
describe(`${hasHeadlessBundle.name}`, () => {
|
|
337
|
+
const subject = () => hasHeadlessBundle();
|
|
338
|
+
|
|
339
|
+
itReturns(subject, false);
|
|
340
|
+
|
|
341
|
+
describe('when src/headless.ts exists', () => {
|
|
342
|
+
beforeEach(() =>
|
|
343
|
+
vol.fromJSON({
|
|
344
|
+
'src/headless.ts': '',
|
|
345
|
+
'tsconfig.json': JSON.stringify({
|
|
346
|
+
compilerOptions: { rootDir: 'src', outDir: 'path' },
|
|
347
|
+
}),
|
|
348
|
+
})
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
itReturns(subject, true);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
335
355
|
describe.each([
|
|
336
356
|
{
|
|
337
357
|
fn: isBundle,
|
|
@@ -8,6 +8,7 @@ import { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-serv
|
|
|
8
8
|
|
|
9
9
|
import { ReviewConfiguration } from '../cli/commands/review';
|
|
10
10
|
import { log } from './log';
|
|
11
|
+
import { getFolders } from './get-folders';
|
|
11
12
|
import { readJson, readJsonSafe } from './read-json';
|
|
12
13
|
|
|
13
14
|
export const allowedWebpackDevServerOptions = ['headers', 'port', 'proxy', 'static'] as const;
|
|
@@ -175,6 +176,17 @@ export function getWebComponentBranchConfigs(locationOrJson: LocationOrJson = '.
|
|
|
175
176
|
return config?.branches;
|
|
176
177
|
}
|
|
177
178
|
|
|
179
|
+
export function hasHeadlessBundle() {
|
|
180
|
+
let source: string;
|
|
181
|
+
try {
|
|
182
|
+
source = getFolders().source;
|
|
183
|
+
} catch {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
const headlessPath = path.join(source, 'headless.ts');
|
|
187
|
+
return fs.existsSync(headlessPath);
|
|
188
|
+
}
|
|
189
|
+
|
|
178
190
|
export function getSwcCompilePackageConfiguration() {
|
|
179
191
|
return getConfiguration()['swc-compile-package'] ?? {};
|
|
180
192
|
}
|
|
@@ -38,7 +38,6 @@ jest.mock('../../utils', () => ({
|
|
|
38
38
|
jest.mock('../configs/utils/get-launchdarkly-sdk-version');
|
|
39
39
|
jest.mock('../utils', () => ({
|
|
40
40
|
...jest.requireActual('../utils'),
|
|
41
|
-
featureCohort: jest.fn(),
|
|
42
41
|
getCallerFile: jest.fn(),
|
|
43
42
|
getModuleEntryPath: jest.fn(),
|
|
44
43
|
}));
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '../../utils';
|
|
18
18
|
import { webComponentStyleRules } from '../__mocks__';
|
|
19
19
|
import { generateMetadata } from '../configs/utils';
|
|
20
|
-
import {
|
|
20
|
+
import { getCallerFile, splitByEntry } from '../utils';
|
|
21
21
|
|
|
22
22
|
import { createWebpackConfig } from '../index';
|
|
23
23
|
|
|
@@ -45,7 +45,6 @@ jest.mock('../../utils', () => ({
|
|
|
45
45
|
jest.mock('../configs/utils/generate-metadata');
|
|
46
46
|
jest.mock('../utils', () => ({
|
|
47
47
|
...jest.requireActual('../utils'),
|
|
48
|
-
featureCohort: jest.fn(),
|
|
49
48
|
getCallerFile: jest.fn(),
|
|
50
49
|
}));
|
|
51
50
|
|
|
@@ -322,6 +321,22 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
322
321
|
});
|
|
323
322
|
});
|
|
324
323
|
|
|
324
|
+
describe('when headless option is set to true', () => {
|
|
325
|
+
beforeEach(() => (options.headless = true));
|
|
326
|
+
|
|
327
|
+
test(`omits design system and registers headless`, () => {
|
|
328
|
+
expect(subject().plugins).toContainEqual(
|
|
329
|
+
new VirtualModulesPlugin({
|
|
330
|
+
[indexPath()]: [
|
|
331
|
+
"import { registerHeadless } from '@servicetitan/web-components';",
|
|
332
|
+
"import { connectedCallback, disconnectedCallback } from './headless';",
|
|
333
|
+
'registerHeadless(connectedCallback, disconnectedCallback);',
|
|
334
|
+
].join('\n'),
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
325
340
|
describe.each([webpackDevConfigFileName, webpackProdConfigFileName])(
|
|
326
341
|
'when invoked from "%s"',
|
|
327
342
|
configFileName => {
|
|
@@ -333,32 +348,6 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
333
348
|
}
|
|
334
349
|
);
|
|
335
350
|
|
|
336
|
-
describe('when featureCohort is active', () => {
|
|
337
|
-
beforeEach(() => {
|
|
338
|
-
jest.mocked(featureCohort).mockImplementation((_: number[], fn: Function) => fn());
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
test('configures "cache"', () => {
|
|
342
|
-
expect(subject().cache).toEqual({
|
|
343
|
-
type: 'filesystem',
|
|
344
|
-
name: `${packageName}__full`,
|
|
345
|
-
profile: true,
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
describe('when embed option is set to true', () => {
|
|
350
|
-
beforeEach(() => (options.embed = true));
|
|
351
|
-
|
|
352
|
-
test('changes "cache.name" suffix to "__light"', () => {
|
|
353
|
-
expect(subject().cache).toEqual(
|
|
354
|
-
expect.objectContaining({
|
|
355
|
-
name: `${packageName}__light`,
|
|
356
|
-
})
|
|
357
|
-
);
|
|
358
|
-
});
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
|
|
362
351
|
describe('when mode is production', () => {
|
|
363
352
|
beforeEach(() =>
|
|
364
353
|
Object.assign((overrides.configuration ??= {}), { mode: 'production' })
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
log,
|
|
30
30
|
} from '../../utils';
|
|
31
31
|
import { fileRules, productionStyleRules, styleRules } from '../__mocks__';
|
|
32
|
-
import {
|
|
32
|
+
import { splitByEntry } from '../utils';
|
|
33
33
|
|
|
34
34
|
import { createWebpackConfig } from '../index';
|
|
35
35
|
|
|
@@ -67,10 +67,6 @@ jest.mock('../../utils', () => ({
|
|
|
67
67
|
loadSharedDependencies: jest.fn(),
|
|
68
68
|
log: { debug: jest.fn(), info: jest.fn(), warning: jest.fn() },
|
|
69
69
|
}));
|
|
70
|
-
jest.mock('../utils', () => ({
|
|
71
|
-
...jest.requireActual('../utils'),
|
|
72
|
-
featureCohort: jest.fn(),
|
|
73
|
-
}));
|
|
74
70
|
|
|
75
71
|
describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
76
72
|
const source = 'src';
|
|
@@ -172,9 +168,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
172
168
|
});
|
|
173
169
|
|
|
174
170
|
test('configures "output.path"', () => {
|
|
175
|
-
expect(subject().output!.path).toEqual(
|
|
176
|
-
expect.stringContaining(path.join(destination, 'bundle'))
|
|
177
|
-
);
|
|
171
|
+
expect(subject().output!.path).toEqual(path.join(process.cwd(), destination, 'bundle'));
|
|
178
172
|
});
|
|
179
173
|
|
|
180
174
|
test('configures "optimization"', () => {
|
|
@@ -471,6 +465,27 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
471
465
|
);
|
|
472
466
|
});
|
|
473
467
|
});
|
|
468
|
+
|
|
469
|
+
describe('headless option is true', () => {
|
|
470
|
+
beforeEach(() => setOptions({ headless: true }));
|
|
471
|
+
|
|
472
|
+
test('configures "output.path"', () => {
|
|
473
|
+
expect(subject().output!.path).toEqual(
|
|
474
|
+
path.join(process.cwd(), destination, 'bundle', 'headless')
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
describe('when mode is "production"', () => {
|
|
479
|
+
beforeEach(() => {
|
|
480
|
+
overrides.configuration ??= {};
|
|
481
|
+
Object.assign(overrides.configuration, { mode: 'production' });
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
test('omits optimization.runtimeChunk', () => {
|
|
485
|
+
expect(subject().optimization?.runtimeChunk).toBeUndefined();
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
});
|
|
474
489
|
});
|
|
475
490
|
});
|
|
476
491
|
|
|
@@ -487,40 +502,14 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
|
|
|
487
502
|
)
|
|
488
503
|
);
|
|
489
504
|
});
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
describe('when featureCohort is active', () => {
|
|
493
|
-
beforeEach(() => {
|
|
494
|
-
jest.mocked(featureCohort).mockImplementation((_: number[], fn: Function) => fn());
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
test('configures "cache"', () => {
|
|
498
|
-
expect(subject().cache).toEqual({
|
|
499
|
-
type: 'filesystem',
|
|
500
|
-
name: packageName,
|
|
501
|
-
profile: true,
|
|
502
|
-
});
|
|
503
|
-
});
|
|
504
505
|
|
|
505
506
|
describe('when package is web component', () => {
|
|
506
507
|
beforeEach(() => jest.mocked(isWebComponent).mockReturnValue(true));
|
|
507
508
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
name: `${packageName}${suffix}`,
|
|
513
|
-
})
|
|
514
|
-
);
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
itAppendsSuffixToPackageName('__full');
|
|
519
|
-
|
|
520
|
-
describe('when embed option is set to true', () => {
|
|
521
|
-
beforeEach(() => setOptions({ embed: true }));
|
|
522
|
-
|
|
523
|
-
itAppendsSuffixToPackageName('__light');
|
|
509
|
+
test('configures "output.path"', () => {
|
|
510
|
+
expect(subject().output!.path).toEqual(
|
|
511
|
+
path.join(process.cwd(), destination, 'bundle', 'light')
|
|
512
|
+
);
|
|
524
513
|
});
|
|
525
514
|
});
|
|
526
515
|
});
|
|
@@ -8,7 +8,7 @@ type ConfigWithCacheGroups = Config & { splitChunks: { cacheGroups: Record<strin
|
|
|
8
8
|
type Result = Pick<Configuration, 'optimization'>;
|
|
9
9
|
|
|
10
10
|
export function optimizationConfig(context: Context, _: Overrides): Result {
|
|
11
|
-
const { isProduction } = context;
|
|
11
|
+
const { headless, isProduction } = context;
|
|
12
12
|
|
|
13
13
|
const optimization: ConfigWithCacheGroups = {
|
|
14
14
|
chunkIds: isProduction ? 'deterministic' : 'named',
|
|
@@ -17,7 +17,7 @@ export function optimizationConfig(context: Context, _: Overrides): Result {
|
|
|
17
17
|
splitChunks: { cacheGroups: {} },
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
if (isProduction) {
|
|
20
|
+
if (!headless && isProduction) {
|
|
21
21
|
optimization.runtimeChunk = 'single';
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -58,8 +58,8 @@ function minimizeConfig(optimization: ConfigWithCacheGroups, context: Context) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function sharedDependenciesConfig(optimization: ConfigWithCacheGroups, context: Context) {
|
|
61
|
-
const { isExposeSharedDependencies } = context;
|
|
62
|
-
if (!isExposeSharedDependencies) {
|
|
61
|
+
const { headless, isExposeSharedDependencies } = context;
|
|
62
|
+
if (!isExposeSharedDependencies || headless) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -80,8 +80,8 @@ function sharedDependenciesConfig(optimization: ConfigWithCacheGroups, context:
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
function webComponentConfig(optimization: ConfigWithCacheGroups, context: Context) {
|
|
83
|
-
const { isWebComponent, isProduction } = context;
|
|
84
|
-
if (!isWebComponent) {
|
|
83
|
+
const { headless, isWebComponent, isProduction } = context;
|
|
84
|
+
if (!isWebComponent || headless) {
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -6,12 +6,14 @@ type Config = Configuration['output'];
|
|
|
6
6
|
type Result = Pick<Configuration, 'output'>;
|
|
7
7
|
|
|
8
8
|
export function outputConfig(context: Context, _: Overrides): Result {
|
|
9
|
-
const { destination, embed, isProduction, isWebComponent, name } = context;
|
|
9
|
+
const { destination, embed, headless, isProduction, isWebComponent, name } = context;
|
|
10
|
+
|
|
11
|
+
const bundleDir = headless ? 'headless' : embed ? 'light' : 'full';
|
|
10
12
|
|
|
11
13
|
const output: Config = {
|
|
12
14
|
filename: '[name].bundle.js',
|
|
13
15
|
path: isWebComponent
|
|
14
|
-
? path.join(process.cwd(), `${destination}/bundle/${
|
|
16
|
+
? path.join(process.cwd(), `${destination}/bundle/${bundleDir}`)
|
|
15
17
|
: path.join(process.cwd(), `${destination}/bundle`),
|
|
16
18
|
};
|
|
17
19
|
|