@servicetitan/startup 31.0.0 → 31.2.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/bin/index.js +8 -0
- 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/utils/log.d.ts +1 -0
- package/dist/utils/log.d.ts.map +1 -1
- package/dist/utils/log.js +9 -0
- package/dist/utils/log.js.map +1 -1
- package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
- package/dist/webpack/configs/dev-server-config.js +11 -0
- package/dist/webpack/configs/dev-server-config.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/__tests__/log.test.ts +8 -0
- package/src/utils/get-configuration.ts +12 -0
- package/src/utils/log.ts +10 -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 +113 -42
- package/src/webpack/configs/dev-server-config.ts +13 -1
- 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
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { fs, vol } from 'memfs';
|
|
1
2
|
import { swcDir } from '@swc/cli';
|
|
2
|
-
import { getSwcCompilePackageConfiguration, log
|
|
3
|
+
import { getSwcCompilePackageConfiguration, log } from '../../../utils';
|
|
3
4
|
import { SwcCompilePackage } from '../swc-compile-package';
|
|
4
|
-
import { compilerOptions } from '../../../../tsconfig/base.json';
|
|
5
5
|
import deepmerge from 'deepmerge';
|
|
6
6
|
|
|
7
|
+
jest.mock('fs', () => fs);
|
|
7
8
|
jest.mock('@swc/cli', () => ({
|
|
8
9
|
swcDir: jest.fn(),
|
|
9
10
|
}));
|
|
@@ -15,9 +16,7 @@ jest.mock('../../../utils', () => ({
|
|
|
15
16
|
destination: 'dist',
|
|
16
17
|
}),
|
|
17
18
|
log: { info: jest.fn(), text: jest.fn() },
|
|
18
|
-
|
|
19
|
-
readJson: jest.fn().mockReturnValue({}),
|
|
20
|
-
getSwcCompilePackageConfiguration: jest.fn().mockReturnValue({}),
|
|
19
|
+
getSwcCompilePackageConfiguration: jest.fn(),
|
|
21
20
|
}));
|
|
22
21
|
|
|
23
22
|
function overwriteMerge(_destinationArray: unknown[], sourceArray: unknown[]) {
|
|
@@ -25,12 +24,27 @@ function overwriteMerge(_destinationArray: unknown[], sourceArray: unknown[]) {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
describe(`[startup] ${SwcCompilePackage.name} task`, () => {
|
|
27
|
+
function volumeFromJSON(overrides: Record<string, any> = {}) {
|
|
28
|
+
return vol.fromJSON({
|
|
29
|
+
'package.json': JSON.stringify({}),
|
|
30
|
+
'tsconfig.json': JSON.stringify({}),
|
|
31
|
+
...Object.fromEntries(
|
|
32
|
+
Object.entries(overrides).map(([key, value]) => [key, JSON.stringify(value)])
|
|
33
|
+
),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
beforeEach(() => {
|
|
29
38
|
globalThis.performance.clearMarks();
|
|
30
39
|
globalThis.performance.clearMeasures();
|
|
31
40
|
jest.clearAllMocks();
|
|
41
|
+
|
|
42
|
+
jest.mocked(getSwcCompilePackageConfiguration).mockReturnValue({});
|
|
43
|
+
volumeFromJSON();
|
|
32
44
|
});
|
|
33
45
|
|
|
46
|
+
afterEach(() => vol.reset());
|
|
47
|
+
|
|
34
48
|
let watch = false;
|
|
35
49
|
|
|
36
50
|
const subject = () => new SwcCompilePackage({ watch }).execute();
|
|
@@ -70,8 +84,8 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
|
|
|
70
84
|
'**/__tests__/*',
|
|
71
85
|
'**/*.test.*',
|
|
72
86
|
'**/__mocks__/*',
|
|
87
|
+
'**/*.stories.*',
|
|
73
88
|
],
|
|
74
|
-
copyFiles: true,
|
|
75
89
|
},
|
|
76
90
|
swcOptions: {
|
|
77
91
|
jsc: {
|
|
@@ -80,16 +94,12 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
|
|
|
80
94
|
tsx: true,
|
|
81
95
|
decorators: true,
|
|
82
96
|
},
|
|
83
|
-
target: compilerOptions.target,
|
|
84
97
|
transform: {
|
|
85
|
-
legacyDecorator: compilerOptions.experimentalDecorators,
|
|
86
|
-
decoratorMetadata: compilerOptions.emitDecoratorMetadata,
|
|
87
98
|
react: {
|
|
88
99
|
runtime: 'automatic',
|
|
89
100
|
},
|
|
90
101
|
},
|
|
91
102
|
},
|
|
92
|
-
sourceMaps: compilerOptions.sourceMap,
|
|
93
103
|
module: {
|
|
94
104
|
type: 'es6',
|
|
95
105
|
},
|
|
@@ -119,10 +129,59 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
|
|
|
119
129
|
itCallsSwcDir(overrides);
|
|
120
130
|
});
|
|
121
131
|
|
|
132
|
+
describe('when tsconfig contains "exclude"', () => {
|
|
133
|
+
const exclude = ['**/stories.*'];
|
|
134
|
+
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
volumeFromJSON({
|
|
137
|
+
'base.json': { exclude },
|
|
138
|
+
'tsconfig.build.json': { extends: './base' },
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('uses exclude config', () => {
|
|
143
|
+
subject();
|
|
144
|
+
|
|
145
|
+
expect(swcDir).toHaveBeenCalledWith(
|
|
146
|
+
expect.objectContaining({
|
|
147
|
+
cliOptions: expect.objectContaining({ ignore: exclude }),
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe.each(
|
|
154
|
+
Object.entries({
|
|
155
|
+
target: 'jsc.target',
|
|
156
|
+
experimentalDecorators: 'jsc.transform.legacyDecorator',
|
|
157
|
+
emitDecoratorMetadata: 'jsc.transform.decoratorMetadata',
|
|
158
|
+
sourceMap: 'sourceMaps',
|
|
159
|
+
})
|
|
160
|
+
)('when tsconfig contains "compilerOptions.%s"', (compilerOption, swcOption) => {
|
|
161
|
+
beforeEach(() => {
|
|
162
|
+
volumeFromJSON({
|
|
163
|
+
'tsconfig.json': { compilerOptions: { [compilerOption]: 'foo' } },
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test(`configures swcOptions.${swcOption}`, () => {
|
|
168
|
+
subject();
|
|
169
|
+
|
|
170
|
+
const keys = swcOption.split('.').toReversed();
|
|
171
|
+
const expected = keys.slice(1).reduce(
|
|
172
|
+
(result, key) => {
|
|
173
|
+
return expect.objectContaining({ [key]: result });
|
|
174
|
+
},
|
|
175
|
+
expect.objectContaining({ [keys[0]]: 'foo' })
|
|
176
|
+
);
|
|
177
|
+
expect(swcDir).toHaveBeenCalledWith(expect.objectContaining({ swcOptions: expected }));
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
122
181
|
describe('when package is commonjs', () => {
|
|
123
182
|
beforeEach(() => {
|
|
124
|
-
|
|
125
|
-
compilerOptions: { module: 'commonjs' },
|
|
183
|
+
volumeFromJSON({
|
|
184
|
+
'tsconfig.json': { compilerOptions: { module: 'commonjs' } },
|
|
126
185
|
});
|
|
127
186
|
});
|
|
128
187
|
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { swcDir } from '@swc/cli';
|
|
2
2
|
import deepmerge from 'deepmerge';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { getFolders, getSwcCompilePackageConfiguration, getTsConfig, log } from '../../utils';
|
|
5
|
+
import { TSConfig } from '../utils';
|
|
5
6
|
import { Task } from './task';
|
|
6
|
-
import { getFolders, getSwcCompilePackageConfiguration, log, readJson } from '../../utils';
|
|
7
7
|
|
|
8
8
|
interface Args {
|
|
9
9
|
[key: string]: unknown;
|
|
10
10
|
watch?: boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function toLowerCase(input: string | undefined): string | undefined {
|
|
14
|
-
return input?.toLowerCase();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
13
|
function overwriteMerge(_destinationArray: unknown[], sourceArray: unknown[]) {
|
|
18
14
|
return sourceArray;
|
|
19
15
|
}
|
|
@@ -25,8 +21,20 @@ export class SwcCompilePackage extends Task {
|
|
|
25
21
|
|
|
26
22
|
async execute(): Promise<void> {
|
|
27
23
|
const { source, destination } = getFolders();
|
|
28
|
-
const compilerOptions = readJson('tsconfig.json').compilerOptions ?? {};
|
|
29
24
|
const packageConfig = getSwcCompilePackageConfiguration();
|
|
25
|
+
const tsConfig = new TSConfig(getTsConfig());
|
|
26
|
+
const target = tsConfig.getValue('compilerOptions.target');
|
|
27
|
+
const legacyDecorator = tsConfig.getValue('compilerOptions.experimentalDecorators');
|
|
28
|
+
const decoratorMetadata = tsConfig.getValue('compilerOptions.emitDecoratorMetadata');
|
|
29
|
+
const sourceMaps = tsConfig.getValue('compilerOptions.sourceMap');
|
|
30
|
+
const module = tsConfig.getValue<string>('compilerOptions.module')?.toLowerCase();
|
|
31
|
+
const ignore = tsConfig.getValue('exclude', [
|
|
32
|
+
'**/*.d.ts',
|
|
33
|
+
'**/__tests__/*',
|
|
34
|
+
'**/*.test.*',
|
|
35
|
+
'**/__mocks__/*',
|
|
36
|
+
'**/*.stories.*',
|
|
37
|
+
]);
|
|
30
38
|
|
|
31
39
|
return new Promise((resolve, reject) => {
|
|
32
40
|
swcDir(
|
|
@@ -38,13 +46,7 @@ export class SwcCompilePackage extends Task {
|
|
|
38
46
|
stripLeadingPaths: true,
|
|
39
47
|
extensions: ['.ts', '.tsx'],
|
|
40
48
|
filenames: [source],
|
|
41
|
-
ignore
|
|
42
|
-
'**/*.d.ts',
|
|
43
|
-
'**/__tests__/*',
|
|
44
|
-
'**/*.test.*',
|
|
45
|
-
'**/__mocks__/*',
|
|
46
|
-
],
|
|
47
|
-
copyFiles: true,
|
|
49
|
+
ignore,
|
|
48
50
|
},
|
|
49
51
|
swcOptions: {
|
|
50
52
|
jsc: {
|
|
@@ -53,20 +55,19 @@ export class SwcCompilePackage extends Task {
|
|
|
53
55
|
tsx: true,
|
|
54
56
|
decorators: true,
|
|
55
57
|
},
|
|
56
|
-
target
|
|
58
|
+
target,
|
|
57
59
|
transform: {
|
|
58
|
-
legacyDecorator
|
|
59
|
-
decoratorMetadata
|
|
60
|
+
legacyDecorator,
|
|
61
|
+
decoratorMetadata,
|
|
60
62
|
react: {
|
|
61
63
|
runtime: 'automatic',
|
|
62
64
|
},
|
|
63
65
|
},
|
|
64
66
|
},
|
|
65
|
-
sourceMaps
|
|
67
|
+
sourceMaps,
|
|
66
68
|
module: {
|
|
67
69
|
type:
|
|
68
|
-
|
|
69
|
-
toLowerCase(compilerOptions.module) === 'nodenext'
|
|
70
|
+
module === 'commonjs' || module === 'nodenext'
|
|
70
71
|
? 'commonjs'
|
|
71
72
|
: 'es6',
|
|
72
73
|
},
|
|
@@ -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,
|
|
@@ -14,6 +14,14 @@ describe(`[startup] Utils`, () => {
|
|
|
14
14
|
stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(jest.fn());
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
test('timestamp() returns the current time in the HH:MM:SS.SSS format', () => {
|
|
18
|
+
jest.useFakeTimers({
|
|
19
|
+
now: new Date('2024-05-14 10:40:00.050'),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(log.timestamp).toBe('10:40:00.050');
|
|
23
|
+
});
|
|
24
|
+
|
|
17
25
|
test('text() writes default text', () => {
|
|
18
26
|
log.text(message);
|
|
19
27
|
|
|
@@ -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
|
}
|
package/src/utils/log.ts
CHANGED
|
@@ -10,6 +10,16 @@ class Log {
|
|
|
10
10
|
this.debugMap = new Map<string, Debugger>();
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
get timestamp() {
|
|
14
|
+
return new Date().toLocaleTimeString(undefined, {
|
|
15
|
+
hour12: false,
|
|
16
|
+
hour: '2-digit',
|
|
17
|
+
minute: '2-digit',
|
|
18
|
+
second: '2-digit',
|
|
19
|
+
fractionalSecondDigits: 3,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
text(...text: string[]) {
|
|
14
24
|
process.stdout.write(chalk(...text) + '\n');
|
|
15
25
|
}
|