pob 9.3.0 → 9.6.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 (27) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/lib/.eslintrc.json +17 -1
  3. package/lib/generators/common/babel/CommonBabelGenerator.js +3 -20
  4. package/lib/generators/common/babel/templates/app.rollup.config.mjs.ejs +1 -1
  5. package/lib/generators/common/format-lint/CommonLintGenerator.js +22 -20
  6. package/lib/generators/common/testing/CommonTestingGenerator.js +187 -71
  7. package/lib/generators/common/testing/templates/babel.config.cjs.ejs +12 -0
  8. package/lib/generators/common/typescript/CommonTypescriptGenerator.js +1 -0
  9. package/lib/generators/common/typescript/templates/tsconfig.build.json.ejs +3 -0
  10. package/lib/generators/core/package/CorePackageGenerator.js +29 -2
  11. package/lib/generators/core/package/templates/check-package.js.ejs +3 -0
  12. package/lib/generators/core/package/templates/check-packages.js.ejs +5 -0
  13. package/lib/generators/core/renovate/CoreRenovateGenerator.js +19 -4
  14. package/lib/generators/core/vscode/CoreVSCodeGenerator.js +8 -0
  15. package/lib/generators/core/vscode/templates/tasks.json.ejs +1 -2
  16. package/lib/generators/lib/PobLibGenerator.js +0 -7
  17. package/lib/generators/lib/release/LibReleaseGenerator.js +4 -1
  18. package/lib/generators/monorepo/PobMonorepoGenerator.js +22 -34
  19. package/lib/generators/monorepo/lerna/MonorepoLernaGenerator.js +0 -21
  20. package/lib/pob.js +7 -9
  21. package/lib/utils/dependenciesPackages.cjs +10 -0
  22. package/lib/utils/json5.js +7 -0
  23. package/lib/utils/package.js +27 -5
  24. package/package.json +4 -3
  25. package/lib/generators/common/babel/templates/babel.config.cjs.ejs +0 -14
  26. package/lib/generators/core/renovate/templates/renovate.app.json +0 -3
  27. package/lib/generators/core/renovate/templates/renovate.lib.json +0 -3
package/CHANGELOG.md CHANGED
@@ -3,6 +3,70 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [9.6.0](https://github.com/christophehurpeau/pob/compare/pob@9.5.0...pob@9.6.0) (2021-12-12)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **pob:** move babel config generator to testing generator and configure for monorepo ([1d2a4e6](https://github.com/christophehurpeau/pob/commit/1d2a4e6f97adae84b8e4e045e36aa10c47913e5f))
12
+ * package locations in mongorepo generator ([63e7f62](https://github.com/christophehurpeau/pob/commit/63e7f62e934e6703066ac16ddb4fff7975811295))
13
+ * **pob:** dont remove preversion script for pob-dependencies ([f62355d](https://github.com/christophehurpeau/pob/commit/f62355d35ab186a9c680fee4836e4aaa5293d77b))
14
+ * **pob:** only add test-setup in ignored build tsconfig when package is not in a monorepo ([dba09fd](https://github.com/christophehurpeau/pob/commit/dba09fdec9a15617274ffe7acdb39c627ba84ab6))
15
+ * add missing clean script in apps ([a871c2c](https://github.com/christophehurpeau/pob/commit/a871c2c74386d9af0febf62ae09962ba092f6a29))
16
+ * add src/test-setup.ts in build exclude ([118efc9](https://github.com/christophehurpeau/pob/commit/118efc90130d07c1689db1f58ccab7762eefe0dd))
17
+ * allow extendable renovate config ([5d9a053](https://github.com/christophehurpeau/pob/commit/5d9a053f0485fa66586fb237b7770f450799c045))
18
+ * allow to extends renovate config ([e61b0b7](https://github.com/christophehurpeau/pob/commit/e61b0b792f63e9e938a9172a102089ff9eb3aa2f))
19
+ * doesJsCheckPackagesExists should be let ([6aac69f](https://github.com/christophehurpeau/pob/commit/6aac69f1a2eb6df4e98d4289da2e4b245a278e94))
20
+ * dont create and delete check-package script in workspace packages ([3398ef5](https://github.com/christophehurpeau/pob/commit/3398ef56a97933149eaea02cea58949cadfc61b2))
21
+ * dont delete plugin dependencies in eslint-config-pob ([31fe081](https://github.com/christophehurpeau/pob/commit/31fe08106647624317f277d2e31f820911445532))
22
+ * get eslint dependency versions from @pob/eslint-config ([4100cc5](https://github.com/christophehurpeau/pob/commit/4100cc5a342b1cc970f614de99692600f9ec89f9))
23
+ * order pob-babel/plugin-run.cjs ([57d6c8b](https://github.com/christophehurpeau/pob/commit/57d6c8bfbcfd756a23f96b436614db8991cf1ed2))
24
+ * read vscode tasks file ([436c480](https://github.com/christophehurpeau/pob/commit/436c480d4538b68893b3521573ab50199d63a23e))
25
+ * **pob:** esm condition for babel.config.cjs ([6aeb96f](https://github.com/christophehurpeau/pob/commit/6aeb96fd7648484755c595310008b0dff20fa6a4))
26
+ * **pob:** global testing config ([fc56a6d](https://github.com/christophehurpeau/pob/commit/fc56a6d28413a8ae2c7a45235f853b5123005c84))
27
+
28
+
29
+ ### Features
30
+
31
+ * configure pob-lcov-reporter for pob monorepo ([e7f40c4](https://github.com/christophehurpeau/pob/commit/e7f40c4dc9a2400e48a1497ac4ea0bdc5f842a15))
32
+ * **pob:** add default check-package-dependencies script if it doesnt exists and package type is module ([7e54041](https://github.com/christophehurpeau/pob/commit/7e540417e34d908f06f6263d668f9cbb4d9c7990))
33
+ * update eslint 8 and eslint-config-pob ([f881f05](https://github.com/christophehurpeau/pob/commit/f881f05852e00c22a35178979e1425445413ce70))
34
+
35
+
36
+
37
+
38
+
39
+ # [9.5.0](https://github.com/christophehurpeau/pob/compare/pob@9.4.0...pob@9.5.0) (2021-12-11)
40
+
41
+
42
+ ### Features
43
+
44
+ * **pob-babel:** include plugin-run as export ([9a4515d](https://github.com/christophehurpeau/pob/commit/9a4515d26d816df6f257a90647046c7da5d83a16))
45
+ * enable global testing in monorepo ([178775b](https://github.com/christophehurpeau/pob/commit/178775bb7fc971bc6a9712b105623508f739ba7b))
46
+
47
+
48
+
49
+
50
+
51
+ # [9.4.0](https://github.com/christophehurpeau/pob/compare/pob@9.3.1...pob@9.4.0) (2021-12-11)
52
+
53
+
54
+ ### Features
55
+
56
+ * monorepo testing generator ([b444042](https://github.com/christophehurpeau/pob/commit/b444042aa5203e4ac7a56a3d93f5a3b98c0fce11))
57
+
58
+
59
+
60
+
61
+
62
+ ## [9.3.1](https://github.com/christophehurpeau/pob/compare/pob@9.3.0...pob@9.3.1) (2021-12-11)
63
+
64
+ **Note:** Version bump only for package pob
65
+
66
+
67
+
68
+
69
+
6
70
  # [9.3.0](https://github.com/christophehurpeau/pob/compare/pob@9.2.1...pob@9.3.0) (2021-12-11)
7
71
 
8
72
 
@@ -7,5 +7,21 @@
7
7
  "no-nested-ternary": "off",
8
8
  "no-console": "off",
9
9
  "complexity": "off"
10
- }
10
+ },
11
+ "overrides": [
12
+ {
13
+ "files": ["**/*.test.{cjs,js}", "__tests__/**/*.{cjs,js}"],
14
+ "env": {
15
+ "jest": true
16
+ },
17
+ "rules": {
18
+ "import/no-extraneous-dependencies": [
19
+ "error",
20
+ {
21
+ "devDependencies": true
22
+ }
23
+ ]
24
+ }
25
+ }
26
+ ]
11
27
  }
@@ -277,12 +277,14 @@ export default class CommonBabelGenerator extends Generator {
277
277
  packageUtils.addOrRemoveScripts(pkg, useBabel, {
278
278
  build: 'pob-build',
279
279
  start: 'pob-watch',
280
+ clean: 'rm -Rf dist',
280
281
  });
281
282
  } else {
282
283
  packageUtils.removeScripts(['start']);
283
284
  packageUtils.addOrRemoveScripts(pkg, useBabel, {
284
285
  build: 'pob-build',
285
286
  watch: 'pob-watch',
287
+ clean: 'rm -Rf dist',
286
288
  });
287
289
  }
288
290
 
@@ -687,15 +689,10 @@ export default class CommonBabelGenerator extends Generator {
687
689
  const pkg = this.fs.readJSON(this.destinationPath('package.json'));
688
690
 
689
691
  const useBabel = this.babelEnvs && this.babelEnvs.length > 0;
690
- const hasReact = useBabel && packageUtils.hasReact(pkg);
691
692
 
692
693
  /* pob-babel config */
693
694
 
694
- packageUtils.addOrRemoveDevDependencies(
695
- pkg,
696
- useBabel && this.options.isApp,
697
- ['@rollup/plugin-run'],
698
- );
695
+ packageUtils.removeDevDependencies(pkg, ['@rollup/plugin-run']);
699
696
 
700
697
  this.fs.delete('rollup.config.js');
701
698
  if (useBabel) {
@@ -726,20 +723,6 @@ export default class CommonBabelGenerator extends Generator {
726
723
  );
727
724
  }
728
725
 
729
- if (useBabel && this.options.testing) {
730
- // cjs for jest compat
731
- this.fs.copyTpl(
732
- this.templatePath('babel.config.cjs.ejs'),
733
- this.destinationPath('babel.config.cjs'),
734
- {
735
- hasReact,
736
- testing: this.options.testing,
737
- },
738
- );
739
- } else {
740
- this.fs.delete('babel.config.cjs');
741
- }
742
-
743
726
  this.fs.writeJSON(this.destinationPath('package.json'), pkg);
744
727
  }
745
728
  }
@@ -1,5 +1,5 @@
1
- import run from '@rollup/plugin-run';
2
1
  import createRollupConfig from 'pob-babel/createRollupConfig.js';
2
+ import run from 'pob-babel/plugin-run.cjs';
3
3
 
4
4
  const watch = process.env.ROLLUP_WATCH === 'true';
5
5
 
@@ -159,14 +159,9 @@ export default class CommonLintGenerator extends Generator {
159
159
  'babel-eslint',
160
160
  'eslint-config-pob',
161
161
  'eslint-config-prettier',
162
- 'eslint-plugin-babel',
163
- 'eslint-plugin-flowtype',
164
- 'eslint-plugin-prefer-class-properties',
165
- 'eslint-plugin-prettier',
166
- 'eslint-plugin-react',
167
- 'eslint-plugin-react-hooks',
168
162
  'typescript-eslint-parser',
169
163
  'standard',
164
+ 'eslint-import-resolver-node',
170
165
  ]);
171
166
 
172
167
  if (!pkg.name.startsWith('@pob/eslint-config')) {
@@ -174,11 +169,18 @@ export default class CommonLintGenerator extends Generator {
174
169
  'eslint-plugin-jsx-a11y',
175
170
  'eslint-config-airbnb',
176
171
  'eslint-config-airbnb-base',
172
+ 'eslint-plugin-babel',
173
+ 'eslint-plugin-flowtype',
174
+ 'eslint-plugin-prefer-class-properties',
175
+ 'eslint-plugin-prettier',
176
+ 'eslint-plugin-react',
177
+ 'eslint-plugin-react-hooks',
177
178
  ]);
178
179
  }
179
180
 
180
181
  const yoConfigPobMonorepo = inLerna && inLerna.pobMonorepoConfig;
181
182
  const globalEslint = yoConfigPobMonorepo && yoConfigPobMonorepo.eslint;
183
+ const globalTesting = yoConfigPobMonorepo && yoConfigPobMonorepo.testing;
182
184
  const composite = yoConfigPobMonorepo && yoConfigPobMonorepo.typescript;
183
185
  const { rootPackageManager, rootYarnNodeLinker } = inLerna || {};
184
186
  const lernaProjectType =
@@ -202,7 +204,6 @@ export default class CommonLintGenerator extends Generator {
202
204
  '@pob/eslint-config-react',
203
205
  '@typescript-eslint/eslint-plugin',
204
206
  '@typescript-eslint/parser',
205
- 'eslint-import-resolver-node',
206
207
  'eslint-plugin-node',
207
208
  'eslint-plugin-unicorn',
208
209
  'eslint-plugin-import',
@@ -244,7 +245,7 @@ export default class CommonLintGenerator extends Generator {
244
245
  packageUtils.addOrRemoveDevDependencies(
245
246
  pkg,
246
247
  shouldHavePluginsDependencies,
247
- ['eslint-plugin-node', 'eslint-import-resolver-node'],
248
+ ['eslint-plugin-node'],
248
249
  );
249
250
 
250
251
  if ((inLerna && inLerna.root) || this.options.monorepo) {
@@ -337,18 +338,19 @@ export default class CommonLintGenerator extends Generator {
337
338
  ? `{${pkg.type === 'commonjs' ? 'mjs' : 'cjs'},js}`
338
339
  : `${hasReact ? '{ts,tsx}' : 'ts'}`;
339
340
 
340
- const jestOverride = !packageUtils.hasJest(pkg)
341
- ? null
342
- : {
343
- files: [`**/*.test.${ext}`, `__tests__/**/*.${ext}`],
344
- env: { jest: true },
345
- rules: {
346
- 'import/no-extraneous-dependencies': [
347
- 'error',
348
- { devDependencies: true },
349
- ],
350
- },
351
- };
341
+ const jestOverride =
342
+ !pkg.jest && !globalTesting
343
+ ? null
344
+ : {
345
+ files: [`**/*.test.${ext}`, `__tests__/**/*.${ext}`],
346
+ env: { jest: true },
347
+ rules: {
348
+ 'import/no-extraneous-dependencies': [
349
+ 'error',
350
+ { devDependencies: true },
351
+ ],
352
+ },
353
+ };
352
354
 
353
355
  if (jestOverride) {
354
356
  // if (!useBabel) {
@@ -1,11 +1,18 @@
1
1
  import Generator from 'yeoman-generator';
2
2
  import inLerna from '../../../utils/inLerna.js';
3
3
  import * as packageUtils from '../../../utils/package.js';
4
+ import { copyAndFormatTpl } from '../../../utils/writeAndFormat.js';
4
5
 
5
6
  export default class CommonTestingGenerator extends Generator {
6
7
  constructor(args, opts) {
7
8
  super(args, opts);
8
9
 
10
+ this.option('monorepo', {
11
+ type: Boolean,
12
+ defaults: false,
13
+ desc: 'is root monorepo',
14
+ });
15
+
9
16
  this.option('enable', {
10
17
  type: Boolean,
11
18
  defaults: true,
@@ -44,10 +51,10 @@ export default class CommonTestingGenerator extends Generator {
44
51
  }
45
52
 
46
53
  default() {
47
- if (!inLerna) {
54
+ if (!inLerna || inLerna.root) {
48
55
  this.composeWith('pob:core:ci', {
49
56
  enable: this.options.ci,
50
- testing: this.options.testing,
57
+ testing: this.options.enable,
51
58
  build: this.options.typescript,
52
59
  typescript: this.options.typescript,
53
60
  documentation: this.options.documentation,
@@ -73,6 +80,11 @@ export default class CommonTestingGenerator extends Generator {
73
80
  'babel-jest',
74
81
  ]);
75
82
 
83
+ const yoConfigPobMonorepo = inLerna && inLerna.pobMonorepoConfig;
84
+ const globalTesting = yoConfigPobMonorepo && yoConfigPobMonorepo.testing;
85
+ const enableForMonorepo = this.options.monorepo && globalTesting;
86
+ const transpileWithBabel = yoConfigPobMonorepo.typescript;
87
+
76
88
  if (!this.options.enable) {
77
89
  packageUtils.removeDevDependencies(pkg, ['jest', '@types/jest']);
78
90
 
@@ -91,81 +103,185 @@ export default class CommonTestingGenerator extends Generator {
91
103
 
92
104
  this.fs.writeJSON(this.destinationPath('package.json'), pkg);
93
105
  } else {
94
- const babelEnvs = pkg.pob.babelEnvs || [];
95
- const transpileWithBabel = packageUtils.transpileWithBabel(pkg);
96
-
97
- const shouldUseExperimentalVmModules =
98
- pkg.type === 'module' || transpileWithBabel;
99
-
100
- const jestCommand = `${
101
- shouldUseExperimentalVmModules
102
- ? 'NODE_OPTIONS=--experimental-vm-modules '
103
- : ''
104
- }jest`;
105
-
106
- packageUtils.addScripts(pkg, {
107
- test: jestCommand,
108
- 'test:watch': `${jestCommand} --watch`,
109
- 'generate:test-coverage': [
110
- 'rm -Rf docs/coverage/',
111
- `NODE_ENV=production ${
112
- transpileWithBabel ? 'BABEL_ENV=test ' : ''
113
- }${jestCommand} --coverage --coverageReporters=pob-lcov-reporter --coverageDirectory=docs/coverage/`,
114
- ].join(' ; '),
115
- });
106
+ packageUtils.addOrRemoveDevDependencies(
107
+ pkg,
108
+ enableForMonorepo || !globalTesting,
109
+ [
110
+ pkg.name !== 'pob-monorepo' && 'pob-lcov-reporter',
111
+ 'jest',
112
+ '@types/jest',
113
+ ],
114
+ );
116
115
 
117
- packageUtils.addDevDependencies(pkg, [
118
- 'pob-lcov-reporter',
119
- 'jest',
120
- '@types/jest',
121
- ]);
116
+ if (this.options.monorepo && !globalTesting) {
117
+ delete pkg.jest;
118
+ packageUtils.addScripts(pkg, {
119
+ test: 'yarn workspaces foreach --parallel -Av run test',
120
+ });
121
+ } else if (this.options.monorepo) {
122
+ const shouldUseExperimentalVmModules = pkg.type === 'module';
122
123
 
123
- const hasReact = transpileWithBabel && packageUtils.hasReact(pkg);
124
- const srcDirectory = transpileWithBabel ? 'src' : 'lib';
125
-
126
- if (!pkg.jest) pkg.jest = {};
127
- Object.assign(pkg.jest, {
128
- cacheDirectory: './node_modules/.cache/jest',
129
- testMatch: [
130
- `<rootDir>/${srcDirectory}/**/__tests__/**/*.${
131
- transpileWithBabel ? 'ts' : '?(m)js'
132
- }${hasReact ? '?(x)' : ''}`,
133
- `<rootDir>/${srcDirectory}/**/*.test.${
134
- transpileWithBabel ? 'ts' : '?(m)js'
135
- }${hasReact ? '?(x)' : ''}`,
136
- ],
137
- collectCoverageFrom: [
138
- `${srcDirectory}/**/*.${transpileWithBabel ? 'ts' : '?(m)js'}${
139
- hasReact ? '?(x)' : ''
140
- }`,
141
- ],
142
- moduleFileExtensions: [
143
- transpileWithBabel && 'ts',
144
- transpileWithBabel && hasReact && 'tsx',
145
- 'js',
146
- // 'jsx',
147
- 'json',
148
- ].filter(Boolean),
149
- extensionsToTreatAsEsm: [
150
- transpileWithBabel && '.ts',
151
- transpileWithBabel && hasReact && '.tsx',
152
- ].filter(Boolean),
153
- // transform: {
154
- // [`^.+\\.ts${hasReact ? 'x?' : ''}$`]: 'babel-jest',
155
- // },
156
- });
157
- delete pkg.jest.transform;
124
+ const jestCommand = `${
125
+ shouldUseExperimentalVmModules
126
+ ? 'NODE_OPTIONS=--experimental-vm-modules '
127
+ : ''
128
+ }jest`;
129
+
130
+ packageUtils.addScripts(pkg, {
131
+ test: jestCommand,
132
+ 'generate:test-coverage': [
133
+ 'rm -Rf docs/coverage/',
134
+ `NODE_ENV=production ${
135
+ transpileWithBabel ? 'BABEL_ENV=test ' : ''
136
+ }${jestCommand} --coverage --coverageReporters=pob-lcov-reporter --coverageDirectory=docs/coverage/`,
137
+ ].join(' ; '),
138
+ });
139
+
140
+ const workspacesWithoutStar = pkg.workspaces.map((workspace) => {
141
+ if (!workspace.endsWith('/*')) {
142
+ throw new Error(`Invalid workspace format: ${workspace}`);
143
+ }
144
+ return workspace.slice(0, -2);
145
+ });
146
+ const workspacesPattern =
147
+ workspacesWithoutStar.length === 1
148
+ ? workspacesWithoutStar[0]
149
+ : `(${workspacesWithoutStar.join('|')})`;
150
+ const hasReact = packageUtils.hasReact(pkg);
158
151
 
159
- if (
160
- babelEnvs.length === 0 ||
161
- babelEnvs.some((env) => env.target === 'node')
162
- ) {
163
- pkg.jest.testEnvironment = 'node';
152
+ if (!pkg.jest) pkg.jest = {};
153
+ Object.assign(pkg.jest, {
154
+ cacheDirectory: './node_modules/.cache/jest',
155
+ testEnvironment: 'node',
156
+ testMatch: [
157
+ `<rootDir>/${workspacesPattern}/*/(src|lib)/**/__tests__/**/*.${
158
+ transpileWithBabel ? '(ts|js|cjs|mjs)' : '(js|cjs|mjs)'
159
+ }${hasReact ? '?(x)' : ''}`,
160
+ `<rootDir>/${workspacesPattern}/*/(src|lib)/**/*.test.${
161
+ transpileWithBabel ? '(ts|js|cjs|mjs)' : '(js|cjs|mjs)'
162
+ }${hasReact ? '?(x)' : ''}`,
163
+ ],
164
+ });
165
+
166
+ if (shouldUseExperimentalVmModules) {
167
+ pkg.jest.extensionsToTreatAsEsm = [
168
+ transpileWithBabel && '.ts',
169
+ transpileWithBabel && hasReact && '.tsx',
170
+ ].filter(Boolean);
171
+ } else {
172
+ delete pkg.jest.extensionsToTreatAsEsm;
173
+ }
174
+ } else if (globalTesting) {
175
+ delete pkg.jest;
176
+ if (pkg.scripts) {
177
+ delete pkg.scripts.test;
178
+ delete pkg.scripts['generate:test-coverage'];
179
+ delete pkg.scripts['test:watch'];
180
+ }
164
181
  } else {
165
- delete pkg.jest.testEnvironment;
182
+ const babelEnvs = pkg.pob.babelEnvs || [];
183
+ const transpileWithBabel = packageUtils.transpileWithBabel(pkg);
184
+
185
+ const shouldUseExperimentalVmModules =
186
+ pkg.type === 'module' && !inLerna;
187
+
188
+ const jestCommand = `${
189
+ shouldUseExperimentalVmModules
190
+ ? 'NODE_OPTIONS=--experimental-vm-modules '
191
+ : ''
192
+ }jest`;
193
+
194
+ packageUtils.addScripts(pkg, {
195
+ test: jestCommand,
196
+ 'test:watch': `${jestCommand} --watch`,
197
+ 'generate:test-coverage': [
198
+ 'rm -Rf docs/coverage/',
199
+ `NODE_ENV=production ${
200
+ transpileWithBabel ? 'BABEL_ENV=test ' : ''
201
+ }${jestCommand} --coverage --coverageReporters=pob-lcov-reporter --coverageDirectory=docs/coverage/`,
202
+ ].join(' ; '),
203
+ });
204
+
205
+ const hasReact = transpileWithBabel && packageUtils.hasReact(pkg);
206
+ const srcDirectory = transpileWithBabel ? 'src' : 'lib';
207
+
208
+ if (!pkg.jest) pkg.jest = {};
209
+ Object.assign(pkg.jest, {
210
+ cacheDirectory: './node_modules/.cache/jest',
211
+ testMatch: [
212
+ `<rootDir>/${srcDirectory}/**/__tests__/**/*.${
213
+ transpileWithBabel ? 'ts' : '?(m)js'
214
+ }${hasReact ? '?(x)' : ''}`,
215
+ `<rootDir>/${srcDirectory}/**/*.test.${
216
+ transpileWithBabel ? 'ts' : '?(m)js'
217
+ }${hasReact ? '?(x)' : ''}`,
218
+ ],
219
+ collectCoverageFrom: [
220
+ `${srcDirectory}/**/*.${transpileWithBabel ? 'ts' : '?(m)js'}${
221
+ hasReact ? '?(x)' : ''
222
+ }`,
223
+ ],
224
+ moduleFileExtensions: [
225
+ transpileWithBabel && 'ts',
226
+ transpileWithBabel && hasReact && 'tsx',
227
+ 'js',
228
+ // 'jsx',
229
+ 'json',
230
+ ].filter(Boolean),
231
+ // transform: {
232
+ // [`^.+\\.ts${hasReact ? 'x?' : ''}$`]: 'babel-jest',
233
+ // },
234
+ });
235
+ delete pkg.jest.transform;
236
+
237
+ if (shouldUseExperimentalVmModules) {
238
+ pkg.jest.extensionsToTreatAsEsm = [
239
+ transpileWithBabel && '.ts',
240
+ transpileWithBabel && hasReact && '.tsx',
241
+ ].filter(Boolean);
242
+ } else {
243
+ delete pkg.jest.extensionsToTreatAsEsm;
244
+ }
245
+
246
+ if (
247
+ babelEnvs.length === 0 ||
248
+ babelEnvs.some((env) => env.target === 'node')
249
+ ) {
250
+ pkg.jest.testEnvironment = 'node';
251
+ } else {
252
+ delete pkg.jest.testEnvironment;
253
+ }
254
+
255
+ if (!transpileWithBabel) delete pkg.jest.transform;
166
256
  }
257
+ }
167
258
 
168
- if (!transpileWithBabel) delete pkg.jest.transform;
259
+ if (
260
+ transpileWithBabel &&
261
+ ((this.options.monorepo && globalTesting) || !globalTesting)
262
+ ) {
263
+ const hasReact = transpileWithBabel && packageUtils.hasReact(pkg);
264
+ // cjs for jest compat
265
+ copyAndFormatTpl(
266
+ this.fs,
267
+ this.templatePath('babel.config.cjs.ejs'),
268
+ this.destinationPath('babel.config.cjs'),
269
+ {
270
+ only: !this.options.monorepo
271
+ ? "'src'"
272
+ : pkg.workspaces
273
+ .flatMap((workspace) => [
274
+ `'${workspace}/src'`,
275
+ `'${workspace}/lib'`,
276
+ ])
277
+ .join(', '),
278
+ hasReact,
279
+ testing: this.options.testing,
280
+ jestExperimentalESM: pkg.type === 'module',
281
+ },
282
+ );
283
+ } else {
284
+ this.fs.delete('babel.config.cjs');
169
285
  }
170
286
 
171
287
  this.fs.writeJSON(this.destinationPath('package.json'), pkg);
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ module.exports = function babelConfig(api) {
4
+ const isTest = api.env('test');
5
+
6
+ if (!isTest) return {};
7
+
8
+ return {
9
+ only: [<%- only %>],
10
+ presets: [[require.resolve('pob-babel/preset.cjs')<% if (!jestExperimentalESM) { %>, { modules: 'commonjs' }<% } %>]],
11
+ };
12
+ };
@@ -127,6 +127,7 @@ export default class CommonTypescriptGenerator extends Generator {
127
127
  this.templatePath('tsconfig.build.json.ejs'),
128
128
  tsconfigBuildPath,
129
129
  {
130
+ inMonorepo: inLerna && !inLerna.root,
130
131
  jsx,
131
132
  composite,
132
133
  monorepoPackageNames,
@@ -18,6 +18,9 @@
18
18
 
19
19
  "exclude": [
20
20
  "dist/**",
21
+ <% if (!inMonorepo) { -%>
22
+ "src/test-setup.ts",
23
+ <% } -%>
21
24
  "src/**/*.test.ts",
22
25
  <% if(jsx) { -%>
23
26
  "src/**/*.test.tsx",
@@ -164,10 +164,19 @@ export default class CorePackageGenerator extends Generator {
164
164
  const doesMjsCheckPackagesExists = this.fs.exists(
165
165
  this.destinationPath('scripts/check-packages.mjs'),
166
166
  );
167
- const doesJsCheckPackagesExists = this.fs.exists(
167
+ let doesJsCheckPackagesExists = this.fs.exists(
168
168
  this.destinationPath('scripts/check-packages.js'),
169
169
  );
170
170
 
171
+ if (pkg.type === 'module' && !doesJsCheckPackagesExists) {
172
+ doesJsCheckPackagesExists = true;
173
+ this.fs.copyTpl(
174
+ this.templatePath('check-packages.js.ejs'),
175
+ this.destinationPath('scripts/check-packages.js'),
176
+ {},
177
+ );
178
+ }
179
+
171
180
  packageUtils.addOrRemoveScripts(
172
181
  pkg,
173
182
  doesMjsCheckPackagesExists || doesJsCheckPackagesExists,
@@ -177,13 +186,31 @@ export default class CorePackageGenerator extends Generator {
177
186
  }`,
178
187
  },
179
188
  );
189
+ } else if (inLerna && !inLerna.root) {
190
+ if (this.fs.exists('scripts/check-package.js')) {
191
+ this.fs.delete('scripts/check-package.js');
192
+ }
193
+ if (this.fs.exists('scripts/check-package.mjs')) {
194
+ this.fs.delete('scripts/check-package.mjs');
195
+ }
196
+ packageUtils.removeScripts(pkg, ['checks']);
180
197
  } else {
181
198
  const doesMjsCheckPackageExists = this.fs.exists(
182
199
  this.destinationPath('scripts/check-package.mjs'),
183
200
  );
184
- const doesJsCheckPackageExists = this.fs.exists(
201
+ let doesJsCheckPackageExists = this.fs.exists(
185
202
  this.destinationPath('scripts/check-package.js'),
186
203
  );
204
+
205
+ if (pkg.type === 'module' && !doesJsCheckPackageExists) {
206
+ doesJsCheckPackageExists = true;
207
+ this.fs.copyTpl(
208
+ this.templatePath('check-package.js.ejs'),
209
+ this.destinationPath('scripts/check-package.js'),
210
+ {},
211
+ );
212
+ }
213
+
187
214
  packageUtils.addOrRemoveScripts(
188
215
  pkg,
189
216
  doesMjsCheckPackageExists || doesJsCheckPackageExists,
@@ -0,0 +1,3 @@
1
+ import { createCheckPackage } from 'check-package-dependencies';
2
+
3
+ createCheckPackage().checkRecommended({});
@@ -0,0 +1,5 @@
1
+ import { createCheckPackageWithWorkspaces } from 'check-package-dependencies';
2
+
3
+ createCheckPackageWithWorkspaces().checkRecommended({
4
+ isLibrary: () => true,
5
+ });
@@ -1,5 +1,6 @@
1
1
  import Generator from 'yeoman-generator';
2
2
  import inLerna from '../../../utils/inLerna.js';
3
+ import { writeAndFormatJson } from '../../../utils/writeAndFormat.js';
3
4
 
4
5
  export default class CoreRenovateGenerator extends Generator {
5
6
  constructor(args, opts) {
@@ -58,11 +59,25 @@ export default class CoreRenovateGenerator extends Generator {
58
59
 
59
60
  writing() {
60
61
  if (this.enableRenovate) {
61
- this.fs.copy(
62
- this.templatePath(
63
- this.options.app ? 'renovate.app.json' : 'renovate.lib.json',
64
- ),
62
+ const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
63
+ const renovateConfig = this.fs.readJSON(
65
64
  this.destinationPath('renovate.json'),
65
+ {},
66
+ );
67
+
68
+ if (this.options.app) {
69
+ renovateConfig.extends = ['config:js-app', '@pob'];
70
+ } else {
71
+ renovateConfig.extends = [
72
+ 'config:js-lib',
73
+ pkg.name === 'pob-monorepo' ? undefined : '@pob',
74
+ ].filter(Boolean);
75
+ }
76
+
77
+ writeAndFormatJson(
78
+ this.fs,
79
+ this.destinationPath('renovate.json'),
80
+ renovateConfig,
66
81
  );
67
82
  } else if (this.fs.exists(this.destinationPath('renovate.json'))) {
68
83
  this.fs.delete(this.destinationPath('renovate.json'));
@@ -1,4 +1,5 @@
1
1
  import Generator from 'yeoman-generator';
2
+ import { readJSON5 } from '../../../utils/json5.js';
2
3
  import { copyAndFormatTpl } from '../../../utils/writeAndFormat.js';
3
4
 
4
5
  export default class CoreVSCodeGenerator extends Generator {
@@ -56,12 +57,19 @@ export default class CoreVSCodeGenerator extends Generator {
56
57
  typescript: this.options.typescript,
57
58
  },
58
59
  );
60
+
61
+ const tasksConfig = readJSON5(
62
+ this.fs,
63
+ this.destinationPath('.vscode/tasks.json'),
64
+ {},
65
+ );
59
66
  copyAndFormatTpl(
60
67
  this.fs,
61
68
  this.templatePath('tasks.json.ejs'),
62
69
  this.destinationPath('.vscode/tasks.json'),
63
70
  {
64
71
  typescript: this.options.typescript,
72
+ tasks: JSON.stringify(tasksConfig.tasks || [], null, 2),
65
73
  },
66
74
  );
67
75
  } else {
@@ -2,6 +2,5 @@
2
2
  // See https://go.microsoft.com/fwlink/?LinkId=733558
3
3
  // for the documentation about the tasks.json format
4
4
  "version": "2.0.0",
5
- "tasks": [
6
- ]
5
+ "tasks": <%- tasks %>
7
6
  }
@@ -320,13 +320,6 @@ export default class PobLibGenerator extends Generator {
320
320
  delete pkg.scripts.version;
321
321
  }
322
322
  }
323
- if (withBabel && (!inLerna || !inLerna.root)) {
324
- packageUtils.addScripts(pkg, {
325
- clean: 'rm -Rf dist',
326
- });
327
- } else {
328
- delete pkg.scripts.clean;
329
- }
330
323
 
331
324
  if (!withBabel) {
332
325
  if (
@@ -39,7 +39,10 @@ export default class LibReleaseGenerator extends Generator {
39
39
 
40
40
  if (!isStandardVersionEnabled) {
41
41
  packageUtils.removeDevDependencies(pkg, ['standard-version']);
42
- packageUtils.removeScripts(pkg, ['release', 'preversion']);
42
+ packageUtils.removeScripts(pkg, [
43
+ 'release',
44
+ pkg.name === 'pob-dependencies' ? null : 'preversion',
45
+ ]);
43
46
  } else {
44
47
  packageUtils.addDevDependencies(pkg, ['standard-version']);
45
48
  packageUtils.addScripts(pkg, {
@@ -1,4 +1,5 @@
1
1
  import fs from 'fs';
2
+ import path from 'path';
2
3
  import { PackageGraph } from '@lerna/package-graph';
3
4
  import { Project as LernaProject } from '@lerna/project';
4
5
  import Generator from 'yeoman-generator';
@@ -82,10 +83,15 @@ export default class PobMonorepoGenerator extends Generator {
82
83
  const batch = [...graph.values()].filter(
83
84
  (node) => node.localDependencies.size === 0,
84
85
  );
86
+ batch.sort((a, b) => a.name.localeCompare(b.name, 'en'));
85
87
 
86
88
  // batches are composed of Package instances, not PackageGraphNodes
87
89
  this.packages.push(...batch.map((node) => node.pkg));
88
- this.packageLocations.push(...batch.map((node) => node.location));
90
+ this.packageLocations.push(
91
+ ...batch.map((node) =>
92
+ path.relative(this.destinationPath(), node.location),
93
+ ),
94
+ );
89
95
 
90
96
  // pruning the graph changes the node.localDependencies.size test
91
97
  graph.prune(...batch);
@@ -165,48 +171,30 @@ export default class PobMonorepoGenerator extends Generator {
165
171
  const pkg = this.fs.readJSON(this.destinationPath('package.json'), {});
166
172
 
167
173
  const packageNames = this.packageNames;
168
-
169
- const basePackageName = pkg.name.startsWith('@')
170
- ? `${pkg.name.replace(/-monorepo$/, '')}-`
171
- : `@${pkg.name}/`;
172
-
173
- const packagePaths = packageNames
174
- .map((packageName) =>
175
- this.options.isAppProject && packageName.startsWith(basePackageName)
176
- ? `packages/${packageName.slice(basePackageName.length)}`
177
- : `${packageName[0] === '@' ? '' : 'packages/'}${packageName}`,
178
- )
179
- .filter(
180
- this.pobLernaConfig.typescript
181
- ? (packagePath) => fs.existsSync(`${packagePath}/tsconfig.json`)
182
- : Boolean,
183
- );
174
+ const packagePaths = this.packageLocations.filter(
175
+ this.pobLernaConfig.typescript
176
+ ? (packagePath) => fs.existsSync(`${packagePath}/tsconfig.json`)
177
+ : Boolean,
178
+ );
184
179
 
185
180
  if (packagePaths.length === 0 && packageNames.length > 0) {
186
- console.log(
187
- packageNames,
188
- packageNames.map((packageName) =>
189
- this.options.isAppProject && packageName.startsWith(basePackageName)
190
- ? `packages/${packageName.slice(basePackageName.length)}`
191
- : `${packageName[0] === '@' ? '' : 'packages/'}${packageName}`,
192
- ),
193
- );
181
+ console.log(packageNames, packagePaths);
194
182
  throw new Error('packages should not be empty');
195
183
  }
196
184
 
197
- this.composeWith('pob:core:ci', {
198
- enable: this.pobLernaConfig.ci,
199
- build: this.pobLernaConfig.typescript,
200
- typescript: this.pobLernaConfig.typescript,
185
+ this.composeWith('pob:common:husky', {});
186
+
187
+ this.composeWith('pob:common:testing', {
188
+ monorepo: true,
189
+ enable: this.pobLernaConfig.testing,
201
190
  testing: this.pobLernaConfig.testing,
202
- codecov: this.pobLernaConfig.codecov,
203
- documentation: this.pobLernaConfig.documentation,
204
- updateOnly: this.options.updateOnly,
191
+ typescript: this.pobLernaConfig.typescript,
192
+ documentation: !!this.pobLernaConfig.documentation,
193
+ codecov: this.pobLernaConfig.testing && this.pobLernaConfig.codecov,
194
+ ci: this.pobLernaConfig.ci,
205
195
  packageManager: this.options.packageManager,
206
196
  });
207
197
 
208
- this.composeWith('pob:common:husky', {});
209
-
210
198
  this.composeWith('pob:common:format-lint', {
211
199
  monorepo: true,
212
200
  documentation: this.pobLernaConfig.documentation,
@@ -152,19 +152,6 @@ export default class MonorepoLernaGenerator extends Generator {
152
152
 
153
153
  packageUtils.removeDevDependencies(pkg, ['standard-version']);
154
154
 
155
- const getPobConfig = (config) => ({
156
- ...(config &&
157
- config.pob &&
158
- (config.pob['pob-config'] || config.pob.lib || config.pob.app)),
159
- });
160
- // ynnub doesnt use babel but still have typescript
161
- // const withTypescript = this.packagePaths.some((packagePath) =>
162
- // this.fs.exists(this.destinationPath(`${packagePath}/tsconfig.json`)),
163
- // );
164
- const withTests = this.packagesConfig.some(
165
- (config) => getPobConfig(config).testing,
166
- );
167
-
168
155
  const monorepoConfig = this.config.get('monorepo');
169
156
  const packageManager = this.npm ? 'npm' : 'yarn';
170
157
  const useYarnWorkspacesCommand =
@@ -205,14 +192,6 @@ export default class MonorepoLernaGenerator extends Generator {
205
192
  ),
206
193
  );
207
194
 
208
- packageUtils.addOrRemoveScripts(pkg, withTests, {
209
- test: `${
210
- useYarnWorkspacesCommand
211
- ? 'yarn workspaces foreach --parallel -Av run'
212
- : 'lerna run --stream'
213
- } test`,
214
- });
215
-
216
195
  packageUtils.addOrRemoveScripts(pkg, withBabel, {
217
196
  build: `${
218
197
  useYarnWorkspacesCommand
package/lib/pob.js CHANGED
@@ -286,16 +286,14 @@ const options = {
286
286
  force: argv.force,
287
287
  };
288
288
 
289
- (async () => {
290
- try {
291
- await env.run('pob', options);
292
- } catch (err) {
293
- if (err) {
294
- console.error(err.stack || err.message || err);
295
- process.exit(1);
296
- }
289
+ try {
290
+ await env.run('pob', options);
291
+ } catch (err) {
292
+ if (err) {
293
+ console.error(err.stack || err.message || err);
294
+ process.exit(1);
297
295
  }
298
- })();
296
+ }
299
297
 
300
298
  // generator.on('error', (err) => {
301
299
  // console.error(err.stack || err.message || err);
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ // eslint-disable-next-line import/no-extraneous-dependencies
4
+ exports.pobEslintConfig = require('@pob/eslint-config/package.json');
5
+
6
+ // eslint-disable-next-line import/no-extraneous-dependencies
7
+ exports.pobEslintConfigTypescript = require('@pob/eslint-config-typescript/package.json');
8
+
9
+ // eslint-disable-next-line import/no-extraneous-dependencies
10
+ exports.pobEslintConfigTypescriptReact = require('@pob/eslint-config-typescript-react/package.json');
@@ -0,0 +1,7 @@
1
+ import JSON5 from 'json5';
2
+
3
+ export function readJSON5(fs, destinationPath, defaults) {
4
+ const content = fs.read(destinationPath, null);
5
+ if (content === null) return defaults;
6
+ return JSON5.parse(content);
7
+ }
@@ -3,6 +3,11 @@ import sortPkg from '@pob/sort-pkg';
3
3
  import parseAuthor from 'parse-author';
4
4
  import pobDependencies from 'pob-dependencies';
5
5
  import semver from 'semver';
6
+ import {
7
+ pobEslintConfig,
8
+ pobEslintConfigTypescript,
9
+ pobEslintConfigTypescriptReact,
10
+ } from './dependenciesPackages.cjs';
6
11
 
7
12
  export { default as parseAuthor } from 'parse-author';
8
13
 
@@ -37,9 +42,6 @@ export const hasReact = (pkg) =>
37
42
  (pkg.peerDependencies && pkg.peerDependencies.react)
38
43
  );
39
44
 
40
- export const hasJest = (pkg) =>
41
- !!(pkg.devDependencies && pkg.devDependencies.jest);
42
-
43
45
  export const sort = function sort(pkg) {
44
46
  return sortPkg(pkg);
45
47
  };
@@ -65,7 +67,7 @@ function internalAddToObject(pkg, key, object) {
65
67
 
66
68
  function internalRemoveFromObject(pkg, key, keys) {
67
69
  if (!pkg[key]) return;
68
- keys.forEach((k) => {
70
+ keys.filter(Boolean).forEach((k) => {
69
71
  delete pkg[key][k];
70
72
  });
71
73
  if (Object.keys(pkg[key]).length === 0) {
@@ -81,6 +83,26 @@ const internalRemoveDependencies = (pkg, type, dependencyKeys) => {
81
83
  };
82
84
 
83
85
  const getVersionFromDependencyName = (dependency) => {
86
+ if (
87
+ [
88
+ // 'eslint-import-resolver-node',
89
+ 'eslint-plugin-import',
90
+ 'eslint-plugin-node',
91
+ 'eslint-plugin-unicorn',
92
+ ].includes(dependency)
93
+ ) {
94
+ return pobEslintConfig.dependencies[dependency];
95
+ }
96
+ if (['eslint-plugin-jsx-a11y', 'eslint-plugin-react'].includes(dependency)) {
97
+ return pobEslintConfigTypescriptReact.dependencies[dependency];
98
+ }
99
+ if (
100
+ ['@typescript-eslint/eslint-plugin', '@typescript-eslint/parser'].includes(
101
+ dependency,
102
+ )
103
+ ) {
104
+ return pobEslintConfigTypescript.dependencies[dependency];
105
+ }
84
106
  return pobDependencies[dependency];
85
107
  };
86
108
 
@@ -91,7 +113,7 @@ const internalAddDependencies = (pkg, type, dependencies, cleaned, prefix) => {
91
113
  const removeDependencies = [];
92
114
 
93
115
  const dependenciesToCheck = [];
94
- dependencies.forEach((dependency) => {
116
+ dependencies.filter(Boolean).forEach((dependency) => {
95
117
  if (ignoreDependencies[dependency] || pkg.name === dependency) {
96
118
  removeDependencies.push(dependency);
97
119
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "9.3.0",
3
+ "version": "9.6.0",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/jest",
5
5
  "keywords": [
6
6
  "skeleton"
@@ -57,18 +57,19 @@
57
57
  "github-username": "^6.0.0",
58
58
  "got": "^11.8.1",
59
59
  "inquirer-npm-name": "^4.0.0",
60
+ "json5": "^2.2.0",
60
61
  "lodash.camelcase": "^4.3.0",
61
62
  "lodash.kebabcase": "^4.1.1",
62
63
  "mem-fs": "1.2.0",
63
64
  "mem-fs-editor": "8.1.2",
64
65
  "minimist-argv": "^1.1.0",
65
66
  "parse-author": "^2.0.0",
66
- "pob-dependencies": "^6.0.4",
67
+ "pob-dependencies": "^6.2.0",
67
68
  "prettier": "2.5.1",
68
69
  "semver": "^7.3.4",
69
70
  "update-notifier": "^5.0.1",
70
71
  "yeoman-environment": "^3.5.1",
71
72
  "yeoman-generator": "^5.4.0"
72
73
  },
73
- "gitHead": "937094f6b4c7776dabb6414630f2c3e5740b8489"
74
+ "gitHead": "60c7c5d5ced2306853000642d05efb12e6115f4b"
74
75
  }
@@ -1,14 +0,0 @@
1
- 'use strict';
2
-
3
- const path = require('path');
4
-
5
- module.exports = function babelConfig(api) {
6
- const isTest = api.env('test');
7
-
8
- if (!isTest) return {};
9
-
10
- return {
11
- only: [path.resolve(__dirname, 'src')],
12
- presets: [require.resolve('pob-babel/preset')],
13
- };
14
- };
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["config:js-app", "@pob"]
3
- }
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["config:js-lib", "@pob"]
3
- }