@lipemat/js-boilerplate 10.9.0 → 10.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/lipemat-js-boilerplate.js +0 -5
- package/config/css-loader.config.js +30 -36
- package/config/css-loader.config.ts +52 -0
- package/helpers/config.js +22 -7
- package/helpers/config.ts +17 -0
- package/helpers/css-classnames.js +55 -69
- package/helpers/css-classnames.ts +117 -0
- package/helpers/entries.js +1 -2
- package/helpers/modules.js +1 -2
- package/helpers/package-config.js +1 -2
- package/package.json +10 -10
- package/tsconfig.json +2 -1
- package/types/css-loader.d.ts +87 -0
- package/types/utility.d.ts +1 -0
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// Update notifier.
|
|
5
|
-
const updateNotifier = require( 'update-notifier' );
|
|
6
|
-
const pkg = require( '../package.json' );
|
|
7
|
-
updateNotifier( {pkg, shouldNotifyInNpmScript: true} ).notify();
|
|
8
|
-
|
|
9
4
|
const spawn = require( 'cross-spawn' );
|
|
10
5
|
const args = process.argv.slice( 2 );
|
|
11
6
|
|
|
@@ -1,51 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const css_classnames_1 = require("../helpers/css-classnames");
|
|
3
4
|
/**
|
|
4
5
|
* Options for the Webpack `css-loader`.
|
|
5
6
|
*
|
|
6
7
|
* Extracted to its on file to allow easy overrides.
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
9
|
/**
|
|
10
10
|
* Default to :global for classes in "global" or "pcss" directories.
|
|
11
11
|
*
|
|
12
12
|
* @param {string} resourcePath
|
|
13
13
|
* @return {string}
|
|
14
14
|
*/
|
|
15
|
-
const mode = resourcePath => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
const mode = (resourcePath) => {
|
|
16
|
+
if (/globals?\//i.test(resourcePath.replace(/\\/g, '/'))) {
|
|
17
|
+
return 'global';
|
|
18
|
+
}
|
|
19
|
+
if (/pcss?\//i.test(resourcePath.replace(/\\/g, '/'))) {
|
|
20
|
+
return 'global';
|
|
21
|
+
}
|
|
22
|
+
return 'local';
|
|
23
23
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
url: false,
|
|
24
|
+
const cssLoader = {
|
|
25
|
+
importLoaders: 1,
|
|
26
|
+
modules: {
|
|
27
|
+
exportLocalsConvention: 'camelCase',
|
|
28
|
+
localIdentName: 'Ⓜ[name]__[local]__[contenthash:base64:2]',
|
|
29
|
+
mode,
|
|
30
|
+
},
|
|
31
|
+
sourceMap: true,
|
|
32
|
+
url: false,
|
|
34
33
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
mode,
|
|
46
|
-
},
|
|
47
|
-
url: false,
|
|
48
|
-
};
|
|
34
|
+
if ('production' === process.env.NODE_ENV) {
|
|
35
|
+
cssLoader.modules = {
|
|
36
|
+
exportLocalsConvention: 'camelCase',
|
|
37
|
+
// Use short CSS Classes if enabled.
|
|
38
|
+
...(0, css_classnames_1.usingShortCssClasses)() ? { getLocalIdent: css_classnames_1.getLocalIdent } : {},
|
|
39
|
+
// Hash used when short CSS classes are not enabled.
|
|
40
|
+
localIdentName: '[contenthash:base64:5]',
|
|
41
|
+
mode,
|
|
42
|
+
};
|
|
43
|
+
cssLoader.sourceMap = false;
|
|
49
44
|
}
|
|
50
|
-
|
|
51
45
|
module.exports = cssLoader;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {getLocalIdent, usingShortCssClasses} from '../helpers/css-classnames';
|
|
2
|
+
import type {Config, Mode} from '../types/css-loader';
|
|
3
|
+
import type {AtLeast} from '../types/utility';
|
|
4
|
+
|
|
5
|
+
export type CssLoaderConfig = AtLeast<Config, 'importLoaders' | 'modules' | 'sourceMap' | 'url'>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for the Webpack `css-loader`.
|
|
9
|
+
*
|
|
10
|
+
* Extracted to its on file to allow easy overrides.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default to :global for classes in "global" or "pcss" directories.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} resourcePath
|
|
17
|
+
* @return {string}
|
|
18
|
+
*/
|
|
19
|
+
const mode = ( resourcePath: string ): Mode => {
|
|
20
|
+
if ( /globals?\//i.test( resourcePath.replace( /\\/g, '/' ) ) ) {
|
|
21
|
+
return 'global';
|
|
22
|
+
}
|
|
23
|
+
if ( /pcss?\//i.test( resourcePath.replace( /\\/g, '/' ) ) ) {
|
|
24
|
+
return 'global';
|
|
25
|
+
}
|
|
26
|
+
return 'local';
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const cssLoader: CssLoaderConfig = {
|
|
30
|
+
importLoaders: 1,
|
|
31
|
+
modules: {
|
|
32
|
+
exportLocalsConvention: 'camelCase',
|
|
33
|
+
localIdentName: 'Ⓜ[name]__[local]__[contenthash:base64:2]',
|
|
34
|
+
mode,
|
|
35
|
+
},
|
|
36
|
+
sourceMap: true,
|
|
37
|
+
url: false,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if ( 'production' === process.env.NODE_ENV ) {
|
|
41
|
+
cssLoader.modules = {
|
|
42
|
+
exportLocalsConvention: 'camelCase',
|
|
43
|
+
// Use short CSS Classes if enabled.
|
|
44
|
+
...usingShortCssClasses() ? {getLocalIdent} : {},
|
|
45
|
+
// Hash used when short CSS classes are not enabled.
|
|
46
|
+
localIdentName: '[contenthash:base64:5]',
|
|
47
|
+
mode,
|
|
48
|
+
}
|
|
49
|
+
cssLoader.sourceMap = false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = cssLoader;
|
package/helpers/config.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getDefaultBrowsersList = void 0;
|
|
4
|
+
exports.hasLocalOverride = hasLocalOverride;
|
|
5
|
+
exports.getConfig = getConfig;
|
|
6
|
+
exports.getExtensionsConfig = getExtensionsConfig;
|
|
7
|
+
exports.getTsConfigFile = getTsConfigFile;
|
|
8
|
+
exports.getBrowsersList = getBrowsersList;
|
|
9
|
+
exports.adjustBrowserslist = adjustBrowserslist;
|
|
4
10
|
const fs_1 = require("fs");
|
|
5
11
|
const path_1 = require("path");
|
|
6
12
|
const package_config_1 = require("./package-config");
|
|
@@ -32,10 +38,14 @@ function hasLocalOverride(fileName, inWorkingDirectory = false) {
|
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
catch (e) {
|
|
41
|
+
if (e instanceof Error) {
|
|
42
|
+
if (!('code' in e) || 'MODULE_NOT_FOUND' !== e.code) {
|
|
43
|
+
console.error(e);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
35
46
|
}
|
|
36
47
|
return hasLocal;
|
|
37
48
|
}
|
|
38
|
-
exports.hasLocalOverride = hasLocalOverride;
|
|
39
49
|
/**
|
|
40
50
|
* Get a config from our /config directory merged with any
|
|
41
51
|
* matching configuration from the project directory.
|
|
@@ -77,10 +87,14 @@ function getConfig(fileName) {
|
|
|
77
87
|
}
|
|
78
88
|
}
|
|
79
89
|
catch (e) {
|
|
90
|
+
if (e instanceof Error) {
|
|
91
|
+
if (!('code' in e) || 'MODULE_NOT_FOUND' !== e.code) {
|
|
92
|
+
console.error(e);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
80
95
|
}
|
|
81
96
|
return mergedConfig;
|
|
82
97
|
}
|
|
83
|
-
exports.getConfig = getConfig;
|
|
84
98
|
/**
|
|
85
99
|
* Get a config from any existing extension's /config directories
|
|
86
100
|
* merged into one.
|
|
@@ -106,11 +120,15 @@ function getExtensionsConfig(fileName, defaultConfig) {
|
|
|
106
120
|
}
|
|
107
121
|
}
|
|
108
122
|
catch (e) {
|
|
123
|
+
if (e instanceof Error) {
|
|
124
|
+
if (!('code' in e) || 'MODULE_NOT_FOUND' !== e.code) {
|
|
125
|
+
console.error(e);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
109
128
|
}
|
|
110
129
|
});
|
|
111
130
|
return mergedConfig;
|
|
112
131
|
}
|
|
113
|
-
exports.getExtensionsConfig = getExtensionsConfig;
|
|
114
132
|
/**
|
|
115
133
|
* Get the path to the "tsconfig.json" file if it exists.
|
|
116
134
|
*
|
|
@@ -134,7 +152,6 @@ function getTsConfigFile() {
|
|
|
134
152
|
});
|
|
135
153
|
return tsConfig;
|
|
136
154
|
}
|
|
137
|
-
exports.getTsConfigFile = getTsConfigFile;
|
|
138
155
|
/**
|
|
139
156
|
* Get the browserslist from the current project.
|
|
140
157
|
*
|
|
@@ -150,7 +167,6 @@ function getBrowsersList() {
|
|
|
150
167
|
}
|
|
151
168
|
return projectBrowsersList;
|
|
152
169
|
}
|
|
153
|
-
exports.getBrowsersList = getBrowsersList;
|
|
154
170
|
/**
|
|
155
171
|
* If browserslist is not specified, we fall back to WordPress defaults.
|
|
156
172
|
*
|
|
@@ -183,4 +199,3 @@ function adjustBrowserslist(browserRules) {
|
|
|
183
199
|
browserRules.push('not op_mini all');
|
|
184
200
|
return browserRules;
|
|
185
201
|
}
|
|
186
|
-
exports.adjustBrowserslist = adjustBrowserslist;
|
package/helpers/config.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {JestConfig} from '../config/jest.config';
|
|
|
6
6
|
import {getPackageConfig} from './package-config';
|
|
7
7
|
import type {EntriesConfig} from '../config/entries.config';
|
|
8
8
|
import type {Config as PostCSSConfig} from 'postcss-load-config';
|
|
9
|
+
import type {CssLoaderConfig} from '../config/css-loader.config';
|
|
9
10
|
|
|
10
11
|
// Must be required to avoid issues with browserslist.
|
|
11
12
|
const browserslist = require( 'browserslist' );
|
|
@@ -13,6 +14,7 @@ const browserslist = require( 'browserslist' );
|
|
|
13
14
|
|
|
14
15
|
type Configs = {
|
|
15
16
|
'babel.config': BabelConfig;
|
|
17
|
+
'css-loader.config': CssLoaderConfig;
|
|
16
18
|
'entries.config': EntriesConfig;
|
|
17
19
|
'jest.config': JestConfig;
|
|
18
20
|
'postcss.config': PostCSSConfig;
|
|
@@ -46,6 +48,11 @@ export function hasLocalOverride( fileName: string, inWorkingDirectory: boolean
|
|
|
46
48
|
hasLocal = true;
|
|
47
49
|
}
|
|
48
50
|
} catch ( e ) {
|
|
51
|
+
if ( e instanceof Error ) {
|
|
52
|
+
if ( ! ( 'code' in e ) || 'MODULE_NOT_FOUND' !== e.code ) {
|
|
53
|
+
console.error( e );
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
return hasLocal;
|
|
@@ -91,6 +98,11 @@ export function getConfig<T extends keyof Configs>( fileName: T ): Configs[T] {
|
|
|
91
98
|
mergedConfig = {...mergedConfig, ...localConfig};
|
|
92
99
|
}
|
|
93
100
|
} catch ( e ) {
|
|
101
|
+
if ( e instanceof Error ) {
|
|
102
|
+
if ( ! ( 'code' in e ) || 'MODULE_NOT_FOUND' !== e.code ) {
|
|
103
|
+
console.error( e );
|
|
104
|
+
}
|
|
105
|
+
}
|
|
94
106
|
}
|
|
95
107
|
return mergedConfig;
|
|
96
108
|
}
|
|
@@ -119,6 +131,11 @@ export function getExtensionsConfig<T extends object>( fileName: string, default
|
|
|
119
131
|
mergedConfig = {...mergedConfig, ...extensionConfig};
|
|
120
132
|
}
|
|
121
133
|
} catch ( e ) {
|
|
134
|
+
if ( e instanceof Error ) {
|
|
135
|
+
if ( ! ( 'code' in e ) || 'MODULE_NOT_FOUND' !== e.code ) {
|
|
136
|
+
console.error( e );
|
|
137
|
+
}
|
|
138
|
+
}
|
|
122
139
|
}
|
|
123
140
|
} );
|
|
124
141
|
|
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLocalIdent = exports.ALPHABET = exports.SHORT_ALPHABET = void 0;
|
|
4
|
+
exports.usingShortCssClasses = usingShortCssClasses;
|
|
5
|
+
exports.resetCounters = resetCounters;
|
|
6
|
+
exports.getNextClass = getNextClass;
|
|
7
|
+
const package_config_1 = require("./package-config");
|
|
8
|
+
exports.SHORT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
9
|
+
exports.ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
6
10
|
const classes = {};
|
|
7
|
-
let counters = [
|
|
8
|
-
|
|
11
|
+
let counters = [-1];
|
|
9
12
|
/**
|
|
10
13
|
* Check if short CSS classes are enabled.
|
|
11
14
|
*
|
|
12
15
|
* Using a helper function to allow for future enhancements.
|
|
13
16
|
*
|
|
14
|
-
* @since
|
|
17
|
+
* @since 4.6.0
|
|
15
18
|
*/
|
|
16
19
|
function usingShortCssClasses() {
|
|
17
|
-
|
|
20
|
+
return Boolean((0, package_config_1.getPackageConfig)().shortCssClasses);
|
|
18
21
|
}
|
|
19
|
-
|
|
20
22
|
/**
|
|
21
23
|
* Reset all counters.
|
|
22
24
|
*
|
|
23
25
|
* @notice Mostly here for unit tests.
|
|
24
26
|
*/
|
|
25
27
|
function resetCounters() {
|
|
26
|
-
|
|
28
|
+
counters = [-1];
|
|
27
29
|
}
|
|
28
|
-
|
|
29
30
|
/**
|
|
30
31
|
* Get the next class is sequence based on:
|
|
31
|
-
* 1. Single character from SHORT_ALPHABET (prevent conflicts with
|
|
32
|
+
* 1. Single character from SHORT_ALPHABET (prevent conflicts with JS boilerplate).
|
|
32
33
|
* 2. Incremented character from the `ALPHABET`.
|
|
33
34
|
* 1. Used once require 2+ characters.
|
|
34
35
|
* 2. Grows to 3+ characters as needed.
|
|
@@ -36,26 +37,22 @@ function resetCounters() {
|
|
|
36
37
|
* @return {string}
|
|
37
38
|
*/
|
|
38
39
|
function getNextClass() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return 0 === i ? SHORT_ALPHABET[ counter ] : ALPHABET[ counter ];
|
|
55
|
-
} ).join( '' );
|
|
40
|
+
const last = counters.length - 1;
|
|
41
|
+
let totalLetters = exports.ALPHABET.length - 1;
|
|
42
|
+
// First level uses the SHORT_ALPHABET.
|
|
43
|
+
if (0 === last) {
|
|
44
|
+
totalLetters = exports.SHORT_ALPHABET.length - 1;
|
|
45
|
+
}
|
|
46
|
+
if (counters[last] < totalLetters) {
|
|
47
|
+
counters[last]++;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
incrementParent();
|
|
51
|
+
}
|
|
52
|
+
return counters.map((counter, i) => {
|
|
53
|
+
return 0 === i ? exports.SHORT_ALPHABET[counter] : exports.ALPHABET[counter];
|
|
54
|
+
}).join('');
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
56
|
/**
|
|
60
57
|
* When we run out of characters on the current level:
|
|
61
58
|
* 1. Increment the parent level.
|
|
@@ -68,31 +65,28 @@ function getNextClass() {
|
|
|
68
65
|
*
|
|
69
66
|
*/
|
|
70
67
|
function incrementParent() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
counters.forEach( ( _, i ) => counters[ i ] = 0 );
|
|
93
|
-
counters.push( 0 );
|
|
68
|
+
let parent = counters.length - 2;
|
|
69
|
+
let totalLetters = exports.ALPHABET.length - 1;
|
|
70
|
+
while (counters[parent] !== undefined) {
|
|
71
|
+
// First level uses the SHORT_ALPHABET.
|
|
72
|
+
if (0 === parent) {
|
|
73
|
+
totalLetters = exports.SHORT_ALPHABET.length - 1;
|
|
74
|
+
}
|
|
75
|
+
if (counters[parent] < totalLetters) {
|
|
76
|
+
counters[parent]++;
|
|
77
|
+
// Reset all child levels to 0.
|
|
78
|
+
while (counters[parent + 1] !== undefined) {
|
|
79
|
+
counters[parent + 1] = 0;
|
|
80
|
+
parent++;
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
parent--;
|
|
85
|
+
}
|
|
86
|
+
// Add a new level and reset all existing levels.
|
|
87
|
+
counters.forEach((_, i) => counters[i] = 0);
|
|
88
|
+
counters.push(0);
|
|
94
89
|
}
|
|
95
|
-
|
|
96
90
|
/**
|
|
97
91
|
* Return a single character unique CSS class name based on WebPack
|
|
98
92
|
* css-loader's `getLocalIdentName` callback.
|
|
@@ -104,17 +98,9 @@ function incrementParent() {
|
|
|
104
98
|
*
|
|
105
99
|
* @link https://webpack.js.org/loaders/css-loader/#getlocalident
|
|
106
100
|
*/
|
|
107
|
-
const getLocalIdent = (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
module.exports = {
|
|
114
|
-
ALPHABET,
|
|
115
|
-
SHORT_ALPHABET,
|
|
116
|
-
getLocalIdent,
|
|
117
|
-
getNextClass,
|
|
118
|
-
usingShortCssClasses,
|
|
119
|
-
resetCounters,
|
|
101
|
+
const getLocalIdent = ({ resourcePath }, _, localName) => {
|
|
102
|
+
classes[resourcePath] ||= {};
|
|
103
|
+
classes[resourcePath][localName] ||= getNextClass();
|
|
104
|
+
return classes[resourcePath][localName];
|
|
120
105
|
};
|
|
106
|
+
exports.getLocalIdent = getLocalIdent;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {getPackageConfig} from './package-config';
|
|
2
|
+
import type {GetLocalIdent, Resource} from '../types/css-loader';
|
|
3
|
+
|
|
4
|
+
export const SHORT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
5
|
+
export const ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
6
|
+
|
|
7
|
+
const classes: {
|
|
8
|
+
[ filename: string ]: {
|
|
9
|
+
[ className: string ]: string
|
|
10
|
+
}
|
|
11
|
+
} = {};
|
|
12
|
+
|
|
13
|
+
let counters = [ -1 ];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if short CSS classes are enabled.
|
|
17
|
+
*
|
|
18
|
+
* Using a helper function to allow for future enhancements.
|
|
19
|
+
*
|
|
20
|
+
* @since 4.6.0
|
|
21
|
+
*/
|
|
22
|
+
export function usingShortCssClasses(): boolean {
|
|
23
|
+
return Boolean( getPackageConfig().shortCssClasses );
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Reset all counters.
|
|
28
|
+
*
|
|
29
|
+
* @notice Mostly here for unit tests.
|
|
30
|
+
*/
|
|
31
|
+
export function resetCounters(): void {
|
|
32
|
+
counters = [ -1 ];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the next class is sequence based on:
|
|
37
|
+
* 1. Single character from SHORT_ALPHABET (prevent conflicts with JS boilerplate).
|
|
38
|
+
* 2. Incremented character from the `ALPHABET`.
|
|
39
|
+
* 1. Used once require 2+ characters.
|
|
40
|
+
* 2. Grows to 3+ characters as needed.
|
|
41
|
+
*
|
|
42
|
+
* @return {string}
|
|
43
|
+
*/
|
|
44
|
+
export function getNextClass(): string {
|
|
45
|
+
const last = counters.length - 1;
|
|
46
|
+
let totalLetters = ALPHABET.length - 1;
|
|
47
|
+
|
|
48
|
+
// First level uses the SHORT_ALPHABET.
|
|
49
|
+
if ( 0 === last ) {
|
|
50
|
+
totalLetters = SHORT_ALPHABET.length - 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if ( counters[ last ] < totalLetters ) {
|
|
54
|
+
counters[ last ]++;
|
|
55
|
+
} else {
|
|
56
|
+
incrementParent();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return counters.map( ( counter, i ) => {
|
|
60
|
+
return 0 === i ? SHORT_ALPHABET[ counter ] : ALPHABET[ counter ];
|
|
61
|
+
} ).join( '' );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* When we run out of characters on the current level:
|
|
67
|
+
* 1. Increment the parent level.
|
|
68
|
+
* 2. Reset current level and all child levels back to 0.
|
|
69
|
+
*
|
|
70
|
+
* If we are out of characters on the parent level or have
|
|
71
|
+
* no parent level:
|
|
72
|
+
* 1. Add a new child level.
|
|
73
|
+
* 2. Reset all levels back to 0.
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
function incrementParent() {
|
|
77
|
+
let parent = counters.length - 2;
|
|
78
|
+
let totalLetters = ALPHABET.length - 1;
|
|
79
|
+
|
|
80
|
+
while ( counters[ parent ] !== undefined ) {
|
|
81
|
+
// First level uses the SHORT_ALPHABET.
|
|
82
|
+
if ( 0 === parent ) {
|
|
83
|
+
totalLetters = SHORT_ALPHABET.length - 1;
|
|
84
|
+
}
|
|
85
|
+
if ( counters[ parent ] < totalLetters ) {
|
|
86
|
+
counters[ parent ]++;
|
|
87
|
+
// Reset all child levels to 0.
|
|
88
|
+
while ( counters[ parent + 1 ] !== undefined ) {
|
|
89
|
+
counters[ parent + 1 ] = 0;
|
|
90
|
+
parent++;
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
parent--;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Add a new level and reset all existing levels.
|
|
98
|
+
counters.forEach( ( _, i ) => counters[ i ] = 0 );
|
|
99
|
+
counters.push( 0 );
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Return a single character unique CSS class name based on WebPack
|
|
104
|
+
* css-loader's `getLocalIdentName` callback.
|
|
105
|
+
*
|
|
106
|
+
* Tracks CSS classes per each file so duplicate uses of the
|
|
107
|
+
* same class in a file receive the same result.
|
|
108
|
+
*
|
|
109
|
+
* @notice Only enabled if the `package.json` has `shortCssClasses` set to true.
|
|
110
|
+
*
|
|
111
|
+
* @link https://webpack.js.org/loaders/css-loader/#getlocalident
|
|
112
|
+
*/
|
|
113
|
+
export const getLocalIdent: GetLocalIdent = ( {resourcePath}: Resource, _: string, localName: string ): string => {
|
|
114
|
+
classes[ resourcePath ] ||= {};
|
|
115
|
+
classes[ resourcePath ][ localName ] ||= getNextClass();
|
|
116
|
+
return classes[ resourcePath ][ localName ];
|
|
117
|
+
};
|
package/helpers/entries.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getEntries =
|
|
3
|
+
exports.getEntries = getEntries;
|
|
4
4
|
const config_1 = require("./config");
|
|
5
5
|
const package_config_1 = require("./package-config");
|
|
6
6
|
const fs_1 = require("fs");
|
|
@@ -28,4 +28,3 @@ function getEntries() {
|
|
|
28
28
|
});
|
|
29
29
|
return matches;
|
|
30
30
|
}
|
|
31
|
-
exports.getEntries = getEntries;
|
package/helpers/modules.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBabelExcludeRegex =
|
|
3
|
+
exports.getBabelExcludeRegex = getBabelExcludeRegex;
|
|
4
4
|
const babel_loader_regex_builder_1 = require("are-you-es5/dist/babel-loader-regex-builder");
|
|
5
5
|
const package_config_1 = require("./package-config");
|
|
6
6
|
const are_you_es5_1 = require("are-you-es5");
|
|
@@ -25,4 +25,3 @@ function getBabelExcludeRegex() {
|
|
|
25
25
|
// We must strip off the leading and trailing '/'.
|
|
26
26
|
return new RegExp(regex.replace(/^\/|\/$/g, ''));
|
|
27
27
|
}
|
|
28
|
-
exports.getBabelExcludeRegex = getBabelExcludeRegex;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPackageConfig =
|
|
3
|
+
exports.getPackageConfig = getPackageConfig;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const node_fs_1 = require("node:fs");
|
|
6
6
|
const workingDirectory = (0, node_fs_1.realpathSync)(process.cwd());
|
|
@@ -33,7 +33,6 @@ catch (e) {
|
|
|
33
33
|
function getPackageConfig() {
|
|
34
34
|
return packageConfig;
|
|
35
35
|
}
|
|
36
|
-
exports.getPackageConfig = getPackageConfig;
|
|
37
36
|
packageConfig.getPackageConfig = getPackageConfig;
|
|
38
37
|
packageConfig.default = packageConfig;
|
|
39
38
|
module.exports = packageConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lipemat/js-boilerplate",
|
|
3
|
-
"version": "10.9.
|
|
3
|
+
"version": "10.9.2",
|
|
4
4
|
"description": "Dependencies and scripts for a no config JavaScript app",
|
|
5
5
|
"author": "Mat Lipe",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"config/",
|
|
29
29
|
"helpers/",
|
|
30
30
|
"lib/",
|
|
31
|
-
"scripts/"
|
|
31
|
+
"scripts/",
|
|
32
|
+
"types/"
|
|
32
33
|
],
|
|
33
34
|
"bin": {
|
|
34
35
|
"lipemat-js-boilerplate": "bin/lipemat-js-boilerplate.js"
|
|
@@ -43,12 +44,12 @@
|
|
|
43
44
|
"watch": "ts-node ./bin/watch.ts"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
|
-
"@babel/core": "^7.
|
|
47
|
+
"@babel/core": "^7.24.7",
|
|
47
48
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
48
|
-
"@babel/plugin-transform-react-jsx-source": "^7.
|
|
49
|
-
"@babel/preset-env": "^7.
|
|
50
|
-
"@babel/preset-react": "^7.
|
|
51
|
-
"@babel/preset-typescript": "^7.
|
|
49
|
+
"@babel/plugin-transform-react-jsx-source": "^7.24.7",
|
|
50
|
+
"@babel/preset-env": "^7.24.7",
|
|
51
|
+
"@babel/preset-react": "^7.24.7",
|
|
52
|
+
"@babel/preset-typescript": "^7.24.7",
|
|
52
53
|
"@csstools/postcss-global-data": "2.0.0",
|
|
53
54
|
"@lipemat/eslint-config": "^3.1.3",
|
|
54
55
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
|
|
@@ -94,8 +95,7 @@
|
|
|
94
95
|
"react-refresh": "^0.14.0",
|
|
95
96
|
"style-loader": "^3.3.1",
|
|
96
97
|
"ts-node": "^10.9.1",
|
|
97
|
-
"typescript": "^5.
|
|
98
|
-
"update-notifier": "^4.1.3",
|
|
98
|
+
"typescript": "^5.5.2",
|
|
99
99
|
"webpack": "^5.72.1",
|
|
100
100
|
"webpack-assets-manifest": "^5.0.6",
|
|
101
101
|
"webpack-cli": "^4.9.1",
|
|
@@ -111,5 +111,5 @@
|
|
|
111
111
|
"memfs": "^3.5.3",
|
|
112
112
|
"setimmediate": "^1.0.5"
|
|
113
113
|
},
|
|
114
|
-
"packageManager": "yarn@4.
|
|
114
|
+
"packageManager": "yarn@4.3.1"
|
|
115
115
|
}
|
package/tsconfig.json
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No public types available.
|
|
3
|
+
*
|
|
4
|
+
* @link https://webpack.js.org/loaders/css-loader/#options
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {LoaderContext} from 'webpack';
|
|
8
|
+
|
|
9
|
+
export type Mode = 'local' | 'global' | 'pure' | 'icss';
|
|
10
|
+
|
|
11
|
+
export type Resource = LoaderContext<{
|
|
12
|
+
resourcePath: string
|
|
13
|
+
}>;
|
|
14
|
+
|
|
15
|
+
export type GetLocalIdent = ( context: Resource, localIdentName: string, localName: string ) => string;
|
|
16
|
+
|
|
17
|
+
export type Modules =
|
|
18
|
+
| boolean
|
|
19
|
+
| 'local'
|
|
20
|
+
| 'global'
|
|
21
|
+
| 'pure'
|
|
22
|
+
| 'icss'
|
|
23
|
+
| {
|
|
24
|
+
auto: boolean | RegExp | ( ( resourcePath: string ) => boolean );
|
|
25
|
+
mode: Mode | ( ( resourcePath: string ) => Mode );
|
|
26
|
+
localIdentName: string;
|
|
27
|
+
localIdentContext: string;
|
|
28
|
+
localIdentHashSalt: string;
|
|
29
|
+
localIdentHashFunction: string;
|
|
30
|
+
localIdentHashDigest: string;
|
|
31
|
+
localIdentRegExp: string | RegExp;
|
|
32
|
+
getLocalIdent: GetLocalIdent;
|
|
33
|
+
namedExport: boolean;
|
|
34
|
+
exportGlobals: boolean;
|
|
35
|
+
exportLocalsConvention:
|
|
36
|
+
| 'asIs'
|
|
37
|
+
| 'camelCase'
|
|
38
|
+
| 'camelCaseOnly'
|
|
39
|
+
| 'dashes'
|
|
40
|
+
| 'dashesOnly'
|
|
41
|
+
| ( ( name: string ) => string );
|
|
42
|
+
exportOnlyLocals: boolean;
|
|
43
|
+
getJSON: ( {
|
|
44
|
+
resourcePath,
|
|
45
|
+
imports,
|
|
46
|
+
exports,
|
|
47
|
+
replacements,
|
|
48
|
+
}: {
|
|
49
|
+
resourcePath: string;
|
|
50
|
+
imports: object[];
|
|
51
|
+
exports: object[];
|
|
52
|
+
replacements: object[];
|
|
53
|
+
} ) => Promise<void> | void;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
type Base = {
|
|
57
|
+
importLoaders?: number;
|
|
58
|
+
sourceMap?: boolean;
|
|
59
|
+
url?: boolean | {
|
|
60
|
+
filter: ( url: string, resourcePath: string ) => boolean;
|
|
61
|
+
};
|
|
62
|
+
importFn?: boolean | {
|
|
63
|
+
filter: (
|
|
64
|
+
url: string,
|
|
65
|
+
media: string,
|
|
66
|
+
resourcePath: string,
|
|
67
|
+
supports?: string,
|
|
68
|
+
layer?: string,
|
|
69
|
+
) => boolean;
|
|
70
|
+
};
|
|
71
|
+
esModule?: boolean;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
type CssStyleSheetExport = Base & {
|
|
76
|
+
exportType?: 'css-style-sheet' | 'string';
|
|
77
|
+
modules?: Partial<Modules> & {
|
|
78
|
+
exportLocalsConvention: 'camelCaseOnly' | 'dashesOnly'
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type ArrayExport = Base & {
|
|
83
|
+
exportType?: 'array';
|
|
84
|
+
modules: Partial<Modules>
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type Config = CssStyleSheetExport | ArrayExport;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AtLeast<T, K extends keyof T> = Partial<T> & Required<Pick<T, K>>;
|