js-build-tools 5.5.0 → 5.7.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/README.md +97 -2
- package/dist/partials/addToReadme.js +28 -17
- package/dist/test-helpers/setUp.js +94 -89
- package/dist/utilities/convertMjsFilesForDocs.js +48 -0
- package/dist/utilities/esmNamedExportsToCjs.js +33 -0
- package/functions/gulpConfigEntries.test.mjs +23 -0
- package/functions/partials/addToReadme.mjs +14 -5
- package/functions/test-helpers/setUp.mjs +5 -0
- package/functions/utilities/convertMjsFilesForDocs.mjs +33 -0
- package/functions/utilities/convertMjsFilesForDocs.test.mjs +57 -0
- package/functions/utilities/esmNamedExportsToCjs.mjs +29 -0
- package/functions/utilities/esmNamedExportsToCjs.test.mjs +47 -0
- package/gulp.config.js +4 -255
- package/gulp.config.mjs +4 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -40,6 +40,8 @@ provided are the defaults):
|
|
|
40
40
|
// Module names or file paths left out of the bundle entirely (requiring one at runtime throws, unless something
|
|
41
41
|
// else provides it, for example a script tag which loads it separately).
|
|
42
42
|
"exclude": [],
|
|
43
|
+
// Additional bundles to produce alongside the primary one above (see 'Configure additional browser bundles').
|
|
44
|
+
"bundles": [],
|
|
43
45
|
// The output directory for browser-bundled files.
|
|
44
46
|
"to": "browser"
|
|
45
47
|
},
|
|
@@ -100,6 +102,9 @@ provided are the defaults):
|
|
|
100
102
|
"from": [
|
|
101
103
|
"src/**/!(*.test).js"
|
|
102
104
|
],
|
|
105
|
+
// Additional .mjs files to document alongside 'from' (see 'Configure including ESM files in the generated
|
|
106
|
+
// readme'). Empty by default: a project that never sets this gets exactly the readme it always did.
|
|
107
|
+
"fromEsm": [],
|
|
103
108
|
// The directory to output the readme file in.
|
|
104
109
|
"to": "./"
|
|
105
110
|
},
|
|
@@ -316,6 +321,56 @@ Two settings in `browser` handle this, both take module names or file paths (see
|
|
|
316
321
|
}
|
|
317
322
|
```
|
|
318
323
|
|
|
324
|
+
### Configure additional browser bundles (optional)
|
|
325
|
+
|
|
326
|
+
By default a project produces exactly one browser bundle, from `dist.main`/`browser.name`/`browser.ignore`/
|
|
327
|
+
`browser.exclude` above. `browser.bundles` adds more bundles alongside it - for example a render-only variant built
|
|
328
|
+
from a different entry point than the full bundle. Each entry only needs to specify what's actually different about
|
|
329
|
+
that bundle; anything left out falls back to the primary bundle's own value:
|
|
330
|
+
|
|
331
|
+
```json
|
|
332
|
+
{
|
|
333
|
+
"browser": {
|
|
334
|
+
"bundles": [
|
|
335
|
+
{
|
|
336
|
+
// Required, and must be unique among all of a project's bundles: the name for this bundle's own output file
|
|
337
|
+
// and standalone export.
|
|
338
|
+
"name": "render-only",
|
|
339
|
+
// This bundle's own entry point. Falls back to dist.main when omitted.
|
|
340
|
+
"main": "dist/renderOnly.js",
|
|
341
|
+
// This bundle's own ignore list. Falls back to browser.ignore when omitted.
|
|
342
|
+
"ignore": [],
|
|
343
|
+
// This bundle's own exclude list. Falls back to browser.exclude when omitted.
|
|
344
|
+
"exclude": []
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
For the `gulpConfig` module's own `get`/`set` functions (read or override a resolved configuration value from your
|
|
352
|
+
own code, by the same dot-notation path a setting has in the JSON above), see the generated reference below.
|
|
353
|
+
|
|
354
|
+
### Configure including ESM files in the generated readme (optional)
|
|
355
|
+
|
|
356
|
+
The readme generator (`jsdoc-to-markdown`) only recognizes `.js` files, even though it parses real ESM `import`/
|
|
357
|
+
`export` syntax just fine once it reads one - the file extension is the only thing it filters on, not the content.
|
|
358
|
+
`readme.fromEsm` names `.mjs` files to document anyway: each one is read, rewritten (every top-level `export const`/
|
|
359
|
+
`export function`/`export class` becomes a plain declaration plus a trailing `module.exports = { ... }` - the same
|
|
360
|
+
shape `jsdoc-to-markdown` already documents cleanly, since that rewrite is exactly what this project's own
|
|
361
|
+
`gulp.config.mjs` needs it for) and written to a temp `.js` file outside your project entirely, which is cleaned up
|
|
362
|
+
again once the readme generator has read it. Other export forms (`export default`, re-exports, `export { a, b }`
|
|
363
|
+
lists) are left untouched in whatever way `jsdoc-to-markdown` already handles ESM - restructure a file to use named
|
|
364
|
+
exports if you want it documented this cleanly:
|
|
365
|
+
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"readme": {
|
|
369
|
+
"fromEsm": ["src/myEsmOnlyModule.mjs"]
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
319
374
|
### Configure move fonts (optional)
|
|
320
375
|
|
|
321
376
|
Be able to copy a source directory of fonts into the distribution path.
|
|
@@ -546,10 +601,12 @@ Modify these configurations to match your project specifications.
|
|
|
546
601
|
* [~StringSetting](#module_gulpConfig..StringSetting) : <code>string</code>
|
|
547
602
|
* [~Setting](#module_gulpConfig..Setting) : <code>ArrayableSetting</code> \| <code>BooleanSetting</code> \| <code>FlagsSetting</code> \| <code>StringSetting</code>
|
|
548
603
|
* [~BrowserConfig](#module_gulpConfig..BrowserConfig) : <code>Object.<string, Setting></code>
|
|
604
|
+
* [~AdditionalBundleConfig](#module_gulpConfig..AdditionalBundleConfig) : <code>Object.<string, Setting></code>
|
|
549
605
|
* [~DistConfig](#module_gulpConfig..DistConfig) : <code>Object.<string, Setting></code>
|
|
550
606
|
* [~FontConfig](#module_gulpConfig..FontConfig) : <code>Object.<string, Setting></code>
|
|
551
607
|
* [~ImageConfig](#module_gulpConfig..ImageConfig) : <code>Object.<string, Setting></code>
|
|
552
608
|
* [~ReadmeConfig](#module_gulpConfig..ReadmeConfig) : <code>Object.<string, Setting></code>
|
|
609
|
+
* [~DocsConfig](#module_gulpConfig..DocsConfig) : <code>Object.<string, Setting></code>
|
|
553
610
|
* [~SassConfig](#module_gulpConfig..SassConfig) : <code>Object.<string, Setting></code>
|
|
554
611
|
* [~TestConfig](#module_gulpConfig..TestConfig) : <code>Object.<string, Setting></code>
|
|
555
612
|
* [~TsConfig](#module_gulpConfig..TsConfig) : <code>Object.<string, Setting></code>
|
|
@@ -646,9 +703,27 @@ Configurations for building the browser files.
|
|
|
646
703
|
| Name | Type | Description |
|
|
647
704
|
| --- | --- | --- |
|
|
648
705
|
| enabled | <code>BooleanSetting</code> | 'true' to generate browser bundled files; 'false' for node environment only |
|
|
649
|
-
| from | <code>StringSetting</code> | The
|
|
650
|
-
| name | <code>StringSetting</code> | The
|
|
706
|
+
| from | <code>StringSetting</code> | The search pattern used for retrieving compiled distribution files. |
|
|
707
|
+
| name | <code>StringSetting</code> | The name to use for the browser-bundled output file (.js will be appended). |
|
|
651
708
|
| to | <code>StringSetting</code> | The output directory for browser-bundled files. |
|
|
709
|
+
| ignore | <code>ArrayableSetting</code> | Module names or file paths which resolve to an empty object ({}) in the bundle instead of their real contents. For a dependency which is only reached because it is the default value of an option you always override (for example a selector engine's default DOM adapter, when you always pass your own), this keeps it (and anything only it requires) out of the bundle, as long as your code never actually reaches the real module by not overriding that option. See browserify's b.ignore(file). |
|
|
710
|
+
| exclude | <code>ArrayableSetting</code> | Module names or file paths left out of the bundle entirely; requiring one at runtime throws unless something else provides it (for example a script tag loading it separately). See browserify's b.exclude(file). |
|
|
711
|
+
| bundles | [<code>Array.<AdditionalBundleConfig></code>](#module_gulpConfig..AdditionalBundleConfig) | Additional bundles to produce alongside the primary one (name/dist.main/ignore/exclude above) - for example a render-only variant built from a different entry point than the full bundle. Empty by default: a project that never sets this gets exactly the one bundle it always did. |
|
|
712
|
+
|
|
713
|
+
<a name="module_gulpConfig..AdditionalBundleConfig"></a>
|
|
714
|
+
|
|
715
|
+
### gulpConfig~AdditionalBundleConfig : <code>Object.<string, Setting></code>
|
|
716
|
+
One additional bundle - everything but `name` falls back to the primary bundle's own value when omitted, so an
|
|
717
|
+
|
|
718
|
+
**Kind**: inner typedef of [<code>gulpConfig</code>](#module_gulpConfig)
|
|
719
|
+
**Properties**
|
|
720
|
+
|
|
721
|
+
| Name | Type | Description |
|
|
722
|
+
| --- | --- | --- |
|
|
723
|
+
| name | <code>StringSetting</code> | The name for this bundle's output file and standalone export - must be unique among all of a project's bundles. |
|
|
724
|
+
| [main] | <code>StringSetting</code> | This bundle's own entry point. Falls back to dist.main when omitted. |
|
|
725
|
+
| [ignore] | <code>ArrayableSetting</code> | This bundle's own ignore list. Falls back to browser.ignore when omitted. |
|
|
726
|
+
| [exclude] | <code>ArrayableSetting</code> | This bundle's own exclude list. Falls back to browser.exclude when omitted. |
|
|
652
727
|
|
|
653
728
|
<a name="module_gulpConfig..DistConfig"></a>
|
|
654
729
|
|
|
@@ -704,10 +779,29 @@ Configurations to compile and generate the Readme file.
|
|
|
704
779
|
| --- | --- | --- |
|
|
705
780
|
| file | <code>StringSetting</code> | The name of the output documentation markdown file. |
|
|
706
781
|
| from | <code>StringSetting</code> | Location of files to use for compiling documentation into the readme. |
|
|
782
|
+
| fromEsm | <code>ArrayableSetting</code> | Additional `.mjs` files to document alongside `from`, converted on the fly since the readme generator only recognizes `.js` files - see 'Configure including ESM files in the generated readme'. Empty by default: a project that never sets this gets exactly the readme it always did. |
|
|
707
783
|
| options | <code>ArrayableSetting</code> | Options for formatting the output readme. |
|
|
708
784
|
| template | <code>StringSetting</code> | The file which will be pre-fixed to your README.md output. |
|
|
709
785
|
| to | <code>StringSetting</code> | The directory to output the readme file in. |
|
|
710
786
|
|
|
787
|
+
<a name="module_gulpConfig..DocsConfig"></a>
|
|
788
|
+
|
|
789
|
+
### gulpConfig~DocsConfig : <code>Object.<string, Setting></code>
|
|
790
|
+
Configurations for generating the HTML documentation of a TypeScript project (with TypeDoc, from the source).
|
|
791
|
+
|
|
792
|
+
**Kind**: inner typedef of [<code>gulpConfig</code>](#module_gulpConfig)
|
|
793
|
+
**Properties**
|
|
794
|
+
|
|
795
|
+
| Name | Type | Description |
|
|
796
|
+
| --- | --- | --- |
|
|
797
|
+
| enabled | <code>BooleanSetting</code> | Toggle generating the documentation from the TypeScript source. When it is on the build does this instead of generating the readme from the jsdoc comments of the compiled files. |
|
|
798
|
+
| from | <code>StringSetting</code> | The directory holding the TypeScript source, each folder in it becomes a module. |
|
|
799
|
+
| index | <code>StringSetting</code> | The markdown file used as the front page of the documentation. |
|
|
800
|
+
| logLevel | <code>StringSetting</code> | How much TypeDoc reports: Verbose, Info, Warn, Error or None. |
|
|
801
|
+
| title | <code>StringSetting</code> | The name of the documentation, defaults to the name in the package.json. |
|
|
802
|
+
| to | <code>StringSetting</code> | The directory to generate the documentation in (it is cleared first). |
|
|
803
|
+
| tsconfig | <code>FlagStringSetting</code> | The tsconfig file to read the source with, defaults to the one of typescript.config. |
|
|
804
|
+
|
|
711
805
|
<a name="module_gulpConfig..SassConfig"></a>
|
|
712
806
|
|
|
713
807
|
### gulpConfig~SassConfig : <code>Object.<string, Setting></code>
|
|
@@ -765,6 +859,7 @@ A set of Configurations options defined by Settings.
|
|
|
765
859
|
| browser | <code>BrowserConfig</code> | Browser bundling configuration group. |
|
|
766
860
|
| cleanPaths | <code>ArrayableSetting</code> | The paths for directories to delete before build. |
|
|
767
861
|
| dist | <code>DistConfig</code> | Distribution file generation configuration group. |
|
|
862
|
+
| docs | <code>DocsConfig</code> | Generate the documentation of a TypeScript project configuration group. |
|
|
768
863
|
| fonts | <code>FontConfig</code> | Fonts copy configuration group. |
|
|
769
864
|
| images | <code>ImageConfig</code> | Minify and copy the images configuration. |
|
|
770
865
|
| readme | <code>ReadmeConfig</code> | Build readme files configuration. |
|
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.addToReadme = void 0;
|
|
8
|
-
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
-
var gulpConfig = _interopRequireWildcard(require("../../gulp.config.js"));
|
|
10
|
-
var _jsdocToMarkdown = _interopRequireDefault(require("jsdoc-to-markdown"));
|
|
11
|
-
var _glob = require("glob");
|
|
12
|
-
|
|
13
|
-
function
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.addToReadme = void 0;
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
var gulpConfig = _interopRequireWildcard(require("../../gulp.config.js"));
|
|
10
|
+
var _jsdocToMarkdown = _interopRequireDefault(require("jsdoc-to-markdown"));
|
|
11
|
+
var _glob = require("glob");
|
|
12
|
+
var _convertMjsFilesForDocs = require("../utilities/convertMjsFilesForDocs.js");
|
|
13
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
15
|
/**
|
|
15
16
|
* Appends all the jsdoc comments to the readme file. Assumes empty or templated file.
|
|
16
17
|
* Configure this with 'readmeSearch', 'readmePath', 'readmeFile', and 'readmeOptions'.
|
|
18
|
+
*
|
|
19
|
+
* jsdoc-to-markdown only recognizes `.js` files, even though it parses real ESM syntax just fine once it reads
|
|
20
|
+
* one - `readme.fromEsm` (empty by default) names `.mjs` files to include anyway, converted on the fly (see
|
|
21
|
+
* {@link convertMjsFilesForDocs}) and cleaned up again once this has read them, win or lose.
|
|
17
22
|
* @memberOf module:partials
|
|
18
23
|
* @returns {string|Uint8Array}
|
|
19
|
-
*/
|
|
20
|
-
const addToReadme = () =>
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
*/
|
|
25
|
+
const addToReadme = () => {
|
|
26
|
+
const {
|
|
27
|
+
filePaths: esmFilePaths,
|
|
28
|
+
cleanUp
|
|
29
|
+
} = (0, _convertMjsFilesForDocs.convertMjsFilesForDocs)((0, _glob.globSync)(gulpConfig.get('readme.fromEsm') || []));
|
|
30
|
+
return _jsdocToMarkdown.default.render({
|
|
31
|
+
files: [...(0, _glob.globSync)(gulpConfig.get('readme.from')), ...esmFilePaths]
|
|
32
|
+
}).finally(cleanUp).then(readme => _fs.default.appendFileSync(gulpConfig.get('readme.to') + gulpConfig.get('readme.file'), readme, gulpConfig.get('readmeOptions')));
|
|
33
|
+
};
|
|
23
34
|
exports.addToReadme = addToReadme;
|
|
@@ -1,94 +1,99 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
Object.defineProperty(exports, "afterEach", {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
get: function () {
|
|
10
|
-
return _testFilesystem.afterEach;
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
Object.defineProperty(exports, "beforeEach", {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () {
|
|
16
|
-
return _testFilesystem.beforeEach;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
Object.defineProperty(exports, "countMatches", {
|
|
20
|
-
enumerable: true,
|
|
21
|
-
get: function () {
|
|
22
|
-
return _testFilesystem.countMatches;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
Object.defineProperty(exports, "createTempDir", {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () {
|
|
28
|
-
return _testFilesystem.createTempDir;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(exports, "fileExists", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
get: function () {
|
|
34
|
-
return _testFilesystem.fileExists;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
exports.gulpConfig = void 0;
|
|
38
|
-
Object.defineProperty(exports, "logObject", {
|
|
39
|
-
enumerable: true,
|
|
40
|
-
get: function () {
|
|
41
|
-
return _testFilesystem.logObject;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
Object.defineProperty(exports, "removeDirectory", {
|
|
45
|
-
enumerable: true,
|
|
46
|
-
get: function () {
|
|
47
|
-
return _testFilesystem.removeDirectory;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
exports.setDefaults = void 0;
|
|
51
|
-
var gulpConfig = _interopRequireWildcard(require("../../gulp.config.js"));
|
|
52
|
-
exports.gulpConfig = gulpConfig;
|
|
53
|
-
var _testFilesystem = require("test-filesystem");
|
|
54
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
55
|
-
// Import the configurations and override some of them to direct to the temp directory.
|
|
56
|
-
|
|
57
|
-
let tempDir = 'test-temp/';
|
|
58
|
-
let srcPath = `${tempDir}src`;
|
|
59
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
Object.defineProperty(exports, "afterEach", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _testFilesystem.afterEach;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "beforeEach", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _testFilesystem.beforeEach;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "countMatches", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _testFilesystem.countMatches;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "createTempDir", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return _testFilesystem.createTempDir;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "fileExists", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return _testFilesystem.fileExists;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
exports.gulpConfig = void 0;
|
|
38
|
+
Object.defineProperty(exports, "logObject", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function () {
|
|
41
|
+
return _testFilesystem.logObject;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(exports, "removeDirectory", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function () {
|
|
47
|
+
return _testFilesystem.removeDirectory;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
exports.setDefaults = void 0;
|
|
51
|
+
var gulpConfig = _interopRequireWildcard(require("../../gulp.config.js"));
|
|
52
|
+
exports.gulpConfig = gulpConfig;
|
|
53
|
+
var _testFilesystem = require("test-filesystem");
|
|
54
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
55
|
+
// Import the configurations and override some of them to direct to the temp directory.
|
|
56
|
+
|
|
57
|
+
let tempDir = 'test-temp/';
|
|
58
|
+
let srcPath = `${tempDir}src`;
|
|
59
|
+
|
|
60
60
|
/**
|
|
61
61
|
* Update the gulp configurations with the test data. Set the test directory where temp files will be created for testing.
|
|
62
62
|
* @memberOf module:testHelpers
|
|
63
63
|
* @param {string} testDir
|
|
64
|
-
*/
|
|
65
|
-
const setDefaults = (testDir = 'test-temp') => {
|
|
66
|
-
tempDir = `${testDir}/`;
|
|
67
|
-
srcPath = `${tempDir}src`;
|
|
68
|
-
_testFilesystem.setUp.setDefaults(tempDir);
|
|
69
|
-
const distPath = `${tempDir}dist`;
|
|
70
|
-
const browserPath = `${tempDir}browser`;
|
|
71
|
-
const sassPath = `${tempDir}sass`;
|
|
72
|
-
gulpConfig.set('browser.from', `${distPath}/**/*.js`);
|
|
73
|
-
gulpConfig.set('browser.to', browserPath);
|
|
74
|
-
gulpConfig.set('cleanPaths', [distPath, browserPath]);
|
|
75
|
-
gulpConfig.set('dist.from', `${srcPath}/**/!(*.test).js`);
|
|
76
|
-
gulpConfig.set('dist.main', `${distPath}/main`);
|
|
77
|
-
gulpConfig.set('dist.to', distPath);
|
|
78
|
-
gulpConfig.set('fonts.from', `${srcPath}/fonts/**/*`);
|
|
79
|
-
gulpConfig.set('fonts.to', `${browserPath}/fonts`);
|
|
80
|
-
gulpConfig.set('images.from', `${srcPath}/img/**/*.+(png|jpg|jpeg|gif|svg)`);
|
|
81
|
-
gulpConfig.set('images.to', `${browserPath}/img`);
|
|
82
|
-
gulpConfig.set('readme.template', `${tempDir}MAIN.md`);
|
|
83
|
-
gulpConfig.set('readme.to', tempDir);
|
|
84
|
-
gulpConfig.set('readme.from', `${srcPath}/**/!(*.test).js`);
|
|
85
|
-
gulpConfig
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
gulpConfig.set('
|
|
90
|
-
gulpConfig.set('
|
|
91
|
-
gulpConfig.set('
|
|
92
|
-
gulpConfig.set('
|
|
93
|
-
};
|
|
64
|
+
*/
|
|
65
|
+
const setDefaults = (testDir = 'test-temp') => {
|
|
66
|
+
tempDir = `${testDir}/`;
|
|
67
|
+
srcPath = `${tempDir}src`;
|
|
68
|
+
_testFilesystem.setUp.setDefaults(tempDir);
|
|
69
|
+
const distPath = `${tempDir}dist`;
|
|
70
|
+
const browserPath = `${tempDir}browser`;
|
|
71
|
+
const sassPath = `${tempDir}sass`;
|
|
72
|
+
gulpConfig.set('browser.from', `${distPath}/**/*.js`);
|
|
73
|
+
gulpConfig.set('browser.to', browserPath);
|
|
74
|
+
gulpConfig.set('cleanPaths', [distPath, browserPath]);
|
|
75
|
+
gulpConfig.set('dist.from', `${srcPath}/**/!(*.test).js`);
|
|
76
|
+
gulpConfig.set('dist.main', `${distPath}/main`);
|
|
77
|
+
gulpConfig.set('dist.to', distPath);
|
|
78
|
+
gulpConfig.set('fonts.from', `${srcPath}/fonts/**/*`);
|
|
79
|
+
gulpConfig.set('fonts.to', `${browserPath}/fonts`);
|
|
80
|
+
gulpConfig.set('images.from', `${srcPath}/img/**/*.+(png|jpg|jpeg|gif|svg)`);
|
|
81
|
+
gulpConfig.set('images.to', `${browserPath}/img`);
|
|
82
|
+
gulpConfig.set('readme.template', `${tempDir}MAIN.md`);
|
|
83
|
+
gulpConfig.set('readme.to', tempDir);
|
|
84
|
+
gulpConfig.set('readme.from', `${srcPath}/**/!(*.test).js`);
|
|
85
|
+
// Reset explicitly: gulpConfig is a process-wide singleton seeded once from this real project's own
|
|
86
|
+
// build-tools.config.json, so without this, this project's own real readme.fromEsm value (gulp.config.mjs)
|
|
87
|
+
// would leak into every test that exercises addToReadme/compileReadme but never sets this path itself -
|
|
88
|
+
// doing real file I/O and a real jsdoc-to-markdown parse of this project's own, much larger, config file.
|
|
89
|
+
gulpConfig.set('readme.fromEsm', []);
|
|
90
|
+
gulpConfig.set('rootPath', tempDir);
|
|
91
|
+
gulpConfig.set('sass.from', `${sassPath}/**/*.+(scss|sass)`);
|
|
92
|
+
gulpConfig.set('sass.path', sassPath);
|
|
93
|
+
gulpConfig.set('sass.to', `${browserPath}/css`);
|
|
94
|
+
gulpConfig.set('srcPath', srcPath);
|
|
95
|
+
gulpConfig.set('typescript.from', `${srcPath}/**/*.ts`);
|
|
96
|
+
gulpConfig.set('typescript.to', distPath);
|
|
97
|
+
gulpConfig.set('test.watch', `${srcPath}/**/*.js`);
|
|
98
|
+
};
|
|
94
99
|
exports.setDefaults = setDefaults;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.convertMjsFilesForDocs = void 0;
|
|
7
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
9
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
10
|
+
var _os = _interopRequireDefault(require("os"));
|
|
11
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
|
+
var _esmNamedExportsToCjs = require("./esmNamedExportsToCjs.js");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
/**
|
|
15
|
+
* Writes a rewritten (see {@link esmNamedExportsToCjs}) copy of each given `.mjs` file into a fresh, unique
|
|
16
|
+
* directory under the OS temp directory, with a `.js` extension - jsdoc-to-markdown only recognizes `.js` as a
|
|
17
|
+
* documentable file, regardless of whether its contents are actually CommonJS or ESM (it parses the real ESM
|
|
18
|
+
* syntax of the rest of a file fine; the extension is the only thing it filters on). Writing outside the project
|
|
19
|
+
* tree means there is nothing to gitignore and nothing left behind in the project - call the returned `cleanUp`
|
|
20
|
+
* once done (for example, right after jsdoc-to-markdown has read the files) to remove the temp directory.
|
|
21
|
+
* @memberOf module:utilities
|
|
22
|
+
* @param {Array<string>} mjsFilePaths - Real `.mjs` files to convert. An empty array is a safe, cheap no-op.
|
|
23
|
+
* @returns {{filePaths: Array<string>, cleanUp: function(): void}} The temp `.js` file paths to pass to
|
|
24
|
+
* jsdoc-to-markdown instead of the real `.mjs` ones, and a function to remove the temp directory afterward.
|
|
25
|
+
*/
|
|
26
|
+
const convertMjsFilesForDocs = (mjsFilePaths = []) => {
|
|
27
|
+
if (mjsFilePaths.length === 0) {
|
|
28
|
+
return {
|
|
29
|
+
filePaths: [],
|
|
30
|
+
cleanUp: () => {}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const tempDir = _fs.default.mkdtempSync(_path.default.join(_os.default.tmpdir(), 'js-build-tools-docs-'));
|
|
34
|
+
const filePaths = mjsFilePaths.map(mjsFilePath => {
|
|
35
|
+
const tempFilePath = _path.default.join(tempDir, _path.default.basename(mjsFilePath, '.js') + '.js');
|
|
36
|
+
const source = _fs.default.readFileSync(mjsFilePath, 'utf8');
|
|
37
|
+
_fs.default.writeFileSync(tempFilePath, (0, _esmNamedExportsToCjs.esmNamedExportsToCjs)(source));
|
|
38
|
+
return tempFilePath;
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
filePaths,
|
|
42
|
+
cleanUp: () => _fs.default.rmSync(tempDir, {
|
|
43
|
+
recursive: true,
|
|
44
|
+
force: true
|
|
45
|
+
})
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
exports.convertMjsFilesForDocs = convertMjsFilesForDocs;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.esmNamedExportsToCjs = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Rewrites named `export const`/`export function`/`export class` declarations to plain declarations plus a
|
|
9
|
+
* trailing `module.exports = { ... }` - the same shape jsdoc-to-markdown already documents cleanly (a plain
|
|
10
|
+
* declaration with its own `@memberOf` tag, exported all at once at the bottom), rather than the "exports.name"
|
|
11
|
+
* longname jsdoc-to-markdown's own ESM-compat layer produces for an inline `export const name = ...`.
|
|
12
|
+
*
|
|
13
|
+
* This is a narrow, text-level rewrite for documentation purposes only - it does not execute the module, so it
|
|
14
|
+
* only has to look enough like the real thing for jsdoc-to-markdown's parser. It handles the common named-export
|
|
15
|
+
* forms (`export const`, `export function`, `export class`) and leaves everything else (including `export
|
|
16
|
+
* default`, re-exports, and `export { a, b }` lists) untouched in place - a file using one of those keeps its
|
|
17
|
+
* own export line as-is, which jsdoc-to-markdown will document however it already does for ESM.
|
|
18
|
+
* @memberOf module:utilities
|
|
19
|
+
* @param {string} source - The raw ESM source text (never executed, just rewritten as text).
|
|
20
|
+
* @returns {string} The rewritten text, safe to write out with a `.js` extension for jsdoc-to-markdown to read.
|
|
21
|
+
*/
|
|
22
|
+
const esmNamedExportsToCjs = source => {
|
|
23
|
+
const exportedNames = [];
|
|
24
|
+
const rewritten = source.replace(/^export (const|function|class) (\w+)/gm, (match, keyword, name) => {
|
|
25
|
+
exportedNames.push(name);
|
|
26
|
+
return `${keyword} ${name}`;
|
|
27
|
+
});
|
|
28
|
+
if (exportedNames.length === 0) {
|
|
29
|
+
return rewritten;
|
|
30
|
+
}
|
|
31
|
+
return `${rewritten}\n\nmodule.exports = { ${exportedNames.join(', ')} }\n`;
|
|
32
|
+
};
|
|
33
|
+
exports.esmNamedExportsToCjs = esmNamedExportsToCjs;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import * as esmConfig from '../gulp.config.mjs'
|
|
4
|
+
|
|
5
|
+
const root = path.resolve(__dirname, '..')
|
|
6
|
+
const readFromCjs = (dotPath) => JSON.parse(execFileSync(process.execPath, [
|
|
7
|
+
'-e',
|
|
8
|
+
`console.log(JSON.stringify(require('./gulp.config.js').get(${JSON.stringify(dotPath)})))`
|
|
9
|
+
], { cwd: root }).toString())
|
|
10
|
+
|
|
11
|
+
describe('gulp.config entries', () => {
|
|
12
|
+
test('the CommonJS entry exposes the same configuration as the ESM source', () => {
|
|
13
|
+
for (const dotPath of ['docs', 'browser', 'dist', 'typescript']) {
|
|
14
|
+
expect(readFromCjs(dotPath)).toEqual(JSON.parse(JSON.stringify(esmConfig.get(dotPath))))
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('the CommonJS entry carries browser.bundles and browser.ignore/exclude', () => {
|
|
19
|
+
for (const dotPath of ['browser.bundles', 'browser.ignore', 'browser.exclude']) {
|
|
20
|
+
expect(readFromCjs(dotPath)).toEqual(JSON.parse(JSON.stringify(esmConfig.get(dotPath))))
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
})
|
|
@@ -2,15 +2,24 @@ import fs from 'fs'
|
|
|
2
2
|
import * as gulpConfig from '../../gulp.config.mjs'
|
|
3
3
|
import jsdoc2md from 'jsdoc-to-markdown'
|
|
4
4
|
import { globSync } from 'glob'
|
|
5
|
+
import { convertMjsFilesForDocs } from '../utilities/convertMjsFilesForDocs.mjs'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Appends all the jsdoc comments to the readme file. Assumes empty or templated file.
|
|
8
9
|
* Configure this with 'readmeSearch', 'readmePath', 'readmeFile', and 'readmeOptions'.
|
|
10
|
+
*
|
|
11
|
+
* jsdoc-to-markdown only recognizes `.js` files, even though it parses real ESM syntax just fine once it reads
|
|
12
|
+
* one - `readme.fromEsm` (empty by default) names `.mjs` files to include anyway, converted on the fly (see
|
|
13
|
+
* {@link convertMjsFilesForDocs}) and cleaned up again once this has read them, win or lose.
|
|
9
14
|
* @memberOf module:partials
|
|
10
15
|
* @returns {string|Uint8Array}
|
|
11
16
|
*/
|
|
12
|
-
export const addToReadme = () =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
export const addToReadme = () => {
|
|
18
|
+
const { filePaths: esmFilePaths, cleanUp } = convertMjsFilesForDocs(globSync(gulpConfig.get('readme.fromEsm') || []))
|
|
19
|
+
return jsdoc2md
|
|
20
|
+
.render({ files: [...globSync(gulpConfig.get('readme.from')), ...esmFilePaths] })
|
|
21
|
+
.finally(cleanUp)
|
|
22
|
+
.then(
|
|
23
|
+
readme => fs.appendFileSync(gulpConfig.get('readme.to') + gulpConfig.get('readme.file'), readme, gulpConfig.get('readmeOptions'))
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -30,6 +30,11 @@ export const setDefaults = (testDir = 'test-temp') => {
|
|
|
30
30
|
gulpConfig.set('readme.template', `${tempDir}MAIN.md`)
|
|
31
31
|
gulpConfig.set('readme.to', tempDir)
|
|
32
32
|
gulpConfig.set('readme.from', `${srcPath}/**/!(*.test).js`)
|
|
33
|
+
// Reset explicitly: gulpConfig is a process-wide singleton seeded once from this real project's own
|
|
34
|
+
// build-tools.config.json, so without this, this project's own real readme.fromEsm value (gulp.config.mjs)
|
|
35
|
+
// would leak into every test that exercises addToReadme/compileReadme but never sets this path itself -
|
|
36
|
+
// doing real file I/O and a real jsdoc-to-markdown parse of this project's own, much larger, config file.
|
|
37
|
+
gulpConfig.set('readme.fromEsm', [])
|
|
33
38
|
gulpConfig.set('rootPath', tempDir)
|
|
34
39
|
gulpConfig.set('sass.from', `${sassPath}/**/*.+(scss|sass)`)
|
|
35
40
|
gulpConfig.set('sass.path', sassPath)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import os from 'os'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { esmNamedExportsToCjs } from './esmNamedExportsToCjs.mjs'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Writes a rewritten (see {@link esmNamedExportsToCjs}) copy of each given `.mjs` file into a fresh, unique
|
|
8
|
+
* directory under the OS temp directory, with a `.js` extension - jsdoc-to-markdown only recognizes `.js` as a
|
|
9
|
+
* documentable file, regardless of whether its contents are actually CommonJS or ESM (it parses the real ESM
|
|
10
|
+
* syntax of the rest of a file fine; the extension is the only thing it filters on). Writing outside the project
|
|
11
|
+
* tree means there is nothing to gitignore and nothing left behind in the project - call the returned `cleanUp`
|
|
12
|
+
* once done (for example, right after jsdoc-to-markdown has read the files) to remove the temp directory.
|
|
13
|
+
* @memberOf module:utilities
|
|
14
|
+
* @param {Array<string>} mjsFilePaths - Real `.mjs` files to convert. An empty array is a safe, cheap no-op.
|
|
15
|
+
* @returns {{filePaths: Array<string>, cleanUp: function(): void}} The temp `.js` file paths to pass to
|
|
16
|
+
* jsdoc-to-markdown instead of the real `.mjs` ones, and a function to remove the temp directory afterward.
|
|
17
|
+
*/
|
|
18
|
+
export const convertMjsFilesForDocs = (mjsFilePaths = []) => {
|
|
19
|
+
if (mjsFilePaths.length === 0) {
|
|
20
|
+
return { filePaths: [], cleanUp: () => {} }
|
|
21
|
+
}
|
|
22
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'js-build-tools-docs-'))
|
|
23
|
+
const filePaths = mjsFilePaths.map((mjsFilePath) => {
|
|
24
|
+
const tempFilePath = path.join(tempDir, path.basename(mjsFilePath, '.mjs') + '.js')
|
|
25
|
+
const source = fs.readFileSync(mjsFilePath, 'utf8')
|
|
26
|
+
fs.writeFileSync(tempFilePath, esmNamedExportsToCjs(source))
|
|
27
|
+
return tempFilePath
|
|
28
|
+
})
|
|
29
|
+
return {
|
|
30
|
+
filePaths,
|
|
31
|
+
cleanUp: () => fs.rmSync(tempDir, { recursive: true, force: true })
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import * as setUp from '../test-helpers/setUp.mjs'
|
|
3
|
+
import { convertMjsFilesForDocs } from './convertMjsFilesForDocs.mjs'
|
|
4
|
+
|
|
5
|
+
setUp.setDefaults('test-temp-convert-mjs-for-docs')
|
|
6
|
+
const gulpConfig = setUp.gulpConfig
|
|
7
|
+
|
|
8
|
+
const rawContents = '/**\n' +
|
|
9
|
+
' * Say hello with a given name.\n' +
|
|
10
|
+
' * @memberOf module:greet\n' +
|
|
11
|
+
' * @param {string} name\n' +
|
|
12
|
+
' * @returns {string}\n' +
|
|
13
|
+
' */\n' +
|
|
14
|
+
'export const sayHello = name => `Hello from ${name}`\n'
|
|
15
|
+
|
|
16
|
+
beforeEach(() => setUp.beforeEach()
|
|
17
|
+
.then(() => fs.writeFileSync(gulpConfig.get('srcPath') + '/greet.mjs', rawContents)))
|
|
18
|
+
|
|
19
|
+
afterEach(setUp.afterEach)
|
|
20
|
+
|
|
21
|
+
describe('convertMjsFilesForDocs', () => {
|
|
22
|
+
test('returns an empty result, with a safe no-op cleanUp, for an empty list', () => {
|
|
23
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([])
|
|
24
|
+
expect(filePaths).toEqual([])
|
|
25
|
+
expect(() => cleanUp()).not.toThrow()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('writes a rewritten, doc-parseable .js copy outside the project tree', () => {
|
|
29
|
+
const mjsFilePath = gulpConfig.get('srcPath') + '/greet.mjs'
|
|
30
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([mjsFilePath])
|
|
31
|
+
|
|
32
|
+
expect(filePaths).toHaveLength(1)
|
|
33
|
+
expect(filePaths[0]).toMatch(/greet\.js$/)
|
|
34
|
+
expect(filePaths[0]).not.toContain(process.cwd())
|
|
35
|
+
|
|
36
|
+
const converted = fs.readFileSync(filePaths[0], 'utf8')
|
|
37
|
+
expect(converted).toContain('const sayHello = name => `Hello from ${name}`')
|
|
38
|
+
expect(converted).toContain('module.exports = { sayHello }')
|
|
39
|
+
|
|
40
|
+
cleanUp()
|
|
41
|
+
expect(fs.existsSync(filePaths[0])).toBe(false)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('converts several files into the same temp directory', () => {
|
|
45
|
+
fs.writeFileSync(gulpConfig.get('srcPath') + '/greetAgain.mjs', rawContents.replace('sayHello', 'sayHelloAgain'))
|
|
46
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([
|
|
47
|
+
gulpConfig.get('srcPath') + '/greet.mjs',
|
|
48
|
+
gulpConfig.get('srcPath') + '/greetAgain.mjs'
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
expect(filePaths).toHaveLength(2)
|
|
52
|
+
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(true))
|
|
53
|
+
|
|
54
|
+
cleanUp()
|
|
55
|
+
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(false))
|
|
56
|
+
})
|
|
57
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites named `export const`/`export function`/`export class` declarations to plain declarations plus a
|
|
3
|
+
* trailing `module.exports = { ... }` - the same shape jsdoc-to-markdown already documents cleanly (a plain
|
|
4
|
+
* declaration with its own `@memberOf` tag, exported all at once at the bottom), rather than the "exports.name"
|
|
5
|
+
* longname jsdoc-to-markdown's own ESM-compat layer produces for an inline `export const name = ...`.
|
|
6
|
+
*
|
|
7
|
+
* This is a narrow, text-level rewrite for documentation purposes only - it does not execute the module, so it
|
|
8
|
+
* only has to look enough like the real thing for jsdoc-to-markdown's parser. It handles the common named-export
|
|
9
|
+
* forms (`export const`, `export function`, `export class`) and leaves everything else (including `export
|
|
10
|
+
* default`, re-exports, and `export { a, b }` lists) untouched in place - a file using one of those keeps its
|
|
11
|
+
* own export line as-is, which jsdoc-to-markdown will document however it already does for ESM.
|
|
12
|
+
* @memberOf module:utilities
|
|
13
|
+
* @param {string} source - The raw ESM source text (never executed, just rewritten as text).
|
|
14
|
+
* @returns {string} The rewritten text, safe to write out with a `.js` extension for jsdoc-to-markdown to read.
|
|
15
|
+
*/
|
|
16
|
+
export const esmNamedExportsToCjs = (source) => {
|
|
17
|
+
const exportedNames = []
|
|
18
|
+
const rewritten = source.replace(
|
|
19
|
+
/^export (const|function|class) (\w+)/gm,
|
|
20
|
+
(match, keyword, name) => {
|
|
21
|
+
exportedNames.push(name)
|
|
22
|
+
return `${keyword} ${name}`
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
if (exportedNames.length === 0) {
|
|
26
|
+
return rewritten
|
|
27
|
+
}
|
|
28
|
+
return `${rewritten}\n\nmodule.exports = { ${exportedNames.join(', ')} }\n`
|
|
29
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { esmNamedExportsToCjs } from './esmNamedExportsToCjs.mjs'
|
|
2
|
+
|
|
3
|
+
describe('esmNamedExportsToCjs', () => {
|
|
4
|
+
test('rewrites a single export const to a plain declaration plus a trailing module.exports', () => {
|
|
5
|
+
const source = 'export const get = (path) => path\n'
|
|
6
|
+
const result = esmNamedExportsToCjs(source)
|
|
7
|
+
expect(result).toContain('const get = (path) => path')
|
|
8
|
+
expect(result).toContain('module.exports = { get }')
|
|
9
|
+
expect(result).not.toContain('export const')
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('rewrites multiple export const declarations into one module.exports with all the names', () => {
|
|
13
|
+
const source = 'export const get = () => {}\nexport const set = () => {}\n'
|
|
14
|
+
const result = esmNamedExportsToCjs(source)
|
|
15
|
+
expect(result).toContain('const get = () => {}')
|
|
16
|
+
expect(result).toContain('const set = () => {}')
|
|
17
|
+
expect(result).toContain('module.exports = { get, set }')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('rewrites export function and export class the same way', () => {
|
|
21
|
+
const source = 'export function doThing() {}\nexport class Thing {}\n'
|
|
22
|
+
const result = esmNamedExportsToCjs(source)
|
|
23
|
+
expect(result).toContain('function doThing() {}')
|
|
24
|
+
expect(result).toContain('class Thing {}')
|
|
25
|
+
expect(result).toContain('module.exports = { doThing, Thing }')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('leaves non-export lines and JSDoc comments untouched', () => {
|
|
29
|
+
const source = '/**\n * A function.\n * @memberOf module:gulpConfig\n */\nexport const get = () => {}\n'
|
|
30
|
+
const result = esmNamedExportsToCjs(source)
|
|
31
|
+
expect(result).toContain('/**\n * A function.\n * @memberOf module:gulpConfig\n */\nconst get = () => {}')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('does not add a module.exports block when there is nothing to export', () => {
|
|
35
|
+
const source = 'import { thing } from \'./thing.mjs\'\nconst local = 1\n'
|
|
36
|
+
const result = esmNamedExportsToCjs(source)
|
|
37
|
+
expect(result).toBe(source)
|
|
38
|
+
expect(result).not.toContain('module.exports')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('leaves export default and other export forms untouched', () => {
|
|
42
|
+
const source = 'const value = 1\nexport default value\n'
|
|
43
|
+
const result = esmNamedExportsToCjs(source)
|
|
44
|
+
expect(result).toContain('export default value')
|
|
45
|
+
expect(result).not.toContain('module.exports')
|
|
46
|
+
})
|
|
47
|
+
})
|
package/gulp.config.js
CHANGED
|
@@ -1,255 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @version 3.0.0
|
|
6
|
-
* @module gulpConfig
|
|
7
|
-
* @memberOf module:js-build-tools
|
|
8
|
-
*/
|
|
9
|
-
const { fileExists } = require('test-filesystem')
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A setting that may be an array of strings or a string only.
|
|
13
|
-
* @typedef {Array<string>|string} module:gulpConfig~ArrayableSetting
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A setting that may be true or false.
|
|
18
|
-
* @typedef {boolean} module:gulpConfig~BooleanSetting
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* A setting that may be flag 'false' or provide a StringSetting
|
|
23
|
-
* @typedef {false|StringSetting} module:gulpConfig~FlagStringSetting
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* An object of boolean settings used as flags.
|
|
28
|
-
* @typedef {Object<string, BooleanSetting>} module:gulpConfig~FlagsSetting
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Configure cli options for running Jest.
|
|
33
|
-
* @typedef {FlagsSetting} module:gulpConfig~JestTestFlags
|
|
34
|
-
* @property {BooleanSetting} clearCache
|
|
35
|
-
* @property {BooleanSetting} debug
|
|
36
|
-
* @property {BooleanSetting} ignoreProjects:
|
|
37
|
-
* @property {BooleanSetting} json
|
|
38
|
-
* @property {BooleanSetting} selectProjects
|
|
39
|
-
* @property {BooleanSetting} showConfig
|
|
40
|
-
* @property {BooleanSetting} useStderr
|
|
41
|
-
* @property {BooleanSetting} watch
|
|
42
|
-
* @property {BooleanSetting} watchAll
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* A setting that may only be a string.
|
|
47
|
-
* @typedef {string} module:gulpConfig~StringSetting
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Any single configuration option is a Setting.
|
|
52
|
-
* @typedef {ArrayableSetting|BooleanSetting|FlagsSetting|StringSetting} Setting
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Configurations for building the browser files.
|
|
57
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~BrowserConfig
|
|
58
|
-
* @property {BooleanSetting} enabled - 'true' to generate browser bundled files; 'false' for node environment only
|
|
59
|
-
* @property {StringSetting} from - The name to use for the browser-bundled output file (.js will be appended).
|
|
60
|
-
* @property {StringSetting} name - The search pattern used for retrieving compiled distribution files.
|
|
61
|
-
* @property {StringSetting} to - The output directory for browser-bundled files.
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Configurations for building the node distribution files.
|
|
66
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~DistConfig
|
|
67
|
-
* @property {StringSetting} from - The search pattern used for gathering source files for distribution.
|
|
68
|
-
* @property {StringSetting} main - Name of the entry the distribution file.
|
|
69
|
-
* @property {StringSetting} to - The output directory for the distribution files.
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Configurations for copying the font files.
|
|
74
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~FontConfig
|
|
75
|
-
* @property {BooleanSetting} enabled - Toggle copy directory of fonts on.
|
|
76
|
-
* @property {StringSetting} from - Path to search for fonts.
|
|
77
|
-
* @property {StringSetting} to - Path to output fonts.
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Configurations to minify and copy the images.
|
|
82
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~ImageConfig
|
|
83
|
-
* @property {BooleanSetting} enabled - Toggle image minify and copy process.
|
|
84
|
-
* @property {StringSetting} from - Path to search for images.
|
|
85
|
-
* @property {StringSetting} to - Path to output images.
|
|
86
|
-
*/
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Configurations to compile and generate the Readme file.
|
|
90
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~ReadmeConfig
|
|
91
|
-
* @property {StringSetting} file - The name of the output documentation markdown file.
|
|
92
|
-
* @property {StringSetting} from - Location of files to use for compiling documentation into the readme.
|
|
93
|
-
* @property {ArrayableSetting} options - Options for formatting the output readme.
|
|
94
|
-
* @property {StringSetting} template - The file which will be pre-fixed to your README.md output.
|
|
95
|
-
* @property {StringSetting} to - The directory to output the readme file in.
|
|
96
|
-
*/
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Configurations to compile and copy the sass files into css.
|
|
100
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~SassConfig
|
|
101
|
-
* @property {BooleanSetting} enabled - Toggle SASS to CSS process on.
|
|
102
|
-
* @property {StringSetting} from - The pattern for finding all sass files.
|
|
103
|
-
* @property {StringSetting} path - The directory were sass files will be stored.
|
|
104
|
-
* @property {StringSetting} to - The destination path for where generated CSS (from SASS files) should go.
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Configurations for running the test suite.
|
|
109
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~TestConfig
|
|
110
|
-
* @property {JestTestFlags} options - Additional flags for programmatically running Jest Cli.
|
|
111
|
-
* @property {ArrayableSetting} path - The directory where Jest test files are stored.
|
|
112
|
-
* By default, stored as *.test.js adjacent to the files they are testing.
|
|
113
|
-
* @property {ArrayableSetting} watch - The search pattern for watching files for changes.
|
|
114
|
-
*/
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Configurations for compiling typescript into JS files.
|
|
118
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~TsConfig
|
|
119
|
-
* @property {FlagStringSetting} config - The path the tsconfig file for running typescript or false if no ts file given.
|
|
120
|
-
* @property {BooleanSetting} enabled - Toggle usage of typescript parsing.
|
|
121
|
-
* @property {StringSetting} from - Pattern for finding the TypeScript files.
|
|
122
|
-
* @property {StringSetting} to - Directory where parsed typescript files go.
|
|
123
|
-
*/
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* A set of Configurations options defined by Settings.
|
|
127
|
-
* @typedef {Object<string, Setting>} module:gulpConfig~Configurations
|
|
128
|
-
* @property {BrowserConfig} browser - Browser bundling configuration group.
|
|
129
|
-
* @property {ArrayableSetting} cleanPaths - The paths for directories to delete before build.
|
|
130
|
-
* @property {DistConfig} dist - Distribution file generation configuration group.
|
|
131
|
-
* @property {FontConfig} fonts - Fonts copy configuration group.
|
|
132
|
-
* @property {ImageConfig} images - Minify and copy the images configuration.
|
|
133
|
-
* @property {ReadmeConfig} readme - Build readme files configuration.
|
|
134
|
-
* @property {StringSetting} rootPath - Base directory of the project.
|
|
135
|
-
* @property {SassConfig} sass - Compile CSS from SASS configuration.
|
|
136
|
-
* @property {StringSetting} srcPath - The directory where your source files are stored (the files you manually created).
|
|
137
|
-
* @property {TestConfig} test - Run test suite configuration.
|
|
138
|
-
* @property {TsConfig} typescript - Compile from typescript configuration.
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
const { dotGet } = require('./dist/utilities/dotGet')
|
|
142
|
-
const { dotSet } = require('./dist/utilities/dotSet')
|
|
143
|
-
const { dotNotate } = require('./dist/utilities/dotNotate')
|
|
144
|
-
const { readFileSync } = require('fs')
|
|
145
|
-
|
|
146
|
-
const setDefaults = {
|
|
147
|
-
browser: {
|
|
148
|
-
enabled: true,
|
|
149
|
-
from: 'dist/**/*.js',
|
|
150
|
-
name: 'default',
|
|
151
|
-
to: 'browser',
|
|
152
|
-
},
|
|
153
|
-
cleanPaths: ['dist', 'browser'],
|
|
154
|
-
dist: {
|
|
155
|
-
from: 'src/**/!(*.test).js',
|
|
156
|
-
main: 'dist/main',
|
|
157
|
-
to: 'dist',
|
|
158
|
-
},
|
|
159
|
-
fonts: {
|
|
160
|
-
enabled: false,
|
|
161
|
-
from: 'src/fonts/**/*',
|
|
162
|
-
to: 'browser/fonts',
|
|
163
|
-
},
|
|
164
|
-
images: {
|
|
165
|
-
enabled: false,
|
|
166
|
-
from: 'src/img/**/*.+(png|jpg|jpeg|gif|svg)',
|
|
167
|
-
to: 'browser/img',
|
|
168
|
-
},
|
|
169
|
-
readme: {
|
|
170
|
-
file: 'README.md',
|
|
171
|
-
from: 'src/**/!(*.test).js',
|
|
172
|
-
options: 'utf8',
|
|
173
|
-
template: 'MAIN.md',
|
|
174
|
-
to: './'
|
|
175
|
-
},
|
|
176
|
-
rootPath: './',
|
|
177
|
-
sass: {
|
|
178
|
-
enabled: false,
|
|
179
|
-
from: 'sass/**/*.+(scss|sass)',
|
|
180
|
-
path: 'sass',
|
|
181
|
-
to: 'browser/css',
|
|
182
|
-
},
|
|
183
|
-
srcPath: 'src',
|
|
184
|
-
test: {
|
|
185
|
-
options: {
|
|
186
|
-
clearCache: false,
|
|
187
|
-
debug: false,
|
|
188
|
-
ignoreProjects: false,
|
|
189
|
-
json: false,
|
|
190
|
-
selectProjects: false,
|
|
191
|
-
showConfig: false,
|
|
192
|
-
useStderr: false,
|
|
193
|
-
watch: false,
|
|
194
|
-
watchAll: false,
|
|
195
|
-
},
|
|
196
|
-
path: ['src'],
|
|
197
|
-
watch: 'src/**/*.js'
|
|
198
|
-
},
|
|
199
|
-
typescript: {
|
|
200
|
-
config: false,
|
|
201
|
-
enabled: false,
|
|
202
|
-
from: 'src/**/*.ts',
|
|
203
|
-
to: 'dist',
|
|
204
|
-
},
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* All the available configuration setting options for running the build.
|
|
208
|
-
* @memberOf module:gulpConfig` `
|
|
209
|
-
* @type {Configurations}
|
|
210
|
-
*/
|
|
211
|
-
let gulpConfigurations = {}
|
|
212
|
-
if (fileExists(process.cwd() + '/build-tools.config.json')) {
|
|
213
|
-
gulpConfigurations = JSON.parse(readFileSync(process.cwd() + '/build-tools.config.json').toString())
|
|
214
|
-
} else {
|
|
215
|
-
if (fileExists('./build-tools.config.json')) {
|
|
216
|
-
gulpConfigurations = JSON.parse(readFileSync('./build-tools.config.json').toString())
|
|
217
|
-
} else {
|
|
218
|
-
console.warn('Missing config path, ensure you have a build-tools.config.js file in you project root')
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const notation = dotNotate(setDefaults)
|
|
223
|
-
for (let notationKey in notation) {
|
|
224
|
-
const arrayEnding = /(\.\d+)$/
|
|
225
|
-
if (arrayEnding.test(notationKey)) {
|
|
226
|
-
// ends in number a key then it must be an array; use the entire array
|
|
227
|
-
notationKey = notationKey.replace(arrayEnding, '')
|
|
228
|
-
}
|
|
229
|
-
const defaultValue = dotGet(setDefaults, notationKey)
|
|
230
|
-
const existingConfig = dotGet(gulpConfigurations, notationKey, defaultValue)
|
|
231
|
-
dotSet(gulpConfigurations, notationKey, existingConfig)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Retrieve a value from the configurations, default may be returned.
|
|
236
|
-
* @memberOf module:gulpConfig
|
|
237
|
-
* @param {string|null} path
|
|
238
|
-
* @param {*} defaultValue
|
|
239
|
-
* @returns {*|null}
|
|
240
|
-
*/
|
|
241
|
-
const get = (path = null, defaultValue = null) => dotGet(gulpConfigurations, path, defaultValue)
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Specify a value for the configurations to use.
|
|
245
|
-
* @memberOf module:gulpConfig
|
|
246
|
-
* @param path
|
|
247
|
-
* @param value
|
|
248
|
-
* @returns {*}
|
|
249
|
-
*/
|
|
250
|
-
const set = (path, value) => dotSet(gulpConfigurations, path, value)
|
|
251
|
-
|
|
252
|
-
module.exports = {
|
|
253
|
-
get,
|
|
254
|
-
set
|
|
255
|
-
}
|
|
1
|
+
// gulp.config.mjs is the single source of truth. This CommonJS entry re-exports it, so CommonJS consumers
|
|
2
|
+
// (dist/*.js, jsdoc.base.js, require('js-build-tools/gulp.config')) read exactly the same configuration.
|
|
3
|
+
// Relies on require(esm), which Node 22.12+ supports natively.
|
|
4
|
+
module.exports = require('./gulp.config.mjs')
|
package/gulp.config.mjs
CHANGED
|
@@ -101,6 +101,9 @@ import { fileExists } from 'test-filesystem'
|
|
|
101
101
|
* @typedef {Object<string, Setting>} module:gulpConfig~ReadmeConfig
|
|
102
102
|
* @property {StringSetting} file - The name of the output documentation markdown file.
|
|
103
103
|
* @property {StringSetting} from - Location of files to use for compiling documentation into the readme.
|
|
104
|
+
* @property {ArrayableSetting} fromEsm - Additional `.mjs` files to document alongside `from`, converted on the
|
|
105
|
+
* fly since the readme generator only recognizes `.js` files - see 'Configure including ESM files in the
|
|
106
|
+
* generated readme'. Empty by default: a project that never sets this gets exactly the readme it always did.
|
|
104
107
|
* @property {ArrayableSetting} options - Options for formatting the output readme.
|
|
105
108
|
* @property {StringSetting} template - The file which will be pre-fixed to your README.md output.
|
|
106
109
|
* @property {StringSetting} to - The directory to output the readme file in.
|
|
@@ -200,6 +203,7 @@ const setDefaults = {
|
|
|
200
203
|
readme: {
|
|
201
204
|
file: 'README.md',
|
|
202
205
|
from: 'src/**/!(*.test).js',
|
|
206
|
+
fromEsm: [],
|
|
203
207
|
options: 'utf8',
|
|
204
208
|
template: 'MAIN.md',
|
|
205
209
|
to: './'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-build-tools",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.0",
|
|
4
4
|
"description": "Standardised build process with gulp.",
|
|
5
5
|
"main": "gulpfile.base.js",
|
|
6
6
|
"exports": {
|
|
@@ -108,5 +108,8 @@
|
|
|
108
108
|
"gulp-imagemin": "github:jheagle/gulp-imagemin#common-js-compatibility",
|
|
109
109
|
"typedoc": "^0.28.20",
|
|
110
110
|
"typescript": "^6.0.3"
|
|
111
|
+
},
|
|
112
|
+
"engines": {
|
|
113
|
+
"node": ">=22.12.0"
|
|
111
114
|
}
|
|
112
115
|
}
|