@servicetitan/startup 22.19.0 → 22.21.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 (97) hide show
  1. package/dist/cli/commands/build.d.ts +1 -0
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +1 -0
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/bundle-package.d.ts +5 -3
  6. package/dist/cli/commands/bundle-package.d.ts.map +1 -1
  7. package/dist/cli/commands/bundle-package.js +7 -2
  8. package/dist/cli/commands/bundle-package.js.map +1 -1
  9. package/dist/cli/commands/start.d.ts +5 -4
  10. package/dist/cli/commands/start.d.ts.map +1 -1
  11. package/dist/cli/commands/start.js +3 -0
  12. package/dist/cli/commands/start.js.map +1 -1
  13. package/dist/cli/utils/bundle.d.ts +2 -0
  14. package/dist/cli/utils/bundle.d.ts.map +1 -1
  15. package/dist/cli/utils/bundle.js +14 -7
  16. package/dist/cli/utils/bundle.js.map +1 -1
  17. package/dist/cli/utils/tsc.js +4 -2
  18. package/dist/cli/utils/tsc.js.map +1 -1
  19. package/dist/utils/get-jest-config.js +1 -1
  20. package/dist/utils/get-jest-config.js.map +1 -1
  21. package/dist/webpack/configs/amd-config.d.ts +6 -0
  22. package/dist/webpack/configs/amd-config.d.ts.map +1 -0
  23. package/dist/webpack/configs/amd-config.js +8 -0
  24. package/dist/webpack/configs/amd-config.js.map +1 -0
  25. package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
  26. package/dist/webpack/configs/dev-server-config.js +1 -5
  27. package/dist/webpack/configs/dev-server-config.js.map +1 -1
  28. package/dist/webpack/configs/index.d.ts +1 -0
  29. package/dist/webpack/configs/index.d.ts.map +1 -1
  30. package/dist/webpack/configs/index.js +1 -0
  31. package/dist/webpack/configs/index.js.map +1 -1
  32. package/dist/webpack/configs/plugins/provide-react-plugin.d.ts +1 -1
  33. package/dist/webpack/configs/plugins/provide-react-plugin.d.ts.map +1 -1
  34. package/dist/webpack/configs/plugins/provide-react-plugin.js +2 -2
  35. package/dist/webpack/configs/plugins/provide-react-plugin.js.map +1 -1
  36. package/dist/webpack/configs/rules/tsx-rules.d.ts +1 -1
  37. package/dist/webpack/configs/rules/tsx-rules.d.ts.map +1 -1
  38. package/dist/webpack/configs/rules/tsx-rules.js +27 -7
  39. package/dist/webpack/configs/rules/tsx-rules.js.map +1 -1
  40. package/dist/webpack/configs/types.d.ts +1 -0
  41. package/dist/webpack/configs/types.d.ts.map +1 -1
  42. package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
  43. package/dist/webpack/configs/utils/generate-metadata.js +5 -1
  44. package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
  45. package/dist/webpack/configs/utils/get-web-components-version.d.ts +2 -0
  46. package/dist/webpack/configs/utils/get-web-components-version.d.ts.map +1 -0
  47. package/dist/webpack/configs/utils/get-web-components-version.js +13 -0
  48. package/dist/webpack/configs/utils/get-web-components-version.js.map +1 -0
  49. package/dist/webpack/create-webpack-config.d.ts.map +1 -1
  50. package/dist/webpack/create-webpack-config.js +3 -1
  51. package/dist/webpack/create-webpack-config.js.map +1 -1
  52. package/dist/webpack/types.d.ts +2 -0
  53. package/dist/webpack/types.d.ts.map +1 -1
  54. package/package.json +8 -6
  55. package/src/cli/commands/__tests__/build.test.ts +14 -0
  56. package/src/cli/commands/__tests__/bundle-package.test.ts +8 -4
  57. package/src/cli/commands/__tests__/init.test.ts +5 -4
  58. package/src/cli/commands/__tests__/mfe-package-clean.test.ts +4 -3
  59. package/src/cli/commands/__tests__/mfe-package-publish.test.ts +5 -4
  60. package/src/cli/commands/__tests__/mfe-publish.test.ts +4 -3
  61. package/src/cli/commands/__tests__/start.test.ts +14 -0
  62. package/src/cli/commands/__tests__/styles-check.test.ts +12 -11
  63. package/src/cli/commands/build.ts +2 -0
  64. package/src/cli/commands/bundle-package.ts +13 -5
  65. package/src/cli/commands/start.ts +8 -4
  66. package/src/cli/utils/__tests__/bundle.test.ts +15 -14
  67. package/src/cli/utils/__tests__/eslint.test.ts +11 -4
  68. package/src/cli/utils/__tests__/get-module-type.test.ts +10 -15
  69. package/src/cli/utils/__tests__/is-module-installed.test.ts +6 -7
  70. package/src/cli/utils/__tests__/tcm.test.ts +6 -5
  71. package/src/cli/utils/__tests__/tsc.test.ts +7 -8
  72. package/src/cli/utils/bundle.ts +25 -7
  73. package/src/cli/utils/tsc.ts +7 -9
  74. package/src/utils/__tests__/get-configuration.test.ts +20 -14
  75. package/src/utils/__tests__/get-destination-folders.test.ts +11 -13
  76. package/src/utils/__tests__/get-folders.test.ts +8 -6
  77. package/src/utils/__tests__/get-jest-config.test.ts +1 -1
  78. package/src/utils/__tests__/get-tsconfig.test.ts +6 -4
  79. package/src/utils/__tests__/read-json.test.ts +12 -16
  80. package/src/utils/get-jest-config.ts +1 -1
  81. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +6 -5
  82. package/src/webpack/__tests__/create-webpack-config.test.ts +53 -10
  83. package/src/webpack/configs/amd-config.ts +8 -0
  84. package/src/webpack/configs/dev-server-config.ts +2 -9
  85. package/src/webpack/configs/index.ts +1 -0
  86. package/src/webpack/configs/plugins/provide-react-plugin.ts +2 -2
  87. package/src/webpack/configs/rules/tsx-rules.ts +32 -10
  88. package/src/webpack/configs/types.ts +1 -0
  89. package/src/webpack/configs/utils/__tests__/generate-metadata.test.ts +17 -13
  90. package/src/webpack/configs/utils/__tests__/get-startup-version.test.ts +6 -10
  91. package/src/webpack/configs/utils/__tests__/get-web-components-version.test.ts +25 -0
  92. package/src/webpack/configs/utils/generate-metadata.ts +5 -1
  93. package/src/webpack/configs/utils/get-web-components-version.ts +8 -0
  94. package/src/webpack/create-webpack-config.ts +5 -1
  95. package/src/webpack/types.ts +2 -0
  96. package/template/.gitignore +7 -0
  97. package/template/.stylelintignore +1 -0
@@ -1,6 +1,5 @@
1
+ import { fs, vol } from 'memfs';
1
2
  import chokidar from 'chokidar';
2
- import fs from 'fs';
3
- import mockFS from 'mock-fs';
4
3
 
5
4
  import { getFolders, log } from '../../../utils';
6
5
  import * as sassModule from '../compile-sass';
@@ -8,6 +7,7 @@ import * as sassModule from '../compile-sass';
8
7
  import { styleExtensions } from '..';
9
8
  import { tcm, tcmWatch } from '../tcm';
10
9
 
10
+ jest.mock('fs', () => fs);
11
11
  jest.mock('../../../utils', () => ({
12
12
  ...jest.requireActual('../../../utils'),
13
13
  getFolders: jest.fn(),
@@ -22,10 +22,11 @@ describe('[startup] Cli Utils', () => {
22
22
  jest.mocked(getFolders).mockReturnValue({ source, destination: undefined });
23
23
  });
24
24
 
25
- afterEach(() => mockFS.restore());
25
+ afterEach(() => vol.reset());
26
26
 
27
27
  function mockStylesModule(module: string, id = 'foo') {
28
- mockFS({ [source]: { [module]: `.${id} { display: none; }` } });
28
+ const content = `.${id} { display: none; }`;
29
+ vol.fromJSON({ [`${source}/${module}`]: content });
29
30
  }
30
31
 
31
32
  function expectTypeDefinitions(module: string, id = 'foo') {
@@ -77,7 +78,7 @@ describe('[startup] Cli Utils', () => {
77
78
  beforeEach(() => {
78
79
  fsWatcher = { on: jest.fn() };
79
80
  watchSpy = jest.spyOn(chokidar, 'watch').mockReturnValue(fsWatcher as any);
80
- mockFS({ [source]: {} });
81
+ vol.fromJSON({ [`${source}/foo.bar`]: '' });
81
82
  });
82
83
 
83
84
  const subject = () => tcmWatch();
@@ -1,14 +1,15 @@
1
1
  import execa from 'execa';
2
- import mockFS from 'mock-fs';
2
+ import { fs, vol } from 'memfs';
3
3
  import { Package, getPackagesGraph, getTsConfig } from '../../../utils';
4
4
  import { createPackage } from '../../../__mocks__';
5
5
 
6
6
  import { tsc, tscWatch } from '../tsc';
7
7
 
8
+ jest.mock('fs', () => fs);
8
9
  jest.mock('execa', () => jest.fn());
9
10
  jest.mock('../../../utils', () => ({
10
11
  ...jest.requireActual('../../../utils'),
11
- log: { info: jest.fn() }, // suppress test output
12
+ log: { info: jest.fn(), debug: jest.fn() }, // suppress test output
12
13
  getPackagesGraph: jest.fn(),
13
14
  }));
14
15
 
@@ -22,15 +23,13 @@ describe('[startup] Cli Utils', () => {
22
23
  createPackage({ name: 'foo', location: 'packages/foo' }),
23
24
  createPackage({ name: 'bar', location: 'packages/bar' }),
24
25
  ];
25
- mockFS({
26
- packages: {
27
- foo: { 'tsconfig.json': JSON.stringify({}) },
28
- bar: { 'tsconfig.json': JSON.stringify({}) },
29
- },
26
+ vol.fromJSON({
27
+ 'packages/foo/tsconfig.json': JSON.stringify({}),
28
+ 'packages/bar/tsconfig.json': JSON.stringify({}),
30
29
  });
31
30
  });
32
31
 
33
- afterEach(() => mockFS.restore());
32
+ afterEach(() => vol.reset());
34
33
 
35
34
  describe(`${tsc.name}`, () => {
36
35
  const subject = async () => tsc(packages);
@@ -12,6 +12,8 @@ import { Overrides, createWebpackConfig } from '../../webpack';
12
12
  interface Options {
13
13
  buildStat?: boolean;
14
14
  config?: string;
15
+ esbuild?: boolean;
16
+ experimentalBundlers?: boolean;
15
17
  }
16
18
 
17
19
  function getName() {
@@ -33,7 +35,7 @@ export async function bundle(options: Options = {}) {
33
35
  const mode = 'production';
34
36
  const fallback = `./${webpackProdConfigFileName}`;
35
37
  const config = readWebpackConfig({ ...options, fallback });
36
- const { buildStat } = options;
38
+ const { buildStat, esbuild, experimentalBundlers } = options;
37
39
 
38
40
  const run = async (config: Configuration) => {
39
41
  const compiler = webpack(config);
@@ -55,6 +57,8 @@ export async function bundle(options: Options = {}) {
55
57
  process.stdout.write(stats.toString(config.stats) + '\n');
56
58
  };
57
59
 
60
+ const webpackOptions = { name, buildStat, esbuild, experimentalBundlers };
61
+
58
62
  if (isWebComponent()) {
59
63
  const webpackConfig: Overrides = {
60
64
  configuration: { ...config?.configuration, mode },
@@ -62,12 +66,12 @@ export async function bundle(options: Options = {}) {
62
66
  };
63
67
 
64
68
  return Promise.all([
65
- run(createWebpackConfig(webpackConfig, { embed: true, name, buildStat })),
66
- run(createWebpackConfig(webpackConfig, { name, buildStat })),
69
+ run(createWebpackConfig(webpackConfig, { embed: true, ...webpackOptions })),
70
+ run(createWebpackConfig(webpackConfig, webpackOptions)),
67
71
  ]);
68
72
  }
69
73
 
70
- return run(config ?? createWebpackConfig({ configuration: { mode } }, { buildStat, name }));
74
+ return run(config ?? createWebpackConfig({ configuration: { mode } }, webpackOptions));
71
75
  }
72
76
 
73
77
  export async function bundleWatch(options: Options = {}) {
@@ -76,6 +80,7 @@ export async function bundleWatch(options: Options = {}) {
76
80
  const name = getName();
77
81
  const mode = 'development';
78
82
  const config = readWebpackConfig({ ...options, fallback: `./${webpackDevConfigFileName}` });
83
+ const { esbuild, experimentalBundlers } = options;
79
84
 
80
85
  const runServe = async ({ devServer = {}, ...config }: Configuration) => {
81
86
  const compiler = webpack(config);
@@ -118,12 +123,25 @@ export async function bundleWatch(options: Options = {}) {
118
123
  };
119
124
 
120
125
  return Promise.all([
121
- run(createWebpackConfig(webpackConfig, { embed: true, name })),
122
- runServe(createWebpackConfig(webpackConfig, { name })),
126
+ run(
127
+ createWebpackConfig(webpackConfig, {
128
+ embed: true,
129
+ name,
130
+ esbuild,
131
+ experimentalBundlers,
132
+ })
133
+ ),
134
+ runServe(createWebpackConfig(webpackConfig, { name, esbuild, experimentalBundlers })),
123
135
  ]);
124
136
  }
125
137
 
126
- return runServe(config ?? createWebpackConfig({ configuration: { mode } }, { name }));
138
+ return runServe(
139
+ config ??
140
+ createWebpackConfig(
141
+ { configuration: { mode } },
142
+ { name, esbuild, experimentalBundlers }
143
+ )
144
+ );
127
145
  }
128
146
 
129
147
  function readWebpackConfig({ config, fallback }: Options & { fallback: string }) {
@@ -12,15 +12,13 @@ export function tscWatch(packages: Package[]) {
12
12
  }
13
13
 
14
14
  async function transpile(packages: Package[], options: string[] = []) {
15
- await execa(
16
- 'tsc',
17
- [
18
- '-b',
19
- ...options,
20
- ...collapsePackages(packages).map(({ location }) => getTsConfig(location)),
21
- ],
22
- { stdio: 'inherit' }
23
- );
15
+ const args = [
16
+ '-b',
17
+ ...options,
18
+ ...collapsePackages(packages).map(({ location }) => getTsConfig(location)),
19
+ ];
20
+ log.debug('tsc', `Running tsc ${args.join(' ')}`);
21
+ await execa('tsc', args, { stdio: 'inherit' });
24
22
  }
25
23
 
26
24
  /**
@@ -1,4 +1,7 @@
1
- import mockFS from 'mock-fs';
1
+ import { fs, vol } from 'memfs';
2
+ import WebpackDevServer from 'webpack-dev-server';
3
+ import path from 'path';
4
+
2
5
  import {
3
6
  getConfiguration,
4
7
  getConfigurationSafe,
@@ -13,7 +16,8 @@ import {
13
16
  isStyleCheckDisabled,
14
17
  isWebComponent,
15
18
  } from '../get-configuration';
16
- import WebpackDevServer from 'webpack-dev-server';
19
+
20
+ jest.mock('fs', () => fs);
17
21
 
18
22
  describe('[startup] Utils', () => {
19
23
  const packageJson = 'package.json';
@@ -23,7 +27,7 @@ describe('[startup] Utils', () => {
23
27
  }
24
28
 
25
29
  function mockPackageJson(content: Record<string, any> = {}) {
26
- mockFS(packageJsonFS(content));
30
+ vol.fromJSON(packageJsonFS(content));
27
31
  }
28
32
 
29
33
  function itReturns(subject: Function, value: any) {
@@ -32,7 +36,7 @@ describe('[startup] Utils', () => {
32
36
 
33
37
  beforeEach(() => mockPackageJson());
34
38
 
35
- afterEach(() => mockFS.restore());
39
+ afterEach(() => jest.resetAllMocks());
36
40
 
37
41
  describe(`${getConfiguration.name}`, () => {
38
42
  let location: string | undefined;
@@ -56,7 +60,7 @@ describe('[startup] Utils', () => {
56
60
 
57
61
  beforeEach(() => {
58
62
  location = 'packages/foo';
59
- mockFS({ packages: { foo: { [packageJson]: JSON.stringify({ cli }) } } });
63
+ vol.fromJSON({ [`packages/foo/${packageJson}`]: JSON.stringify({ cli }) });
60
64
  });
61
65
 
62
66
  test("returns location's cli", () => {
@@ -65,7 +69,7 @@ describe('[startup] Utils', () => {
65
69
  });
66
70
 
67
71
  describe('with no package.json', () => {
68
- beforeEach(() => mockFS({}));
72
+ beforeEach(() => vol.reset());
69
73
 
70
74
  test('throws error', () => {
71
75
  expect(subject).toThrowError();
@@ -95,7 +99,7 @@ describe('[startup] Utils', () => {
95
99
 
96
100
  beforeEach(() => {
97
101
  location = 'packages/foo';
98
- mockFS({ packages: { foo: { [packageJson]: JSON.stringify({ cli }) } } });
102
+ vol.fromJSON({ [`packages/foo/${packageJson}`]: JSON.stringify({ cli }) });
99
103
  });
100
104
 
101
105
  test("returns location's cli", () => {
@@ -104,7 +108,7 @@ describe('[startup] Utils', () => {
104
108
  });
105
109
 
106
110
  describe('with no package.json', () => {
107
- beforeEach(() => mockFS({}));
111
+ beforeEach(() => vol.reset());
108
112
 
109
113
  itReturns(subject, {});
110
114
  });
@@ -135,7 +139,7 @@ describe('[startup] Utils', () => {
135
139
  });
136
140
 
137
141
  describe('when "cli.webpack.proxy" is a path', () => {
138
- const proxy = 'proxy.json';
142
+ const proxy = 'proxy.js';
139
143
  const proxyConfig = { cli: { webpack: { ...webpack, proxy } } };
140
144
 
141
145
  beforeEach(() => mockPackageJson(proxyConfig));
@@ -148,12 +152,14 @@ describe('[startup] Utils', () => {
148
152
 
149
153
  describe('when file exists', () => {
150
154
  beforeEach(() => {
151
- mockFS({
155
+ vol.fromJSON({
152
156
  ...packageJsonFS(proxyConfig),
153
157
  [proxy]: JSON.stringify(webpack.proxy),
154
- // Need node_modules so Jest can require() json file
155
- // eslint-disable-next-line @typescript-eslint/naming-convention
156
- node_modules: mockFS.load('./node_modules'),
158
+ });
159
+
160
+ // Have to mock proxy.js because our fs is virtual, but require() is not
161
+ jest.doMock(path.resolve('proxy.js'), () => webpack.proxy, {
162
+ virtual: true,
157
163
  });
158
164
  });
159
165
 
@@ -265,7 +271,7 @@ describe('[startup] Utils', () => {
265
271
  describe('with a location', () => {
266
272
  beforeEach(() => {
267
273
  location = 'packages/foo';
268
- mockFS({ packages: { foo: { [packageJson]: JSON.stringify(trigger) } } });
274
+ vol.fromJSON({ [`packages/foo/${packageJson}`]: JSON.stringify(trigger) });
269
275
  });
270
276
 
271
277
  test("returns location's status", () => {
@@ -1,9 +1,9 @@
1
- import fs from 'fs';
2
- import mockFS from 'mock-fs';
1
+ import { fs, vol } from 'memfs';
3
2
  import { getPackages } from '../get-packages';
4
3
 
5
4
  import { getDestinationFolders } from '../get-destination-folders';
6
5
 
6
+ jest.mock('fs', () => fs);
7
7
  jest.mock('../get-packages', () => ({ getPackages: jest.fn() }));
8
8
 
9
9
  describe('[startup] Utils', () => {
@@ -12,28 +12,26 @@ describe('[startup] Utils', () => {
12
12
 
13
13
  beforeEach(() => {
14
14
  locations = ['foo', 'bar'];
15
- mockFS(packageFS(locations));
15
+ vol.fromJSON(packageFS(locations));
16
16
  jest.mocked(getPackages).mockImplementation((): any =>
17
17
  locations.map(location => ({ location: `packages/${location}` }))
18
18
  );
19
19
  });
20
20
 
21
- afterEach(() => mockFS.restore());
21
+ afterEach(() => vol.reset());
22
22
 
23
23
  const subject = () => getDestinationFolders();
24
24
 
25
25
  function packageFS(locations: string[]) {
26
26
  const packages = Object.fromEntries(
27
27
  locations.map(location => [
28
- location,
29
- {
30
- 'tsconfig.json': JSON.stringify({
31
- compilerOptions: { outDir: `${location}outDir` },
32
- }),
33
- },
28
+ `packages/${location}/tsconfig.json`,
29
+ JSON.stringify({
30
+ compilerOptions: { outDir: `${location}outDir` },
31
+ }),
34
32
  ])
35
33
  );
36
- return { packages };
34
+ return packages;
37
35
  }
38
36
 
39
37
  function expectedOutDirs(locations: string[]) {
@@ -45,7 +43,7 @@ describe('[startup] Utils', () => {
45
43
  });
46
44
 
47
45
  describe('when package has no tsconfig', () => {
48
- beforeEach(() => mockFS(packageFS(locations.slice(1))));
46
+ beforeEach(() => fs.rmSync(`packages/${locations[0]}/tsconfig.json`));
49
47
 
50
48
  test('omits location from result', () => {
51
49
  expect(subject()).toEqual(expectedOutDirs(locations.slice(1)));
@@ -54,7 +52,7 @@ describe('[startup] Utils', () => {
54
52
 
55
53
  describe('when tsconfig has no "outDir"', () => {
56
54
  beforeEach(() => {
57
- fs.writeFileSync(`packages/${locations[0]}/tsconfig.json`, JSON.stringify({}));
55
+ vol.fromJSON({ [`packages/${locations[0]}/tsconfig.json`]: JSON.stringify({}) });
58
56
  });
59
57
 
60
58
  test('omits location from result', () => {
@@ -1,14 +1,16 @@
1
- import mock from 'mock-fs';
1
+ import { fs, vol } from 'memfs';
2
2
 
3
3
  import { getFolders } from '..';
4
4
 
5
+ jest.mock('fs', () => fs);
6
+
5
7
  describe('[Startup] utils:get-folders', () => {
6
8
  afterAll(() => {
7
- mock.restore();
9
+ vol.reset();
8
10
  });
9
11
 
10
12
  test('getFolders throws an exception if "compilerOptions.rootDir" isn\'t defined', () => {
11
- mock({
13
+ vol.fromJSON({
12
14
  'package.json': JSON.stringify({}),
13
15
  'tsconfig.json': JSON.stringify({ compilerOptions: { ourDir: 'dist' } }),
14
16
  });
@@ -25,7 +27,7 @@ describe('[Startup] utils:get-folders', () => {
25
27
  });
26
28
 
27
29
  test('getFolders throws an exception if "compilerOptions.outDir" isn\'t defined', () => {
28
- mock({
30
+ vol.fromJSON({
29
31
  'package.json': JSON.stringify({}),
30
32
  'tsconfig.json': JSON.stringify({ compilerOptions: { rootDir: 'src' } }),
31
33
  });
@@ -42,7 +44,7 @@ describe('[Startup] utils:get-folders', () => {
42
44
  });
43
45
 
44
46
  test('"compilerOptions.outDir" used as the destination', () => {
45
- mock({
47
+ vol.fromJSON({
46
48
  'package.json': JSON.stringify({}),
47
49
  'tsconfig.json': JSON.stringify({
48
50
  compilerOptions: { rootDir: 'src', outDir: 'path' },
@@ -53,7 +55,7 @@ describe('[Startup] utils:get-folders', () => {
53
55
  });
54
56
 
55
57
  test('"compilerOptions.rootDir" used as the source', () => {
56
- mock({
58
+ vol.fromJSON({
57
59
  'package.json': JSON.stringify({}),
58
60
  'tsconfig.json': JSON.stringify({
59
61
  compilerOptions: { rootDir: 'path', outDir: 'dist' },
@@ -33,7 +33,7 @@ describe('[startup] Utils', () => {
33
33
  testPathIgnorePatterns: ['\\.yalc', ...destinationFolders],
34
34
  setupFiles: [expect.stringContaining(path.join('jest', 'setup.js'))],
35
35
  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
36
- coverageReporters: ['html-spa', 'text', 'json', 'cobertura'],
36
+ coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
37
37
  collectCoverageFrom: ['**/*.{ts,tsx}'],
38
38
  };
39
39
 
@@ -1,8 +1,10 @@
1
- import mockFS from 'mock-fs';
1
+ import { fs, vol } from 'memfs';
2
2
  import path from 'path';
3
3
 
4
4
  import { getTsConfig } from '../get-tsconfig';
5
5
 
6
+ jest.mock('fs', () => fs);
7
+
6
8
  describe(`[startup] Utils`, () => {
7
9
  describe(`${getTsConfig.name}`, () => {
8
10
  const defaultConfig = 'tsconfig.json';
@@ -13,14 +15,14 @@ describe(`[startup] Utils`, () => {
13
15
 
14
16
  beforeEach(() => (location = undefined));
15
17
 
16
- afterEach(() => mockFS.restore());
18
+ afterEach(() => vol.reset());
17
19
 
18
20
  test(`returns ${defaultConfig}`, () => {
19
21
  expect(subject()).toBe(defaultConfig);
20
22
  });
21
23
 
22
24
  describe(`when ${buildConfig} is present`, () => {
23
- beforeEach(() => mockFS({ [buildConfig]: JSON.stringify({}) }));
25
+ beforeEach(() => vol.fromJSON({ [buildConfig]: JSON.stringify({}) }));
24
26
 
25
27
  test(`returns ${buildConfig}`, () => {
26
28
  expect(subject()).toBe(buildConfig);
@@ -36,7 +38,7 @@ describe(`[startup] Utils`, () => {
36
38
 
37
39
  describe(`when ${buildConfig} is present`, () => {
38
40
  beforeEach(() => {
39
- mockFS({ packages: { foo: { [buildConfig]: JSON.stringify({}) } } });
41
+ vol.fromJSON({ [`packages/foo/${buildConfig}`]: JSON.stringify({}) });
40
42
  });
41
43
 
42
44
  test(`returns {location}/${buildConfig}`, () => {
@@ -1,14 +1,16 @@
1
- import mock from 'mock-fs';
1
+ import { fs, vol } from 'memfs';
2
2
 
3
3
  import { readJson } from '..';
4
4
 
5
+ jest.mock('fs', () => fs);
6
+
5
7
  describe('[Startup] utils:read-json', () => {
6
8
  afterAll(() => {
7
- mock.restore();
9
+ vol.reset();
8
10
  });
9
11
 
10
12
  test('readJson works with the current directory', () => {
11
- mock({
13
+ vol.fromJSON({
12
14
  'file.json': JSON.stringify({
13
15
  a: true,
14
16
  b: 'string',
@@ -28,20 +30,14 @@ describe('[Startup] utils:read-json', () => {
28
30
  });
29
31
 
30
32
  test('readJson works with the nested directory', () => {
31
- mock({
32
- path: {
33
- to: {
34
- folder: {
35
- 'file.json': JSON.stringify({
36
- a: true,
37
- b: 'string',
38
- c: {
39
- d: 7,
40
- },
41
- }),
42
- },
33
+ vol.fromJSON({
34
+ 'path/to/folder/file.json': JSON.stringify({
35
+ a: true,
36
+ b: 'string',
37
+ c: {
38
+ d: 7,
43
39
  },
44
- },
40
+ }),
45
41
  });
46
42
 
47
43
  expect(readJson('./path/to/folder/file.json')).toEqual({
@@ -44,7 +44,7 @@ const getJestConfigBase = (
44
44
  ],
45
45
  setupFiles: [path.join(__dirname, '../../jest/setup.js'), ...toArray(setupFiles)],
46
46
  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$', ...coveragePathIgnorePatterns],
47
- coverageReporters: ['html-spa', 'text', 'json', 'cobertura'],
47
+ coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
48
48
  collectCoverageFrom: ['**/*.{ts,tsx}'],
49
49
  };
50
50
  };
@@ -1,6 +1,6 @@
1
1
  import HtmlWebpackPlugin from 'html-webpack-plugin';
2
2
  import MiniCssExtractPlugin from 'mini-css-extract-plugin';
3
- import mockFS from 'mock-fs';
3
+ import { fs, vol } from 'memfs';
4
4
  import path from 'path';
5
5
  import { DefinePlugin } from 'webpack';
6
6
  import WebpackAssetsManifest from 'webpack-assets-manifest';
@@ -14,6 +14,7 @@ import { featureCohort, getCallerFile, splitByEntry } from '../utils';
14
14
 
15
15
  import { createWebpackConfig } from '../index';
16
16
 
17
+ jest.mock('fs', () => fs);
17
18
  jest.mock('fork-ts-checker-webpack-plugin', () => jest.fn());
18
19
  jest.mock('html-webpack-plugin', () => jest.fn());
19
20
  jest.mock('mini-css-extract-plugin', () =>
@@ -86,10 +87,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
86
87
  jest.mocked(getPackages).mockReturnValue([]);
87
88
  jest.mocked(getTsConfig).mockReturnValue(tsConfig);
88
89
 
89
- mockFS({ [packageJson]: JSON.stringify({ name: packageName }) });
90
+ vol.fromJSON({ [packageJson]: JSON.stringify({ name: packageName }) });
90
91
  });
91
92
 
92
- afterEach(() => mockFS.restore());
93
+ afterEach(() => vol.reset());
93
94
 
94
95
  const subject = () => createWebpackConfig(overrides, options);
95
96
 
@@ -222,9 +223,9 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
222
223
 
223
224
  describe('when design-system.css exists', () => {
224
225
  beforeEach(() => {
225
- mockFS({
226
+ vol.fromJSON({
226
227
  [packageJson]: JSON.stringify({ name: packageName }),
227
- [source]: { 'design-system.css': '' },
228
+ [`${source}/design-system.css`]: '',
228
229
  });
229
230
  });
230
231
 
@@ -1,7 +1,7 @@
1
1
  import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
2
2
  import HtmlWebpackPlugin from 'html-webpack-plugin';
3
3
  import MiniCssExtractPlugin from 'mini-css-extract-plugin';
4
- import mockFS from 'mock-fs';
4
+ import { fs, vol } from 'memfs';
5
5
  import MomentLocalesPlugin from 'moment-locales-webpack-plugin';
6
6
  import os from 'os';
7
7
  import path from 'path';
@@ -28,6 +28,7 @@ import { featureCohort, splitByEntry } from '../utils';
28
28
 
29
29
  import { createWebpackConfig } from '../index';
30
30
 
31
+ jest.mock('fs', () => fs);
31
32
  jest.mock('fork-ts-checker-webpack-plugin', () => jest.fn());
32
33
  jest.mock('html-webpack-plugin', () => jest.fn());
33
34
  jest.mock('mini-css-extract-plugin', () =>
@@ -124,10 +125,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
124
125
 
125
126
  Object.keys(argv).forEach(key => delete (argv as any)[key]);
126
127
 
127
- mockFS({ [packageJson]: JSON.stringify({ name: packageName }) });
128
+ vol.fromJSON({ [packageJson]: JSON.stringify({ name: packageName }) });
128
129
  });
129
130
 
130
- afterEach(() => mockFS.restore());
131
+ afterEach(() => vol.reset());
131
132
 
132
133
  const subject = () => createWebpackConfig(overrides, options);
133
134
 
@@ -173,6 +174,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
173
174
  });
174
175
  });
175
176
 
177
+ test('configures "amd"', () => {
178
+ expect(subject().amd).toEqual(false);
179
+ });
180
+
176
181
  test('configures "devServer"', () => {
177
182
  expect(subject().devServer).toEqual({
178
183
  port: 8080,
@@ -205,7 +210,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
205
210
  test('configures "devServer.watchOptions" to ignore TSC packages', () => {
206
211
  const ignored = packages
207
212
  .filter(({ type }) => type === PackageType.TSC)
208
- .map(({ location }) => path.join(location, getFolders(location).source));
213
+ .map(({ location }) => location);
209
214
  expect(subject().devServer?.watchOptions).toEqual({ ignored });
210
215
  });
211
216
  });
@@ -226,25 +231,63 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
226
231
  });
227
232
  });
228
233
 
229
- describe('with --esbuild command line argument', () => {
230
- beforeEach(() => Object.assign(argv, { esbuild: true }));
231
-
234
+ function itConfiguresTsLoader() {
232
235
  test('configures ".tsx" rules to use esbuild-loader', () => {
236
+ expect(subject().module?.rules).toContainEqual({
237
+ test: /\.tsx?$/,
238
+ exclude: /node_modules/,
239
+ use: [{ loader: 'esbuild-loader', options: { loader: 'tsx', target: 'es2018' } }],
240
+ });
241
+ });
242
+ }
243
+ function itConfiguresSwcLoader() {
244
+ test('configures ".tsx" rules to use swc-loader', () => {
233
245
  expect(subject().module?.rules).toContainEqual({
234
246
  test: /\.tsx?$/,
235
247
  exclude: /node_modules/,
236
248
  use: [
237
249
  {
238
- loader: 'esbuild-loader',
239
- options: { loader: 'tsx', target: 'es2018' },
250
+ loader: 'swc-loader',
251
+ options: {
252
+ jsc: {
253
+ parser: { syntax: 'typescript', tsx: true, decorators: true },
254
+ target: 'es2018',
255
+ transform: { legacyDecorator: true, decoratorMetadata: true },
256
+ },
257
+ },
240
258
  },
241
259
  ],
242
260
  });
243
261
  });
244
-
262
+ }
263
+ function itConfiguresReactToLoadAutomatically() {
245
264
  test('configures React to load automatically', () => {
246
265
  expect(subject().plugins).toContainEqual(new ProvidePlugin({ React: 'react' }));
247
266
  });
267
+ }
268
+ describe('with --esbuild command line argument', () => {
269
+ beforeEach(() => Object.assign(argv, { esbuild: true }));
270
+ itConfiguresTsLoader();
271
+ itConfiguresReactToLoadAutomatically();
272
+ });
273
+ describe('with esbuild option', () => {
274
+ beforeEach(() => {
275
+ options = { esbuild: true };
276
+ });
277
+ itConfiguresTsLoader();
278
+ itConfiguresReactToLoadAutomatically();
279
+ });
280
+ describe('with experimental-bundlers option', () => {
281
+ beforeEach(() => {
282
+ options = { experimentalBundlers: true };
283
+ });
284
+ itConfiguresSwcLoader();
285
+ itConfiguresReactToLoadAutomatically();
286
+ });
287
+ describe('with --experimental-bundlers command line argument', () => {
288
+ beforeEach(() => Object.assign(argv, { 'experimental-bundlers': true }));
289
+ itConfiguresSwcLoader();
290
+ itConfiguresReactToLoadAutomatically();
248
291
  });
249
292
 
250
293
  test('configures ".css" rule to exclude .module.css files', () => {