sku 12.5.0 → 12.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.
- package/CHANGELOG.md +63 -0
- package/README.md +13 -5
- package/config/babel/babelConfig.js +7 -1
- package/config/webpack/plugins/createHtmlRenderPlugin.js +1 -1
- package/config/webpack/utils/resolvePackage.js +2 -1
- package/context/defaultCompilePackages.js +65 -39
- package/lib/allocatePort.js +2 -1
- package/lib/buildFileUtils.js +16 -6
- package/lib/configure.js +2 -1
- package/lib/copyDirContents.js +1 -0
- package/lib/createServer.js +1 -0
- package/lib/cwd.js +1 -0
- package/lib/env.js +1 -0
- package/lib/exists.js +1 -0
- package/lib/getSiteForHost.js +1 -0
- package/lib/install.js +2 -0
- package/lib/isCI.js +1 -0
- package/lib/isCompilePackage.js +1 -0
- package/lib/isEmptyDir.js +1 -0
- package/lib/parseArgs.js +4 -1
- package/lib/routeMatcher.js +1 -0
- package/lib/runBin.js +3 -2
- package/lib/runTsc.js +1 -0
- package/lib/runVocab.js +1 -0
- package/lib/storybook.js +1 -0
- package/lib/suggestScript.js +1 -0
- package/lib/validateLessFiles.js +9 -3
- package/lib/validatePeerDeps.js +34 -22
- package/package.json +8 -6
- package/scripts/build-storybook.js +2 -2
- package/scripts/build.js +2 -2
- package/scripts/init.js +17 -16
- package/tsconfig.json +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# sku
|
|
2
2
|
|
|
3
|
+
## 12.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add support for [removing assertion functions][assertion removal docs] named `invariant` and assertions from the `tiny-invariant` library, a lightweight alternative to `assert` ([#966](https://github.com/seek-oss/sku/pull/966))
|
|
8
|
+
|
|
9
|
+
**EXAMPLE USAGE**:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import invariant from 'tiny-invariant';
|
|
14
|
+
|
|
15
|
+
export const Rating = ({ rating }: { rating: number }) => {
|
|
16
|
+
invariant(rating >= 0 && rating <= 5, 'Rating must be between 0 and 5');
|
|
17
|
+
|
|
18
|
+
return <div>...</div>;
|
|
19
|
+
};
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
[assertion removal docs]: https://seek-oss.github.io/sku/#/./docs/extra-features?id=assertion-removal
|
|
23
|
+
|
|
24
|
+
## 12.5.1
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Remove `rimraf` dependency in favour of Node.js's `rm` ([#961](https://github.com/seek-oss/sku/pull/961))
|
|
29
|
+
|
|
30
|
+
- Unpin and bump `@pmmmwh/react-refresh-webpack-plugin` ([#959](https://github.com/seek-oss/sku/pull/959))
|
|
31
|
+
|
|
32
|
+
- Ensure all sku-generated gitignored files are present in `.prettierignore` and `.eslintignore` too ([#957](https://github.com/seek-oss/sku/pull/957))
|
|
33
|
+
|
|
34
|
+
Consumers should notice a few new files being added to the sku-managed sections within `.prettierignore` and `.eslintignore` the next time a `sku` command is run:
|
|
35
|
+
|
|
36
|
+
```diff
|
|
37
|
+
# managed by sku
|
|
38
|
+
*.less.d.ts
|
|
39
|
+
+.eslintcache
|
|
40
|
+
+.eslintrc
|
|
41
|
+
+.prettierrc
|
|
42
|
+
.storybook/main.js
|
|
43
|
+
coverage/
|
|
44
|
+
dist-storybook/
|
|
45
|
+
dist/
|
|
46
|
+
report/
|
|
47
|
+
# end managed by sku
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
These changes should be committed to your repo.
|
|
51
|
+
|
|
52
|
+
- Disable peer dependency validation for PNPM ([#952](https://github.com/seek-oss/sku/pull/952))
|
|
53
|
+
|
|
54
|
+
The method we currently use to validate peer dependencies and warn users about duplicate package is not compatible with how PNPM organizes dependencies in `node_modules`. This feature has been disabled for PNPM repos until further notice.
|
|
55
|
+
|
|
56
|
+
- Replace `memoizee` dependency with `nano-memoize` ([#953](https://github.com/seek-oss/sku/pull/953))
|
|
57
|
+
|
|
58
|
+
- Replace `fast-glob` with `fdir` and `picomatch` ([#952](https://github.com/seek-oss/sku/pull/952))
|
|
59
|
+
|
|
60
|
+
- Replace `validate-npm-package-name` dependency with a regexp ([#954](https://github.com/seek-oss/sku/pull/954))
|
|
61
|
+
|
|
62
|
+
- Improve performance of peer dependency validation ([#952](https://github.com/seek-oss/sku/pull/952))
|
|
63
|
+
|
|
64
|
+
Peer dependency validation shoould now complete within a few seconds, rather than a few minutes.
|
|
65
|
+
|
|
3
66
|
## 12.5.0
|
|
4
67
|
|
|
5
68
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
Front-end development toolkit, powered by [Webpack](https://webpack.js.org/), [Babel](https://babeljs.io/), [Vanilla Extract](https://vanilla-extract.style/), [CSS Modules](https://github.com/css-modules/css-modules), [Less](http://lesscss.org/), [ESLint](http://eslint.org/), [Prettier](https://prettier.io/), [Jest](https://facebook.github.io/jest/) and [Storybook](https://storybook.js.org/).
|
|
8
8
|
|
|
9
|
-
Quickly get up and running with a zero-config development environment, or optionally add minimal config when needed.
|
|
9
|
+
Quickly get up and running with a zero-config development environment, or optionally add minimal config when needed.
|
|
10
|
+
Designed for usage with [braid-design-system](https://github.com/seek-oss/braid-design-system), although this isn't a requirement.
|
|
10
11
|
|
|
11
12
|
This tool is heavily inspired by other work, most notably:
|
|
12
13
|
|
|
@@ -14,13 +15,19 @@ This tool is heavily inspired by other work, most notably:
|
|
|
14
15
|
- [insin/nwb](https://github.com/insin/nwb)
|
|
15
16
|
- [NYTimes/kyt](https://github.com/NYTimes/kyt)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
> While this software is open source, its primary purpose is to improve consistency, cross-team collaboration and code quality at SEEK.
|
|
20
|
+
> As a result, it’s likely that this tool may not exactly suit your needs, or may be overkill for your use case.
|
|
21
|
+
> It may be worth considering alternatives such as [Vite] or [Parcel].
|
|
22
|
+
|
|
23
|
+
[Vite]: https://vitejs.dev/
|
|
24
|
+
[Parcel]: https://parceljs.org/
|
|
18
25
|
|
|
19
26
|
## Getting Started
|
|
20
27
|
|
|
21
28
|
Create a new project and start a local development environment:
|
|
22
29
|
|
|
23
|
-
```
|
|
30
|
+
```sh
|
|
24
31
|
$ npx sku init my-app
|
|
25
32
|
$ cd my-app
|
|
26
33
|
$ yarn start
|
|
@@ -30,7 +37,7 @@ By default, a new project's dependencies will be installed with the first suppor
|
|
|
30
37
|
Package managers are detected in the following order: `yarn` -> `pnpm` -> `npm`.
|
|
31
38
|
This can be overridden via the `--packageManager` flag:
|
|
32
39
|
|
|
33
|
-
```
|
|
40
|
+
```sh
|
|
34
41
|
$ pnpm dlx sku init --packageManager pnpm my-app
|
|
35
42
|
$ cd my-app
|
|
36
43
|
$ pnpm start
|
|
@@ -40,7 +47,8 @@ $ pnpm start
|
|
|
40
47
|
|
|
41
48
|
## Contributing
|
|
42
49
|
|
|
43
|
-
Refer to [CONTRIBUTING.md](/CONTRIBUTING.md).
|
|
50
|
+
Refer to [CONTRIBUTING.md](/CONTRIBUTING.md).
|
|
51
|
+
If you're planning to change the public API, please [open a new issue](https://github.com/seek-oss/sku/issues/new).
|
|
44
52
|
|
|
45
53
|
## License
|
|
46
54
|
|
|
@@ -55,7 +55,13 @@ module.exports = ({
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (removeAssertionsInProduction) {
|
|
58
|
-
plugins.push(
|
|
58
|
+
plugins.push([
|
|
59
|
+
require.resolve('babel-plugin-unassert'),
|
|
60
|
+
{
|
|
61
|
+
variables: ['assert', 'invariant'],
|
|
62
|
+
modules: ['assert', 'node:assert', 'tiny-invariant'],
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require('node:path');
|
|
2
|
-
const memoize = require('
|
|
2
|
+
const { default: memoize } = require('nano-memoize');
|
|
3
3
|
const debug = require('debug')('sku:resolvePackage');
|
|
4
4
|
const { cwd } = require('../../../lib/cwd');
|
|
5
5
|
|
|
@@ -37,6 +37,7 @@ const createPackageResolver = (fs, resolve) => {
|
|
|
37
37
|
*
|
|
38
38
|
* Throws if a package is listed in the project's dependencies and cannot be resolved.
|
|
39
39
|
*/
|
|
40
|
+
/** @param {string} packageName */
|
|
40
41
|
function resolvePackage(packageName) {
|
|
41
42
|
try {
|
|
42
43
|
// First, try to use require.resolve to find the package.
|
|
@@ -1,57 +1,83 @@
|
|
|
1
1
|
const { posix: path } = require('node:path');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
|
-
const
|
|
3
|
+
const { fdir: Fdir } = require('fdir');
|
|
4
4
|
|
|
5
|
-
const { cwd
|
|
5
|
+
const { cwd } = require('../lib/cwd');
|
|
6
6
|
const toPosixPath = require('../lib/toPosixPath');
|
|
7
7
|
|
|
8
8
|
const { rootDir, isPnpm } = require('../lib/packageManager');
|
|
9
|
+
const debug = require('debug')('sku:compilePackages');
|
|
9
10
|
|
|
10
11
|
/** @type {string[]} */
|
|
11
12
|
let detectedCompilePackages = [];
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// If there's no rootDir, we're either inside `sku init`, or we can't determine the user's
|
|
15
|
+
// package manager. In either case, we can't correctly detect compile packages.
|
|
16
|
+
if (rootDir) {
|
|
17
|
+
try {
|
|
18
|
+
let crawler = new Fdir();
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'.',
|
|
24
|
-
pnpmVirtualStorePath,
|
|
25
|
-
);
|
|
26
|
-
const pnpmVirtualStoreGlob = path.join(
|
|
27
|
-
pnpmVirtualStoreRelativePath,
|
|
28
|
-
'@seek*/node_modules/@seek/*/package.json',
|
|
29
|
-
);
|
|
20
|
+
if (isPnpm) {
|
|
21
|
+
// Follow symlinks inside node_modules into the pnpm virtual store
|
|
22
|
+
crawler = crawler.withSymlinks().withRelativePaths();
|
|
23
|
+
} else {
|
|
24
|
+
crawler = crawler.withBasePath();
|
|
25
|
+
}
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
const seekDependencyGlob = '**/@seek/*/package.json';
|
|
28
|
+
|
|
29
|
+
let results = crawler
|
|
30
|
+
.glob(seekDependencyGlob)
|
|
31
|
+
.crawl('./node_modules/@seek')
|
|
32
|
+
.sync();
|
|
33
|
+
|
|
34
|
+
if (isPnpm) {
|
|
35
|
+
const pnpmVirtualStorePath = path.join(
|
|
36
|
+
toPosixPath(rootDir),
|
|
37
|
+
'node_modules/.pnpm',
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const pnpmVirtualStoreRelativePath = path.relative(
|
|
41
|
+
'.',
|
|
42
|
+
pnpmVirtualStorePath,
|
|
43
|
+
);
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
const pnpmVirtualStoreResults = new Fdir()
|
|
46
|
+
.withRelativePaths()
|
|
47
|
+
.glob(seekDependencyGlob)
|
|
48
|
+
.crawl(pnpmVirtualStoreRelativePath)
|
|
49
|
+
.sync();
|
|
50
|
+
|
|
51
|
+
results.push(...pnpmVirtualStoreResults);
|
|
52
|
+
|
|
53
|
+
// All results will be relative to the virtual store directory, so we need
|
|
54
|
+
// to prepend the relative path from the current directory to the virtual store
|
|
55
|
+
results = results.map((file) =>
|
|
56
|
+
path.join(pnpmVirtualStoreRelativePath, file),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
detectedCompilePackages = results
|
|
61
|
+
.map((packagePath) => {
|
|
62
|
+
const packageJson = require(path.join(cwd(), packagePath));
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
isCompilePackage: Boolean(packageJson.skuCompilePackage),
|
|
66
|
+
packageName: packageJson.name,
|
|
67
|
+
};
|
|
68
|
+
})
|
|
69
|
+
.filter(({ isCompilePackage }) => isCompilePackage)
|
|
70
|
+
.map(({ packageName }) => packageName);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.log(
|
|
73
|
+
chalk.red`Warning: Failed to detect compile packages. Contact #sku-support.`,
|
|
74
|
+
);
|
|
75
|
+
console.error(e);
|
|
76
|
+
}
|
|
53
77
|
}
|
|
54
78
|
|
|
79
|
+
debug(detectedCompilePackages);
|
|
80
|
+
|
|
55
81
|
module.exports = [
|
|
56
82
|
'sku',
|
|
57
83
|
'braid-design-system',
|
package/lib/allocatePort.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const { yellow, bold } = require('chalk');
|
|
2
3
|
const getPort = require('get-port');
|
|
3
4
|
const debug = require('debug')('sku:allocatePort');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
|
-
* @param {{ port?: number, host?: string }}
|
|
7
|
+
* @param {{ port?: number, host?: string }} options
|
|
7
8
|
*/
|
|
8
9
|
const allocatePort = async ({ port, host }) => {
|
|
9
10
|
debug(`Finding available port with request for ${port}`);
|
package/lib/buildFileUtils.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const path = require('node:path');
|
|
2
3
|
const fs = require('node:fs/promises');
|
|
3
|
-
const {
|
|
4
|
+
const { fdir: Fdir } = require('fdir');
|
|
4
5
|
|
|
5
6
|
const { paths } = require('../context');
|
|
6
7
|
const exists = require('./exists');
|
|
7
8
|
const copyDirContents = require('./copyDirContents');
|
|
8
9
|
|
|
9
|
-
const cleanTargetDirectory = () =>
|
|
10
|
+
const cleanTargetDirectory = async () => {
|
|
11
|
+
fs.rm(paths.target, { recursive: true, force: true });
|
|
12
|
+
};
|
|
10
13
|
|
|
11
14
|
const copyPublicFiles = async () => {
|
|
12
15
|
if (await exists(paths.public)) {
|
|
@@ -18,14 +21,21 @@ const ensureTargetDirectory = async () => {
|
|
|
18
21
|
await fs.mkdir(paths.target, { recursive: true });
|
|
19
22
|
};
|
|
20
23
|
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
+
const cleanStaticRenderEntry = async () => {
|
|
25
|
+
const files = await new Fdir()
|
|
26
|
+
.withBasePath()
|
|
27
|
+
.filter((file) => file.endsWith('render.js'))
|
|
28
|
+
.crawl(paths.target)
|
|
29
|
+
.withPromise();
|
|
30
|
+
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
await fs.rm(file);
|
|
33
|
+
}
|
|
24
34
|
};
|
|
25
35
|
|
|
26
36
|
module.exports = {
|
|
27
37
|
cleanTargetDirectory,
|
|
28
38
|
copyPublicFiles,
|
|
29
39
|
ensureTargetDirectory,
|
|
30
|
-
|
|
40
|
+
cleanStaticRenderEntry,
|
|
31
41
|
};
|
package/lib/configure.js
CHANGED
|
@@ -48,7 +48,6 @@ module.exports = async () => {
|
|
|
48
48
|
storybookTargetDirectory,
|
|
49
49
|
storybookMainConfigPath,
|
|
50
50
|
];
|
|
51
|
-
const lintIgnorePatterns = [...gitIgnorePatterns, '*.less.d.ts'];
|
|
52
51
|
|
|
53
52
|
// Generate ESLint configuration
|
|
54
53
|
const eslintConfigFilename = '.eslintrc';
|
|
@@ -67,6 +66,8 @@ module.exports = async () => {
|
|
|
67
66
|
});
|
|
68
67
|
gitIgnorePatterns.push(prettierConfigFilename);
|
|
69
68
|
|
|
69
|
+
const lintIgnorePatterns = [...gitIgnorePatterns, '*.less.d.ts'];
|
|
70
|
+
|
|
70
71
|
if (languages) {
|
|
71
72
|
const generatedVocabFileGlob = '**/*.vocab/index.ts';
|
|
72
73
|
gitIgnorePatterns.push(generatedVocabFileGlob);
|
package/lib/copyDirContents.js
CHANGED
package/lib/createServer.js
CHANGED
package/lib/cwd.js
CHANGED
package/lib/env.js
CHANGED
package/lib/exists.js
CHANGED
package/lib/getSiteForHost.js
CHANGED
package/lib/install.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const { getAddCommand } = require('./packageManager');
|
|
2
3
|
|
|
3
4
|
const spawn = require('cross-spawn');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @param {import("../lib/packageManager").GetAddCommandOptions} options
|
|
8
|
+
* @returns {Promise<void>}
|
|
7
9
|
*/
|
|
8
10
|
module.exports = ({ deps, type, logLevel, exact = true }) =>
|
|
9
11
|
new Promise((resolve, reject) => {
|
package/lib/isCI.js
CHANGED
package/lib/isCompilePackage.js
CHANGED
package/lib/isEmptyDir.js
CHANGED
package/lib/parseArgs.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const minimist = require('minimist');
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Supports parsing args that look like:
|
|
5
6
|
* [/path/to/node/node, /path/to/sku, scriptName, arg1, arg2]
|
|
6
7
|
*
|
|
7
|
-
* @param {string[]}
|
|
8
|
+
* @param {string[]} processArgv - should look like process.argv
|
|
8
9
|
*/
|
|
9
10
|
module.exports = (processArgv) => {
|
|
10
11
|
/**
|
|
@@ -48,6 +49,8 @@ module.exports = (processArgv) => {
|
|
|
48
49
|
// need to track them ourselves
|
|
49
50
|
unknown: (arg) => {
|
|
50
51
|
unknown.push(arg);
|
|
52
|
+
|
|
53
|
+
return true;
|
|
51
54
|
},
|
|
52
55
|
},
|
|
53
56
|
);
|
package/lib/routeMatcher.js
CHANGED
package/lib/runBin.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const path = require('node:path');
|
|
2
3
|
const spawn = require('cross-spawn');
|
|
3
4
|
|
|
@@ -45,13 +46,13 @@ const spawnPromise = (commandPath, args, options) => {
|
|
|
45
46
|
*/
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
|
-
* @param {Options}
|
|
49
|
+
* @param {Options} options
|
|
49
50
|
*/
|
|
50
51
|
const runBin = ({ packageName, binName, args, options }) =>
|
|
51
52
|
spawnPromise(resolveBin(packageName, binName), args, options);
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
|
-
* @param {Options}
|
|
55
|
+
* @param {Options} options
|
|
55
56
|
*/
|
|
56
57
|
const startBin = ({ packageName, binName, args, options }) => {
|
|
57
58
|
const childProcess = spawn(resolveBin(packageName, binName), args, options);
|
package/lib/runTsc.js
CHANGED
package/lib/runVocab.js
CHANGED
package/lib/storybook.js
CHANGED
package/lib/suggestScript.js
CHANGED
package/lib/validateLessFiles.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const fs = require('node:fs');
|
|
2
|
-
const path = require('node:path');
|
|
3
|
-
const glob = require('fast-glob');
|
|
4
2
|
const chalk = require('chalk');
|
|
3
|
+
const { fdir: Fdir } = require('fdir');
|
|
5
4
|
|
|
6
5
|
const printBanner = require('./banner');
|
|
7
6
|
const exists = require('./exists');
|
|
@@ -14,11 +13,18 @@ module.exports = async () => {
|
|
|
14
13
|
const lessFileGlobResults = await Promise.all(
|
|
15
14
|
srcPathsExist
|
|
16
15
|
.filter((srcPath) => srcPath && fs.statSync(srcPath).isDirectory())
|
|
17
|
-
.map(async (srcPath) =>
|
|
16
|
+
.map(async (srcPath) =>
|
|
17
|
+
new Fdir()
|
|
18
|
+
.filter((file) => file.endsWith('.less'))
|
|
19
|
+
.crawl(srcPath)
|
|
20
|
+
.withPromise(),
|
|
21
|
+
),
|
|
18
22
|
);
|
|
23
|
+
|
|
19
24
|
const srcHasLessFiles = lessFileGlobResults.some(
|
|
20
25
|
(fileArray) => fileArray.length > 0,
|
|
21
26
|
);
|
|
27
|
+
|
|
22
28
|
if (srcHasLessFiles) {
|
|
23
29
|
printBanner('warning', 'LESS styles detected', [
|
|
24
30
|
`Support for ${chalk.bold('LESS')} has been deprecated.`,
|
package/lib/validatePeerDeps.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
const { getWhyCommand } = require('./packageManager');
|
|
1
|
+
const { getWhyCommand, isPnpm } = require('./packageManager');
|
|
2
2
|
|
|
3
3
|
const { readFile } = require('node:fs/promises');
|
|
4
|
-
const
|
|
4
|
+
const { fdir: Fdir } = require('fdir');
|
|
5
5
|
const semver = require('semver');
|
|
6
6
|
const chalk = require('chalk');
|
|
7
7
|
|
|
8
8
|
const banner = require('./banner');
|
|
9
9
|
const track = require('../telemetry');
|
|
10
|
-
const {
|
|
10
|
+
const { getPathFromCwd } = require('../lib/cwd');
|
|
11
11
|
const { paths } = require('../context');
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -21,30 +21,42 @@ const asyncMap = (list, fn) => {
|
|
|
21
21
|
const singletonPackages = ['@vanilla-extract/css'];
|
|
22
22
|
|
|
23
23
|
module.exports = async () => {
|
|
24
|
+
if (isPnpm) {
|
|
25
|
+
// pnpm doesn't nest dependencies in the same way as yarn or npm, so the method used below won't
|
|
26
|
+
// work for detecting duplicate packages
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
/** @type {string[]} */
|
|
32
|
+
const duplicatePackages = [];
|
|
33
|
+
const packagesToCheck = [...paths.compilePackages, ...singletonPackages];
|
|
34
|
+
|
|
35
|
+
const packagePatterns = packagesToCheck.map((packageName) => [
|
|
36
|
+
packageName,
|
|
37
|
+
`node_modules/${packageName}/package.json`,
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
const patterns = packagePatterns.map(([, pattern]) => pattern);
|
|
41
|
+
|
|
42
|
+
const results = await new Fdir()
|
|
43
|
+
.withBasePath()
|
|
44
|
+
.filter((file) => patterns.some((pattern) => file.endsWith(pattern)))
|
|
45
|
+
.crawl('./node_modules')
|
|
46
|
+
.withPromise();
|
|
47
|
+
|
|
48
|
+
for (const [packageName, pattern] of packagePatterns) {
|
|
49
|
+
const resultsForPackage = results.filter((result) =>
|
|
50
|
+
result.endsWith(pattern),
|
|
39
51
|
);
|
|
40
52
|
|
|
41
|
-
if (
|
|
53
|
+
if (resultsForPackage.length > 1) {
|
|
42
54
|
const messages = [
|
|
43
55
|
chalk`Multiple copies of {bold ${packageName}} are present in node_modules. This is likely to cause errors, but even if it works, it will probably result in an unnecessarily large bundle size.`,
|
|
44
56
|
];
|
|
45
57
|
|
|
46
58
|
messages.push(
|
|
47
|
-
|
|
59
|
+
resultsForPackage
|
|
48
60
|
.map((depLocation) => {
|
|
49
61
|
const { version } = require(getPathFromCwd(depLocation));
|
|
50
62
|
|
|
@@ -64,14 +76,14 @@ module.exports = async () => {
|
|
|
64
76
|
compile_package: packageName,
|
|
65
77
|
});
|
|
66
78
|
banner('error', 'Error: Duplicate packages detected', messages);
|
|
67
|
-
}
|
|
68
79
|
|
|
69
|
-
|
|
80
|
+
duplicatePackages.push(...resultsForPackage);
|
|
81
|
+
}
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
const compilePackages = new Map();
|
|
73
85
|
|
|
74
|
-
await asyncMap(
|
|
86
|
+
await asyncMap(duplicatePackages, async (p) => {
|
|
75
87
|
const contents = await readFile(getPathFromCwd(p), {
|
|
76
88
|
encoding: 'utf8',
|
|
77
89
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sku",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.6.0",
|
|
4
4
|
"description": "Front-end development toolkit, powered by Webpack, Babel, CSS Modules, Less and Jest",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@loadable/server": "^5.14.0",
|
|
40
40
|
"@loadable/webpack-plugin": "^5.14.0",
|
|
41
41
|
"@manypkg/find-root": "^2.2.0",
|
|
42
|
-
"@pmmmwh/react-refresh-webpack-plugin": "0.5.
|
|
42
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.12",
|
|
43
43
|
"@storybook/builder-webpack5": "^7.0.17",
|
|
44
44
|
"@storybook/cli": "^7.0.17",
|
|
45
45
|
"@storybook/react": "^7.0.17",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"eslint-config-seek": "^12.0.1",
|
|
83
83
|
"exception-formatter": "^2.1.2",
|
|
84
84
|
"express": "^4.16.3",
|
|
85
|
-
"fast-glob": "^3.2.5",
|
|
86
85
|
"fastest-validator": "^1.9.0",
|
|
86
|
+
"fdir": "^6.1.1",
|
|
87
87
|
"find-up": "^5.0.0",
|
|
88
88
|
"get-port": "^5.0.0",
|
|
89
89
|
"hostile": "^1.3.3",
|
|
@@ -95,18 +95,18 @@
|
|
|
95
95
|
"less": "^4.1.0",
|
|
96
96
|
"less-loader": "^12.0.0",
|
|
97
97
|
"lint-staged": "^11.1.1",
|
|
98
|
-
"memoizee": "^0.4.15",
|
|
99
98
|
"mini-css-extract-plugin": "^2.6.1",
|
|
100
99
|
"minimist": "^1.2.8",
|
|
100
|
+
"nano-memoize": "^3.0.16",
|
|
101
101
|
"node-html-parser": "^6.1.1",
|
|
102
102
|
"open": "^7.3.1",
|
|
103
103
|
"path-to-regexp": "^6.2.0",
|
|
104
|
+
"picomatch": "^3.0.1",
|
|
104
105
|
"postcss": "^8.4.0",
|
|
105
106
|
"postcss-loader": "^8.0.0",
|
|
106
107
|
"prettier": "^2.8.8",
|
|
107
108
|
"pretty-ms": "^7.0.1",
|
|
108
109
|
"react-refresh": "^0.14.0",
|
|
109
|
-
"rimraf": "^5.0.0",
|
|
110
110
|
"selfsigned": "^2.1.1",
|
|
111
111
|
"semver": "^7.3.4",
|
|
112
112
|
"serialize-javascript": "^6.0.0",
|
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
"terser-webpack-plugin": "^5.1.4",
|
|
116
116
|
"tree-kill": "^1.2.1",
|
|
117
117
|
"typescript": "~5.3.0",
|
|
118
|
-
"validate-npm-package-name": "^5.0.0",
|
|
119
118
|
"webpack": "^5.52.0",
|
|
120
119
|
"webpack-bundle-analyzer": "^4.6.1",
|
|
121
120
|
"webpack-dev-server": "^5.0.2",
|
|
@@ -127,7 +126,10 @@
|
|
|
127
126
|
},
|
|
128
127
|
"devDependencies": {
|
|
129
128
|
"@types/cross-spawn": "^6.0.3",
|
|
129
|
+
"@types/debug": "^4.1.12",
|
|
130
130
|
"@types/express": "^4.17.11",
|
|
131
|
+
"@types/minimist": "^1.2.5",
|
|
132
|
+
"@types/picomatch": "^2.3.3",
|
|
131
133
|
"@types/react": "^18.2.3",
|
|
132
134
|
"@types/react-dom": "^18.2.3",
|
|
133
135
|
"@types/which": "^3.0.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// First, ensure the build is running in production mode
|
|
2
2
|
process.env.NODE_ENV = 'production';
|
|
3
3
|
|
|
4
|
-
const {
|
|
4
|
+
const { rm } = require('node:fs/promises');
|
|
5
5
|
const { argv, config } = require('../config/args');
|
|
6
6
|
const gracefulSpawn = require('../lib/gracefulSpawn');
|
|
7
7
|
const { storybookTarget } = require('../context');
|
|
@@ -11,7 +11,7 @@ const { setUpStorybookConfigDirectory } = require('../lib/storybook');
|
|
|
11
11
|
|
|
12
12
|
(async () => {
|
|
13
13
|
await runVocabCompile();
|
|
14
|
-
await
|
|
14
|
+
await rm(storybookTarget, { recursive: true, force: true });
|
|
15
15
|
await setUpStorybookConfigDirectory();
|
|
16
16
|
|
|
17
17
|
argv.push('build');
|
package/scripts/build.js
CHANGED
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
copyPublicFiles,
|
|
11
11
|
cleanTargetDirectory,
|
|
12
12
|
ensureTargetDirectory,
|
|
13
|
-
|
|
13
|
+
cleanStaticRenderEntry,
|
|
14
14
|
} = require('../lib/buildFileUtils');
|
|
15
15
|
const { run } = require('../lib/runWebpack');
|
|
16
16
|
const createHtmlRenderPlugin = require('../config/webpack/plugins/createHtmlRenderPlugin');
|
|
@@ -31,7 +31,7 @@ const { runVocabCompile } = require('../lib/runVocab');
|
|
|
31
31
|
}),
|
|
32
32
|
),
|
|
33
33
|
);
|
|
34
|
-
await
|
|
34
|
+
await cleanStaticRenderEntry();
|
|
35
35
|
await copyPublicFiles();
|
|
36
36
|
|
|
37
37
|
const timeTaken = performance.now();
|
package/scripts/init.js
CHANGED
|
@@ -11,7 +11,6 @@ const chalk = require('chalk');
|
|
|
11
11
|
const fs = require('node:fs/promises');
|
|
12
12
|
const { posix: path } = require('node:path');
|
|
13
13
|
const { isEmptyDir } = require('../lib/isEmptyDir');
|
|
14
|
-
const validatePackageName = require('validate-npm-package-name');
|
|
15
14
|
const dedent = require('dedent');
|
|
16
15
|
const { setCwd } = require('../lib/cwd');
|
|
17
16
|
const prettierWrite = require('../lib/runPrettier').write;
|
|
@@ -21,7 +20,7 @@ const install = require('../lib/install');
|
|
|
21
20
|
const banner = require('../lib/banner');
|
|
22
21
|
const toPosixPath = require('../lib/toPosixPath');
|
|
23
22
|
const trace = require('debug')('sku:init');
|
|
24
|
-
const
|
|
23
|
+
const { fdir: Fdir } = require('fdir');
|
|
25
24
|
const ejs = require('ejs');
|
|
26
25
|
|
|
27
26
|
const args = require('../config/args');
|
|
@@ -48,6 +47,11 @@ const getTemplateFileDestinationFromRoot =
|
|
|
48
47
|
return path.join(projectRoot, filePathRelativeToTemplate);
|
|
49
48
|
};
|
|
50
49
|
|
|
50
|
+
// Copied from `package-name-regex@4.0.0`
|
|
51
|
+
// See https://github.com/dword-design/package-name-regex/blob/acae7d482b1d03379003899df4d484238625364d/src/index.js#L1-L2
|
|
52
|
+
const packageNameRegex =
|
|
53
|
+
/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
54
|
+
|
|
51
55
|
(async () => {
|
|
52
56
|
const projectName = args.argv[0];
|
|
53
57
|
|
|
@@ -89,21 +93,16 @@ const getTemplateFileDestinationFromRoot =
|
|
|
89
93
|
'braid-design-system',
|
|
90
94
|
].sort();
|
|
91
95
|
|
|
92
|
-
const
|
|
93
|
-
validForNewPackages,
|
|
94
|
-
errors = [],
|
|
95
|
-
warnings = [],
|
|
96
|
-
} = validatePackageName(appName);
|
|
96
|
+
const isValidPackageName = packageNameRegex.test(appName);
|
|
97
97
|
|
|
98
|
-
if (!
|
|
98
|
+
if (!isValidPackageName) {
|
|
99
99
|
console.error(dedent`
|
|
100
|
-
Could not create a project called ${chalk.red(
|
|
101
|
-
|
|
100
|
+
Could not create a project called ${chalk.red(
|
|
101
|
+
`"${appName}"`,
|
|
102
|
+
)} because of npm naming restrictions. \
|
|
103
|
+
Please see https://docs.npmjs.com/cli/configuring-npm/package-json for package name rules.
|
|
102
104
|
`);
|
|
103
105
|
|
|
104
|
-
const results = [...errors, ...warnings];
|
|
105
|
-
results.forEach((result) => console.error(chalk.red(` * ${result}`)));
|
|
106
|
-
|
|
107
106
|
process.exit(1);
|
|
108
107
|
}
|
|
109
108
|
|
|
@@ -152,9 +151,11 @@ const getTemplateFileDestinationFromRoot =
|
|
|
152
151
|
process.chdir(root);
|
|
153
152
|
|
|
154
153
|
const templateDirectory = path.join(toPosixPath(__dirname), '../template');
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
|
|
155
|
+
const templateFiles = await new Fdir()
|
|
156
|
+
.withBasePath()
|
|
157
|
+
.crawl(templateDirectory)
|
|
158
|
+
.withPromise();
|
|
158
159
|
|
|
159
160
|
const getTemplateFileDestination = getTemplateFileDestinationFromRoot(
|
|
160
161
|
root,
|
package/tsconfig.json
DELETED