@servicetitan/startup 22.16.0 → 22.17.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.
Files changed (41) hide show
  1. package/dist/__mocks__/create-package.d.ts +3 -0
  2. package/dist/__mocks__/create-package.d.ts.map +1 -0
  3. package/dist/{cli/__mocks__ → __mocks__}/create-package.js +4 -2
  4. package/dist/__mocks__/create-package.js.map +1 -0
  5. package/dist/__mocks__/index.d.ts.map +1 -0
  6. package/dist/__mocks__/index.js.map +1 -0
  7. package/dist/cli/index.js +25 -23
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/utils/set-node-options.d.ts +2 -1
  10. package/dist/cli/utils/set-node-options.d.ts.map +1 -1
  11. package/dist/cli/utils/set-node-options.js.map +1 -1
  12. package/dist/utils/get-configuration.d.ts +23 -6
  13. package/dist/utils/get-configuration.d.ts.map +1 -1
  14. package/dist/utils/get-configuration.js +19 -1
  15. package/dist/utils/get-configuration.js.map +1 -1
  16. package/package.json +4 -4
  17. package/src/{cli/__mocks__ → __mocks__}/create-package.ts +3 -2
  18. package/src/cli/commands/__tests__/build.test.ts +1 -1
  19. package/src/cli/commands/__tests__/init.test.ts +2 -1
  20. package/src/cli/commands/__tests__/mfe-publish.test.ts +1 -1
  21. package/src/cli/commands/__tests__/start.test.ts +1 -1
  22. package/src/cli/commands/__tests__/styles-check.test.ts +2 -1
  23. package/src/cli/index.ts +28 -40
  24. package/src/cli/utils/__tests__/bundle.test.ts +1 -1
  25. package/src/cli/utils/__tests__/set-node-options.test.ts +2 -1
  26. package/src/cli/utils/__tests__/tsc.test.ts +1 -1
  27. package/src/cli/utils/set-node-options.ts +2 -2
  28. package/src/utils/__tests__/get-jest-config.test.ts +2 -1
  29. package/src/utils/get-configuration.ts +26 -9
  30. package/src/webpack/__tests__/create-development-config.test.ts +306 -0
  31. package/src/webpack/__tests__/create-production-config.test.ts +231 -0
  32. package/src/webpack/__tests__/create-shared-config.test.ts +508 -0
  33. package/src/webpack/__tests__/create-webpack-config.test.ts +74 -0
  34. package/dist/cli/__mocks__/create-package.d.ts +0 -3
  35. package/dist/cli/__mocks__/create-package.d.ts.map +0 -1
  36. package/dist/cli/__mocks__/create-package.js.map +0 -1
  37. package/dist/cli/__mocks__/index.d.ts.map +0 -1
  38. package/dist/cli/__mocks__/index.js.map +0 -1
  39. /package/dist/{cli/__mocks__ → __mocks__}/index.d.ts +0 -0
  40. /package/dist/{cli/__mocks__ → __mocks__}/index.js +0 -0
  41. /package/src/{cli/__mocks__ → __mocks__}/index.ts +0 -0
@@ -0,0 +1,508 @@
1
+ import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
2
+ import HtmlWebpackPlugin from 'html-webpack-plugin';
3
+ import mockFS from 'mock-fs';
4
+ import MomentLocalesPlugin from 'moment-locales-webpack-plugin';
5
+ import os from 'os';
6
+ import path from 'path';
7
+ import { DefinePlugin, ProvidePlugin } from 'webpack';
8
+ import WebpackAssetsManifest from 'webpack-assets-manifest';
9
+ import VirtualModulesPlugin from 'webpack-virtual-modules';
10
+ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
11
+ const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');
12
+ import { argv } from 'yargs';
13
+ import {
14
+ getFolders,
15
+ getPackageData,
16
+ getPackageDependencyVersion,
17
+ getTsConfig,
18
+ isExposeSharedDependencies,
19
+ isWebComponent,
20
+ loadSharedDependencies,
21
+ } from '../../utils';
22
+ import { getModuleEntryPath } from '../utils/bundle';
23
+ import { splitByEntry } from '../utils/split-by-entry';
24
+
25
+ import { createConfig as createSharedConfig } from '../shared.config';
26
+
27
+ jest.mock('fork-ts-checker-webpack-plugin', () => jest.fn());
28
+ jest.mock('html-webpack-plugin', () => jest.fn());
29
+ jest.mock('moment-locales-webpack-plugin', () => jest.fn());
30
+ jest.mock('webpack', () => ({
31
+ ...jest.requireActual('webpack'),
32
+ DefinePlugin: jest.fn(),
33
+ ProvidePlugin: jest.fn(),
34
+ }));
35
+ jest.mock('webpack-assets-manifest', () => jest.fn());
36
+ jest.mock('webpack-bundle-analyzer', () => ({ BundleAnalyzerPlugin: jest.fn() }));
37
+ jest.mock('webpack-filter-warnings-plugin', () => jest.fn());
38
+ jest.mock('webpack-virtual-modules', () => jest.fn());
39
+ jest.mock('yargs', () => ({ argv: {} }));
40
+ jest.mock('../../utils', () => ({
41
+ ...jest.requireActual('../../utils'),
42
+ getFolders: jest.fn(),
43
+ getPackageData: jest.fn(),
44
+ getPackageDependencyVersion: jest.fn(),
45
+ getTsConfig: jest.fn(),
46
+ loadSharedDependencies: jest.fn(),
47
+ isExposeSharedDependencies: jest.fn(),
48
+ isWebComponent: jest.fn(),
49
+ }));
50
+ jest.mock('../utils/bundle', () => ({
51
+ ...jest.requireActual('../utils/bundle'),
52
+ getModuleEntryPath: jest.fn(),
53
+ }));
54
+
55
+ describe('createSharedConfig', () => {
56
+ const source = 'src';
57
+ const destination = 'dist';
58
+ const tsConfig = 'tsconfig.build.json';
59
+
60
+ let overrides: Parameters<typeof createSharedConfig>[0];
61
+ let options: Parameters<typeof createSharedConfig>[1];
62
+
63
+ function mockPlugIn(name: string) {
64
+ return (options: Record<string, any>): any => ({ [name]: options });
65
+ }
66
+
67
+ beforeEach(() => {
68
+ overrides = {
69
+ configuration: { mode: 'production' },
70
+ plugins: {
71
+ ForkTsCheckerWebpackPlugin: { logger: 'webpack-infrastructure' },
72
+ HtmlWebpackPlugin: { favicon: 'foo' },
73
+ },
74
+ };
75
+ options = { name: '' };
76
+
77
+ jest.resetAllMocks();
78
+ jest.mocked(BundleAnalyzerPlugin).mockImplementation(mockPlugIn('BundleAnalyzerPlugin'));
79
+ jest.mocked(DefinePlugin).mockImplementation(mockPlugIn('DefinePlugin'));
80
+ jest.mocked(FilterWarningsPlugin).mockImplementation(mockPlugIn('FilterWarningsPlugin'));
81
+ jest.mocked(ForkTsCheckerWebpackPlugin).mockImplementation(
82
+ mockPlugIn('ForkTsCheckerWebpackPlugin')
83
+ );
84
+ jest.mocked(HtmlWebpackPlugin).mockImplementation(mockPlugIn('HtmlWebpackPlugin'));
85
+ jest.mocked(MomentLocalesPlugin).mockImplementation(mockPlugIn('MomentLocalesPlugin'));
86
+ jest.mocked(ProvidePlugin).mockImplementation(mockPlugIn('ProvidePlugin'));
87
+ jest.mocked(VirtualModulesPlugin).mockImplementation(mockPlugIn('VirtualModulesPlugin'));
88
+ jest.mocked(WebpackAssetsManifest).mockImplementation(mockPlugIn('WebpackAssetsManifest'));
89
+
90
+ jest.mocked(getFolders).mockReturnValue({ source, destination });
91
+ jest.mocked(getPackageData).mockReturnValue({ dependencies: {}, sharedDependencies: {} });
92
+ jest.mocked(getTsConfig).mockReturnValue(tsConfig);
93
+ jest.mocked(loadSharedDependencies).mockReturnValue({});
94
+
95
+ Object.keys(argv).forEach(key => delete (argv as any)[key]);
96
+ });
97
+
98
+ const subject = () => createSharedConfig(overrides, options);
99
+
100
+ test('includes input configuration', () => {
101
+ expect(subject()).toEqual(expect.objectContaining(overrides.configuration));
102
+ });
103
+
104
+ test('configures "resolve"', () => {
105
+ expect(subject().resolve).toEqual({ extensions: ['.js', '.jsx', '.ts', '.tsx'] });
106
+ });
107
+
108
+ test('configures "entry"', () => {
109
+ expect(subject().entry).toEqual({ main: [`./${source}/index`] });
110
+ });
111
+
112
+ Object.entries({
113
+ '.js': {
114
+ test: /\.js$/,
115
+ enforce: 'pre',
116
+ exclude: /node_modules/,
117
+ loader: 'source-map-loader',
118
+ },
119
+ '.worker.js': {
120
+ test: /\.worker\.js$/,
121
+ use: { loader: 'worker-loader' },
122
+ },
123
+ 'images': {
124
+ test: /\.(png|svg|jpg|jpeg|gif)$/i,
125
+ type: 'asset',
126
+ generator: { filename: 'images/[contenthash][ext][query]' },
127
+ },
128
+ 'fonts': {
129
+ test: /\.(woff|woff2|eot|ttf|otf)$/i,
130
+ type: 'asset/resource',
131
+ generator: { filename: 'fonts/[contenthash][ext][query]' },
132
+ },
133
+ '.tsx': {
134
+ test: /\.tsx?$/,
135
+ exclude: /node_modules/,
136
+ use: [{ loader: 'ts-loader', options: { transpileOnly: true } }],
137
+ },
138
+ }).forEach(([extension, rule]) => {
139
+ test(`configures "${extension}" rules`, () => {
140
+ expect(subject().module?.rules).toContainEqual(rule);
141
+ });
142
+ });
143
+
144
+ test('configures "output.path"', () => {
145
+ expect(subject().output!.path).toEqual(
146
+ expect.stringContaining(path.join(destination, 'bundle'))
147
+ );
148
+ });
149
+
150
+ test('configures "optimization"', () => {
151
+ expect(subject().optimization).toEqual({
152
+ chunkIds: 'size',
153
+ moduleIds: 'size',
154
+ mangleExports: 'size',
155
+ splitChunks: { cacheGroups: {} },
156
+ });
157
+ });
158
+
159
+ test('configures "stats"', () => {
160
+ expect(subject().stats).toEqual({
161
+ all: false,
162
+ errors: true,
163
+ errorDetails: true,
164
+ warnings: true,
165
+ builtAt: true,
166
+ colors: true,
167
+ });
168
+ });
169
+
170
+ test('configures MomentLocalesPlugin plugin', () => {
171
+ expect(subject().plugins).toContainEqual(
172
+ new MomentLocalesPlugin({ localesToKeep: ['en-au', 'en-ca', 'en-gb'] })
173
+ );
174
+ });
175
+
176
+ test('configures ForkTsCheckerWebpackPlugin plugin', () => {
177
+ expect(subject().plugins).toContainEqual(
178
+ new ForkTsCheckerWebpackPlugin({
179
+ typescript: {
180
+ configFile: tsConfig,
181
+ configOverwrite: {
182
+ exclude: [
183
+ '**/__tests__/**/*',
184
+ '**/__mocks__/**/*',
185
+ '**/*.test.*',
186
+ '**/*.stories.tsx',
187
+ ],
188
+ references: [],
189
+ },
190
+ },
191
+ ...overrides.plugins?.ForkTsCheckerWebpackPlugin,
192
+ })
193
+ );
194
+ });
195
+
196
+ test('configures FilterWarningsPlugin plugin', () => {
197
+ expect(subject().plugins).toContainEqual(
198
+ new FilterWarningsPlugin({
199
+ exclude: /export .* was not found in/,
200
+ })
201
+ );
202
+ });
203
+
204
+ const defaultHtmlWebpackPluginOptions: ConstructorParameters<typeof HtmlWebpackPlugin>[0] = {
205
+ title: 'ServiceTitan',
206
+ hash: true,
207
+ templateParameters: { splitByEntry },
208
+ };
209
+
210
+ test('configures HtmlWebpackPlugin plugin', () => {
211
+ expect(subject().plugins).toContainEqual(
212
+ new HtmlWebpackPlugin({
213
+ ...defaultHtmlWebpackPluginOptions,
214
+ ...overrides.plugins?.HtmlWebpackPlugin,
215
+ })
216
+ );
217
+ });
218
+
219
+ describe('when package is web component', () => {
220
+ const designSystemPath = () => path.join(process.cwd(), `${source}/design-system.css`);
221
+ const designSystemCode = [
222
+ `@import '~@servicetitan/tokens/core/tokens.css';`,
223
+ `@import '~@servicetitan/anvil-fonts/dist/css/anvil-fonts.css';`,
224
+ `@import '~@servicetitan/design-system/dist/system.min.css';`,
225
+ ].join('\n');
226
+
227
+ const indexPath = () => path.join(process.cwd(), `${source}/index.ts`);
228
+ const indexCode = [
229
+ `import { register } from '@servicetitan/web-components';`,
230
+ `import { App } from './app';`,
231
+ `require('./design-system.css');`,
232
+ `register(App, false);`,
233
+ ].join('\n');
234
+
235
+ beforeEach(() => jest.mocked(isWebComponent).mockReturnValue(true));
236
+
237
+ test('configures WEB_COMPONENT_NAME', () => {
238
+ expect(subject().plugins).toContainEqual(
239
+ // eslint-disable-next-line @typescript-eslint/naming-convention
240
+ new DefinePlugin({ WEB_COMPONENT_NAME: JSON.stringify(options.name) })
241
+ );
242
+ });
243
+
244
+ test('configures WebpackAssetsManifest plugin', () => {
245
+ expect(subject().plugins).toContainEqual(
246
+ new WebpackAssetsManifest({
247
+ entrypoints: true,
248
+ output: 'entrypoints.json',
249
+ transform: expect.any(Function),
250
+ })
251
+ );
252
+ });
253
+
254
+ test('WebpackAssetsManifest plugin groups assets by type', () => {
255
+ const assets = {
256
+ entrypoints: {
257
+ foo: { assets: { css: ['bar.css'] } },
258
+ baz: { assets: { js: ['qux.js'] } },
259
+ },
260
+ };
261
+
262
+ subject();
263
+
264
+ const transform: any = jest.mocked(WebpackAssetsManifest).mock.calls[0][0]?.transform;
265
+ expect(transform(assets)).toEqual({
266
+ css: ['bar.css'],
267
+ js: ['qux.js'],
268
+ });
269
+ });
270
+
271
+ test('configures HtmlWebpackPlugin plugin with additional properties', () => {
272
+ expect(subject().plugins).toContainEqual(
273
+ new HtmlWebpackPlugin({
274
+ ...defaultHtmlWebpackPluginOptions,
275
+ ...overrides.plugins?.HtmlWebpackPlugin,
276
+ inject: false,
277
+ publicPath: '/',
278
+ templateContent: expect.any(Function),
279
+ })
280
+ );
281
+ });
282
+
283
+ test('configures HtmlWebpackPlugin plugin to render template content', () => {
284
+ const headTags = '{headTags}';
285
+ const bodyTags = '{bodyTags}';
286
+ const files = { css: ['foo.css'] };
287
+ const styleUrls = encodeURIComponent(JSON.stringify(files.css));
288
+ const template = `
289
+ <!DOCTYPE html>
290
+ <html>
291
+ <head>
292
+ <meta name="viewport" content="width=device-width,initial-scale=1">
293
+ ${headTags}
294
+ </head>
295
+ <body>
296
+ <${options.name} style-urls="${styleUrls}" />
297
+ ${bodyTags}
298
+ </body>
299
+ </html>
300
+ `;
301
+
302
+ subject();
303
+
304
+ const templateContent: any =
305
+ jest.mocked(HtmlWebpackPlugin).mock.calls[0][0]?.templateContent;
306
+ expect(
307
+ templateContent({
308
+ htmlWebpackPlugin: { tags: { headTags, bodyTags }, files },
309
+ }).replace(/\n\s+/g, '\n')
310
+ ).toEqual(template.replace(/\n\s+/g, '\n'));
311
+ });
312
+
313
+ test(`configures virtual modules`, () => {
314
+ expect(subject().plugins).toContainEqual(
315
+ new VirtualModulesPlugin({
316
+ [designSystemPath()]: designSystemCode,
317
+ [indexPath()]: indexCode,
318
+ })
319
+ );
320
+ });
321
+
322
+ test('appends "/full" to output path', () => {
323
+ expect(subject().output?.path).toEqual(
324
+ expect.stringContaining(path.join(destination, 'bundle', 'full'))
325
+ );
326
+ });
327
+
328
+ test('configures "optimization.splitChunks.cacheGroups.styles', () => {
329
+ expect((subject().optimization?.splitChunks as any).cacheGroups.styles).toEqual({
330
+ name: 'main',
331
+ type: 'css/mini-extract',
332
+ chunks: 'all',
333
+ enforce: true,
334
+ });
335
+ });
336
+
337
+ describe('when design-system.css exists', () => {
338
+ beforeEach(() => mockFS({ [source]: { 'design-system.css': '' } }));
339
+ afterEach(() => mockFS.restore());
340
+
341
+ test('omits design system virtual module', () => {
342
+ expect(subject().plugins).toContainEqual(
343
+ new VirtualModulesPlugin({
344
+ [indexPath()]: indexCode,
345
+ })
346
+ );
347
+ });
348
+ });
349
+
350
+ describe('when embed option is set to true', () => {
351
+ beforeEach(() => (options.embed = true));
352
+
353
+ test(`changes virtual index module to omit design system and to register App`, () => {
354
+ expect(subject().plugins).toContainEqual(
355
+ new VirtualModulesPlugin({
356
+ [designSystemPath()]: designSystemCode,
357
+ [indexPath()]: indexCode
358
+ .replace("require('./design-system.css');\n", '')
359
+ .replace('register(App, false)', 'register(App, true)'),
360
+ })
361
+ );
362
+ });
363
+
364
+ test('appends "/light" to output path', () => {
365
+ expect(subject().output?.path).toEqual(
366
+ expect.stringContaining(path.join(destination, 'bundle', 'light'))
367
+ );
368
+ });
369
+ });
370
+ });
371
+
372
+ describe('when package exposes shared dependencies', () => {
373
+ const sharedDependencies = {
374
+ '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
375
+ 'react': 'SharedDependencies.React',
376
+ };
377
+ const dependencies: Record<string, string> = {
378
+ '@servicetitan/design-system': '1.2.3',
379
+ 'react': '4.5.6',
380
+ };
381
+
382
+ beforeEach(() => {
383
+ jest.mocked(isExposeSharedDependencies).mockReturnValue(true);
384
+ jest.mocked(loadSharedDependencies).mockReturnValue(sharedDependencies);
385
+ jest.mocked(getModuleEntryPath).mockImplementation(name => `${name}/entryPath`);
386
+ jest.mocked(getPackageData).mockReturnValue({ dependencies, sharedDependencies });
387
+ jest.mocked(getPackageDependencyVersion).mockImplementation(
388
+ (_, defaultVersion) => defaultVersion
389
+ );
390
+ });
391
+
392
+ test('configures EXPOSE_DEPENDENCIES', () => {
393
+ const exposedDependencies = Object.fromEntries(
394
+ Object.entries(sharedDependencies).map(([name, variable]) => [
395
+ name,
396
+ {
397
+ version: getPackageDependencyVersion(name, dependencies[name]),
398
+ variable,
399
+ },
400
+ ])
401
+ );
402
+ expect(subject().plugins).toContainEqual(
403
+ new DefinePlugin({
404
+ // eslint-disable-next-line @typescript-eslint/naming-convention
405
+ EXPOSED_DEPENDENCIES: JSON.stringify(exposedDependencies),
406
+ })
407
+ );
408
+ });
409
+
410
+ test('configures shared dependency entry points', () => {
411
+ expect(subject().entry).toEqual({
412
+ main: expect.arrayContaining(
413
+ Object.keys(sharedDependencies).map(getModuleEntryPath)
414
+ ),
415
+ });
416
+ });
417
+
418
+ test('configures shared dependencies to use expose-loader', () => {
419
+ Object.entries(sharedDependencies).forEach(([name, value]) => {
420
+ expect(subject().module?.rules).toContainEqual({
421
+ test: getModuleEntryPath(name),
422
+ loader: require.resolve('../loaders/expose-loader'),
423
+ options: { exposes: value },
424
+ });
425
+ });
426
+ });
427
+
428
+ test('configures "optimization.splitChunks.cacheGroups.design-system"', () => {
429
+ expect(
430
+ (subject().optimization?.splitChunks as any).cacheGroups['design-system']
431
+ ).toEqual({
432
+ test: /[\\/]node_modules[\\/]@servicetitan[\\/](tokens|anvil-fonts|design-system)[\\/].*\.css$/,
433
+ name: 'design-system',
434
+ chunks: 'all',
435
+ enforce: true,
436
+ });
437
+ });
438
+
439
+ describe('when embed option is set to true', () => {
440
+ beforeEach(() => (options.embed = true));
441
+
442
+ test('configures "externals"', () => {
443
+ expect(subject().externals).toEqual(
444
+ Object.fromEntries(
445
+ Object.entries(sharedDependencies).map(([name, value]) => [
446
+ name,
447
+ `${value}['${options.name}']`,
448
+ ])
449
+ )
450
+ );
451
+ });
452
+ });
453
+ });
454
+
455
+ describe('when buildStat option is set to true', () => {
456
+ beforeEach(() => {
457
+ options.buildStat = true;
458
+ jest.useFakeTimers();
459
+ jest.spyOn(os, 'tmpdir').mockReturnValue('tmpdir');
460
+ });
461
+
462
+ const reportFilename = (type: string) =>
463
+ path.join(os.tmpdir(), `report-${type}-bundle-${Date.now()}.html`);
464
+
465
+ test('configures BundleAnalyzerPlugin plugin', () => {
466
+ expect(subject().plugins).toContainEqual(
467
+ new BundleAnalyzerPlugin({
468
+ analyzerMode: 'static',
469
+ reportFilename: reportFilename('full'),
470
+ })
471
+ );
472
+ });
473
+
474
+ describe('when embed option is set to true', () => {
475
+ beforeEach(() => (options.embed = true));
476
+
477
+ test('changes BundleAnalyzerPlugin reportFilename from "full" to "light"', () => {
478
+ expect(subject().plugins).toContainEqual(
479
+ new BundleAnalyzerPlugin({
480
+ analyzerMode: 'static',
481
+ reportFilename: reportFilename('light'),
482
+ })
483
+ );
484
+ });
485
+ });
486
+ });
487
+
488
+ describe('with --esbuild command line argument', () => {
489
+ beforeEach(() => Object.assign(argv, { esbuild: true }));
490
+
491
+ test('configures ".tsx" rules to use esbuild-loader', () => {
492
+ expect(subject().module?.rules).toContainEqual({
493
+ test: /\.tsx?$/,
494
+ exclude: /node_modules/,
495
+ use: [
496
+ {
497
+ loader: 'esbuild-loader',
498
+ options: { loader: 'tsx', target: 'es2018' },
499
+ },
500
+ ],
501
+ });
502
+ });
503
+
504
+ test('configures React to load automatically', () => {
505
+ expect(subject().plugins).toContainEqual(new ProvidePlugin({ React: 'react' }));
506
+ });
507
+ });
508
+ });
@@ -0,0 +1,74 @@
1
+ import { Configuration } from 'webpack';
2
+ import { webpackDevConfigFileName, webpackProdConfigFileName } from '../../cli/utils';
3
+ import { isWebComponent } from '../../utils';
4
+ import { createConfig as createDevelopmentConfig } from '../development.config';
5
+ import { createConfig as createProductionConfig } from '../production.config';
6
+ import { getCallerFile } from '../utils/get-caller-filename';
7
+
8
+ import { createWebpackConfig } from '../index';
9
+
10
+ jest.mock('../../utils', () => ({
11
+ ...jest.requireActual('../../utils'),
12
+ isWebComponent: jest.fn(),
13
+ }));
14
+ jest.mock('../development.config');
15
+ jest.mock('../production.config');
16
+ jest.mock('../utils/get-caller-filename');
17
+
18
+ describe(`${createWebpackConfig.name}`, () => {
19
+ const developmentConfig: Configuration = { devServer: { port: 8080 } };
20
+ const productionConfig: Configuration = { output: { clean: true } };
21
+
22
+ let overrides: Parameters<typeof createWebpackConfig>[0];
23
+ let options: Parameters<typeof createWebpackConfig>[1];
24
+
25
+ beforeEach(() => {
26
+ jest.mocked(createDevelopmentConfig).mockReturnValue(developmentConfig);
27
+ jest.mocked(createProductionConfig).mockReturnValue(productionConfig);
28
+ jest.mocked(getCallerFile).mockReturnValue('');
29
+ options = { buildStat: false };
30
+ });
31
+
32
+ const subject = () => createWebpackConfig(overrides, options);
33
+
34
+ describe('when mode is "development"', () => {
35
+ beforeEach(() => (overrides = { configuration: { mode: 'development' } }));
36
+
37
+ test('returns development config', () => {
38
+ expect(subject()).toBe(developmentConfig);
39
+ expect(createDevelopmentConfig).toHaveBeenCalledWith(overrides, {
40
+ embed: false,
41
+ name: '',
42
+ ...options,
43
+ });
44
+ });
45
+ });
46
+
47
+ describe('when mode is "production"', () => {
48
+ beforeEach(() => (overrides = { configuration: { mode: 'production' } }));
49
+
50
+ test('returns production config', () => {
51
+ expect(subject()).toBe(productionConfig);
52
+ expect(createProductionConfig).toHaveBeenCalledWith(overrides, {
53
+ embed: false,
54
+ name: '',
55
+ ...options,
56
+ });
57
+ });
58
+ });
59
+
60
+ describe('when package is webComponent', () => {
61
+ beforeEach(() => jest.mocked(isWebComponent).mockReturnValue(true));
62
+
63
+ describe.each([webpackDevConfigFileName, webpackProdConfigFileName])(
64
+ 'when invoked from "%s"',
65
+ configFileName => {
66
+ beforeEach(() => jest.mocked(getCallerFile).mockReturnValue(configFileName));
67
+
68
+ test('throws error', () => {
69
+ expect(subject).toThrowError(/cannot call createWebpackConfig/);
70
+ });
71
+ }
72
+ );
73
+ });
74
+ });
@@ -1,3 +0,0 @@
1
- import { Package } from '../../utils';
2
- export declare function createPackage(props: Partial<Package>): Package;
3
- //# sourceMappingURL=create-package.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-package.d.ts","sourceRoot":"","sources":["../../../src/cli/__mocks__/create-package.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAEnD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAS9D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-package.js","sourceRoot":"","sources":["../../../src/cli/__mocks__/create-package.ts"],"names":[],"mappings":";;;AAAA,uCAAmD;AAEnD,SAAgB,aAAa,CAAC,KAAuB;IACjD,uBACI,IAAI,EAAE,mBAAmB,EACzB,IAAI,EAAE,mBAAW,CAAC,MAAM,EACxB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,KAAK,EACd,QAAQ,EAAE,cAAc,IACrB,KAAK,EACV;AACN,CAAC;AATD,sCASC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/__mocks__/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC"}
File without changes
File without changes
File without changes