@cocreate/utils 1.37.3 → 1.39.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 +33 -0
- package/docs/index.html +321 -321
- package/package.json +4 -8
- package/src/index.js +274 -139
- package/webpack.config.js +65 -90
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.39.0",
|
|
4
4
|
"description": "A simple utils component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"utils",
|
|
@@ -45,14 +45,10 @@
|
|
|
45
45
|
},
|
|
46
46
|
"main": "./src/index.js",
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"clean-webpack-plugin": "^3.0.0",
|
|
52
|
-
"file-loader": "^6.2.0",
|
|
48
|
+
"css-loader": "^5.1.3",
|
|
49
|
+
"esbuild": "^0.25.2",
|
|
50
|
+
"esbuild-loader": "^4.3.0",
|
|
53
51
|
"mini-css-extract-plugin": "^1.5.0",
|
|
54
|
-
"style-loader": "^3.3.1",
|
|
55
|
-
"terser-webpack-plugin": "^5.1.1",
|
|
56
52
|
"webpack": "^5.24.4",
|
|
57
53
|
"webpack-cli": "^4.5.0",
|
|
58
54
|
"webpack-log": "^3.0.1"
|
package/src/index.js
CHANGED
|
@@ -221,6 +221,72 @@
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Flattens a deeply nested object or array into a single-level object
|
|
226
|
+
* where keys are dot/bracket notation paths and values are the corresponding
|
|
227
|
+
* primitive values (string, number, boolean, null, undefined) from the
|
|
228
|
+
* original structure.
|
|
229
|
+
*
|
|
230
|
+
* @param {object|array} input The object or array to flatten.
|
|
231
|
+
* @returns {object} A flat object with dot/bracket notation keys mapped to their primitive values.
|
|
232
|
+
*/
|
|
233
|
+
function objectToDotNotation(input) {
|
|
234
|
+
const results = {}; // Initialize an empty OBJECT to store key-value pairs
|
|
235
|
+
|
|
236
|
+
// Helper function for recursion
|
|
237
|
+
function traverse(currentValue, path) {
|
|
238
|
+
// Base Case: Primitive values (or null/undefined)
|
|
239
|
+
// We consider anything that's not an object or is null as a primitive endpoint.
|
|
240
|
+
if (typeof currentValue !== "object" || currentValue === null) {
|
|
241
|
+
// Only add if a path exists (handles the edge case where the initial input itself is primitive)
|
|
242
|
+
if (path !== undefined && path !== null && path !== "") {
|
|
243
|
+
results[path] = currentValue; // Assign the primitive value to the constructed path key
|
|
244
|
+
}
|
|
245
|
+
return; // Stop recursion for this branch
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Recursive Step: Array
|
|
249
|
+
if (Array.isArray(currentValue)) {
|
|
250
|
+
// Only traverse non-empty arrays if we're looking for primitive values
|
|
251
|
+
// If you wanted empty arrays represented (e.g., 'notes': []), you'd add logic here.
|
|
252
|
+
if (currentValue.length > 0) {
|
|
253
|
+
currentValue.forEach((item, index) => {
|
|
254
|
+
// Build the next path segment using bracket notation for arrays
|
|
255
|
+
const nextPath = `${path}[${index}]`;
|
|
256
|
+
traverse(item, nextPath);
|
|
257
|
+
});
|
|
258
|
+
} else if (path) {
|
|
259
|
+
// Optional: represent empty arrays explicitly if needed
|
|
260
|
+
// results[path] = []; // Uncomment this line if you want empty arrays included
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// Recursive Step: Object (and not null, not an array)
|
|
264
|
+
else {
|
|
265
|
+
const keys = Object.keys(currentValue);
|
|
266
|
+
// Only traverse non-empty objects if we're looking for primitive values
|
|
267
|
+
// If you wanted empty objects represented (e.g., 'metadata': {}), you'd add logic here.
|
|
268
|
+
if (keys.length > 0) {
|
|
269
|
+
keys.forEach((key) => {
|
|
270
|
+
// Build the next path segment:
|
|
271
|
+
// - Use dot notation if the current path is not empty.
|
|
272
|
+
// - Just use the key if it's the first level.
|
|
273
|
+
const nextPath = path ? `${path}.${key}` : key;
|
|
274
|
+
traverse(currentValue[key], nextPath);
|
|
275
|
+
});
|
|
276
|
+
} else if (path) {
|
|
277
|
+
// Optional: represent empty objects explicitly if needed
|
|
278
|
+
// results[path] = {}; // Uncomment this line if you want empty objects included
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Start the traversal with the initial input and an empty path
|
|
284
|
+
// Using an empty string '' ensures the first level keys don't start with '.'
|
|
285
|
+
traverse(input, "");
|
|
286
|
+
|
|
287
|
+
return results; // Return the populated results object
|
|
288
|
+
}
|
|
289
|
+
|
|
224
290
|
function getValueFromObject(object = {}, path = "", throwError = false) {
|
|
225
291
|
try {
|
|
226
292
|
if (!Object.keys(object).length || !path) {
|
|
@@ -439,6 +505,51 @@
|
|
|
439
505
|
}
|
|
440
506
|
}
|
|
441
507
|
|
|
508
|
+
/**
|
|
509
|
+
* Converts a JavaScript object into a URL-encoded query string using
|
|
510
|
+
* the standard URLSearchParams API (works in Node.js and modern browsers).
|
|
511
|
+
* - Uses repeated keys for arrays.
|
|
512
|
+
* - Skips null/undefined values.
|
|
513
|
+
* - Converts other values to strings.
|
|
514
|
+
*
|
|
515
|
+
* @param {object | null | undefined} paramsObj The object to convert.
|
|
516
|
+
* @returns {string} A URL-encoded query string starting with '?'
|
|
517
|
+
* if params exist, otherwise an empty string.
|
|
518
|
+
*/
|
|
519
|
+
function objectToSearchParams(paramsObj) {
|
|
520
|
+
if (
|
|
521
|
+
!paramsObj ||
|
|
522
|
+
typeof paramsObj !== "object" ||
|
|
523
|
+
Array.isArray(paramsObj)
|
|
524
|
+
) {
|
|
525
|
+
return "";
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Filter out null/undefined values
|
|
529
|
+
const filteredObj = {};
|
|
530
|
+
for (const key in paramsObj) {
|
|
531
|
+
if (Object.hasOwn(paramsObj, key)) {
|
|
532
|
+
const value = paramsObj[key];
|
|
533
|
+
if (value !== null && value !== undefined) {
|
|
534
|
+
filteredObj[key] = value;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (Object.keys(filteredObj).length === 0) {
|
|
540
|
+
return "";
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// --- CORE LOGIC ---
|
|
544
|
+
// Create URLSearchParams directly from the filtered object
|
|
545
|
+
// This works identically in modern Node.js and browsers.
|
|
546
|
+
const searchParams = new URLSearchParams(filteredObj);
|
|
547
|
+
const queryString = searchParams.toString();
|
|
548
|
+
// --- END CORE LOGIC ---
|
|
549
|
+
|
|
550
|
+
return queryString ? `?${queryString}` : "";
|
|
551
|
+
}
|
|
552
|
+
|
|
442
553
|
function domParser(str) {
|
|
443
554
|
try {
|
|
444
555
|
var mainTag = str.match(/\<(?<tag>[a-z0-9]+)(.*?)?\>/).groups.tag;
|
|
@@ -540,157 +651,179 @@
|
|
|
540
651
|
return path;
|
|
541
652
|
}
|
|
542
653
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
654
|
+
// Define a list of query types that describe relationships or contexts in the DOM.
|
|
655
|
+
const queryTypes = [
|
|
656
|
+
"$closest", // Selects the closest ancestor matching the selector
|
|
657
|
+
"$parent", // Selects the direct parent element
|
|
658
|
+
"$next", // Selects the next sibling element
|
|
659
|
+
"$previous", // Selects the previous sibling element
|
|
660
|
+
"$document", // Selects the document containing the element
|
|
661
|
+
"$frame", // Selects the frame or iframe containing the element
|
|
662
|
+
"$top" // Selects the top-level document or window
|
|
663
|
+
];
|
|
664
|
+
|
|
665
|
+
// Construct a regular expression pattern to match any of the query types.
|
|
666
|
+
// Each query type begins with a dollar sign, which is escaped in the regex.
|
|
667
|
+
const regexPatternString = `(?:${queryTypes
|
|
668
|
+
.map((type) => type.replace("$", "\\$")) // Escape $ character for regex
|
|
669
|
+
.join("|")})`;
|
|
670
|
+
|
|
671
|
+
// Compile the regular expression pattern into a RegExp object.
|
|
672
|
+
// This regex will be used to find the first occurrence of any query type within a string.
|
|
673
|
+
const queryTypesRegex = new RegExp(regexPatternString);
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Function to query DOM elements based on specified criteria.
|
|
677
|
+
* @param {Object} params - Object containing parameters for querying elements.
|
|
678
|
+
* @param {Element|Document} params.element - The root element or document to start the query from. Defaults to the entire document.
|
|
679
|
+
* @param {string} params.prefix - Optional prefix used to construct the query.
|
|
680
|
+
* @param {string} params.selector - The CSS selector or query string to use.
|
|
681
|
+
* @returns {Array} - An array of elements that match the query.
|
|
682
|
+
*/
|
|
683
|
+
function queryElements({ element = document, prefix, selector }) {
|
|
684
|
+
// Initialize a Set to store unique elements.
|
|
685
|
+
let elements = new Set();
|
|
686
|
+
|
|
687
|
+
// If no selector is provided and the element is an element node.
|
|
688
|
+
if (!selector && element.nodeType === 1) {
|
|
689
|
+
// If no prefix is provided, derive one from the element's attributes.
|
|
690
|
+
if (!prefix) {
|
|
691
|
+
for (let attr of element.attributes) {
|
|
692
|
+
// If an attribute with "-query" suffix is found, extract prefix.
|
|
693
|
+
if (attr.name.endsWith("-query")) {
|
|
694
|
+
prefix = attr.name.slice(0, -6);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
// If no valid prefix is found, exit the function.
|
|
698
|
+
if (!prefix) return false;
|
|
560
699
|
}
|
|
700
|
+
// Get the selector using the derived prefix.
|
|
701
|
+
selector = element.getAttribute(prefix + "-" + "query");
|
|
702
|
+
if (!selector) return false; // Exit if no selector is found.
|
|
703
|
+
}
|
|
561
704
|
|
|
562
|
-
|
|
563
|
-
|
|
705
|
+
// Split complex selectors into individual ones, handling nested structures.
|
|
706
|
+
let selectors = selector.split(/,(?![^()\[\]]*[)\]])/g);
|
|
707
|
+
for (let i = 0; i < selectors.length; i++) {
|
|
708
|
+
if (!selectors[i]) continue; // Skip empty selectors.
|
|
564
709
|
|
|
565
|
-
|
|
566
|
-
if (selectors[j].includes("@")) {
|
|
567
|
-
selectors[j] = checkMediaQueries(selectors[j]);
|
|
568
|
-
if (selectors[j] === false) continue;
|
|
569
|
-
}
|
|
710
|
+
let queriedElement = element; // Start query from the current element.
|
|
570
711
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
// queriedElement = [queriedElement]
|
|
577
|
-
// }
|
|
578
|
-
|
|
579
|
-
if (!specialSelectors[k]) continue;
|
|
580
|
-
if (k === 0) {
|
|
581
|
-
if (type[i] === "parent")
|
|
582
|
-
queriedElement = queriedElement.parentElement;
|
|
583
|
-
else if (type[i] === "next")
|
|
584
|
-
queriedElement =
|
|
585
|
-
queriedElement.nextElementSibling;
|
|
586
|
-
else if (type[i] === "previous")
|
|
587
|
-
queriedElement =
|
|
588
|
-
queriedElement.previousElementSibling;
|
|
589
|
-
} else if (queriedElement.contentDocument) {
|
|
590
|
-
queriedElement = queriedElement.contentDocument;
|
|
591
|
-
}
|
|
712
|
+
// If media queries are included, verify and filter the selector accordingly.
|
|
713
|
+
if (selectors[i].includes("@")) {
|
|
714
|
+
selectors[i] = checkMediaQueries(selectors[i]);
|
|
715
|
+
if (selectors[i] === false) continue; // Skip if media query is not matched.
|
|
716
|
+
}
|
|
592
717
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
case "parent":
|
|
611
|
-
queriedElement = queriedElement.parentElement;
|
|
612
|
-
break;
|
|
613
|
-
case "next":
|
|
614
|
-
queriedElement =
|
|
615
|
-
queriedElement.nextElementSibling;
|
|
616
|
-
break;
|
|
617
|
-
case "previous":
|
|
618
|
-
queriedElement =
|
|
619
|
-
queriedElement.previousElementSibling;
|
|
620
|
-
break;
|
|
621
|
-
default:
|
|
622
|
-
if (k === 0 && type[i] === "closest")
|
|
623
|
-
if (specialSelectors[k].includes(" ")) {
|
|
624
|
-
let [firstSelector, ...restSelectors] =
|
|
625
|
-
specialSelectors[k].split(/ (.+)/);
|
|
626
|
-
queriedElement =
|
|
627
|
-
queriedElement.closest(
|
|
628
|
-
firstSelector
|
|
629
|
-
);
|
|
630
|
-
if (restSelectors.length > 0) {
|
|
631
|
-
if (restSelectors[0].endsWith("[]"))
|
|
632
|
-
queriedElement =
|
|
633
|
-
queriedElement.querySelectorAll(
|
|
634
|
-
restSelectors[0].slice(
|
|
635
|
-
0,
|
|
636
|
-
-2
|
|
637
|
-
)
|
|
638
|
-
);
|
|
639
|
-
else
|
|
640
|
-
queriedElement =
|
|
641
|
-
queriedElement.querySelector(
|
|
642
|
-
restSelectors[0]
|
|
643
|
-
);
|
|
644
|
-
}
|
|
645
|
-
} else {
|
|
646
|
-
// If no space, just use the selector with closest
|
|
647
|
-
queriedElement = queriedElement.closest(
|
|
648
|
-
specialSelectors[k]
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
else if (
|
|
652
|
-
specialSelectors[k] === "$clickedElement"
|
|
653
|
-
) {
|
|
654
|
-
queriedElement =
|
|
655
|
-
queriedElement.clickedElement;
|
|
656
|
-
} else if (specialSelectors[k].endsWith("[]"))
|
|
657
|
-
queriedElement =
|
|
658
|
-
queriedElement.querySelectorAll(
|
|
659
|
-
specialSelectors[k].slice(0, -2)
|
|
660
|
-
);
|
|
661
|
-
else
|
|
662
|
-
queriedElement =
|
|
663
|
-
queriedElement.querySelector(
|
|
664
|
-
specialSelectors[k]
|
|
665
|
-
);
|
|
666
|
-
}
|
|
667
|
-
if (!queriedElement) break;
|
|
668
|
-
}
|
|
718
|
+
let remainingSelector = selectors[i].trim(); // Trim any whitespace.
|
|
719
|
+
let match;
|
|
720
|
+
|
|
721
|
+
// Process each part of the selector that corresponds to specific query types/operators.
|
|
722
|
+
while ((match = queryTypesRegex.exec(remainingSelector)) !== null) {
|
|
723
|
+
const matchIndex = match.index;
|
|
724
|
+
const operator = match[0];
|
|
725
|
+
|
|
726
|
+
// Process the part before the operator (if any).
|
|
727
|
+
const part = remainingSelector
|
|
728
|
+
.substring(0, matchIndex)
|
|
729
|
+
.trim()
|
|
730
|
+
.replace(/,$/, "");
|
|
731
|
+
if (part) {
|
|
732
|
+
queriedElement = querySelector(queriedElement, part);
|
|
733
|
+
if (!queriedElement) break; // Exit loop if no element is found.
|
|
734
|
+
}
|
|
669
735
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
736
|
+
// Remove the processed part and operator from the remaining selector.
|
|
737
|
+
remainingSelector = remainingSelector
|
|
738
|
+
.substring(matchIndex + operator.length)
|
|
739
|
+
.trim();
|
|
740
|
+
|
|
741
|
+
// Handle the $closest operator specifically.
|
|
742
|
+
if (operator === "$closest") {
|
|
743
|
+
let [closest, remaining = ""] = remainingSelector.split(
|
|
744
|
+
/\s+/,
|
|
745
|
+
2
|
|
746
|
+
);
|
|
747
|
+
queriedElement = queriedElement.closest(closest);
|
|
748
|
+
remainingSelector = remaining.trim();
|
|
749
|
+
} else {
|
|
750
|
+
// Process other operators using the queryType function.
|
|
751
|
+
queriedElement = queryType(queriedElement, operator);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (!queriedElement) break; // Exit loop if no element is found.
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (!queriedElement) continue; // Skip if no element is found.
|
|
758
|
+
|
|
759
|
+
// Process the remaining part after the last operator (if any).
|
|
760
|
+
if (remainingSelector) {
|
|
761
|
+
queriedElement = querySelector(
|
|
762
|
+
queriedElement,
|
|
763
|
+
remainingSelector
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Add elements to the set.
|
|
768
|
+
if (
|
|
769
|
+
Array.isArray(queriedElement) ||
|
|
770
|
+
queriedElement instanceof HTMLCollection ||
|
|
771
|
+
queriedElement instanceof NodeList
|
|
772
|
+
) {
|
|
773
|
+
for (let el of queriedElement) {
|
|
774
|
+
if (el instanceof Element) {
|
|
775
|
+
elements.add(el);
|
|
678
776
|
}
|
|
679
777
|
}
|
|
680
|
-
} else if (
|
|
681
|
-
|
|
682
|
-
elements.set(element.parentElement, "");
|
|
683
|
-
else if (type[i] === "next")
|
|
684
|
-
elements.set(element.nextElementSibling, "");
|
|
685
|
-
else if (type[i] === "previous")
|
|
686
|
-
elements.set(element.previousElementSibling, "");
|
|
778
|
+
} else if (queriedElement instanceof Element) {
|
|
779
|
+
elements.add(queriedElement);
|
|
687
780
|
}
|
|
688
781
|
}
|
|
689
782
|
|
|
690
|
-
|
|
691
|
-
|
|
783
|
+
return Array.from(elements); // Convert Set to Array and return found elements.
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
function queryType(element, type) {
|
|
787
|
+
if (!element) return null;
|
|
788
|
+
|
|
789
|
+
switch (type) {
|
|
790
|
+
case "$top":
|
|
791
|
+
return window.top.document;
|
|
792
|
+
case "$frame":
|
|
793
|
+
// If element is a document, return the iframe element containing it
|
|
794
|
+
if (element.nodeType === 9) return window.frameElement;
|
|
795
|
+
// If element is an iframe, return it as is
|
|
796
|
+
return element;
|
|
797
|
+
case "$document":
|
|
798
|
+
// If element is a document, return itself, else return `ownerDocument`
|
|
799
|
+
return element.nodeType === 9 ? element : element.ownerDocument;
|
|
800
|
+
case "$closest":
|
|
801
|
+
// If closest find the first selector seperated by space
|
|
802
|
+
|
|
803
|
+
return element.nodeType === 9 ? element : element.ownerDocument;
|
|
804
|
+
case "$parent":
|
|
805
|
+
// If it's a document, return the parent document (if inside an iframe)
|
|
806
|
+
if (element.nodeType === 9) {
|
|
807
|
+
return element.defaultView !== window.top
|
|
808
|
+
? element.defaultView.parent.document
|
|
809
|
+
: null;
|
|
810
|
+
}
|
|
811
|
+
// Otherwise, return parent element
|
|
812
|
+
return element.parentElement;
|
|
813
|
+
case "$next":
|
|
814
|
+
return element.nextElementSibling;
|
|
815
|
+
case "$previous":
|
|
816
|
+
return element.previousElementSibling;
|
|
817
|
+
default:
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
692
821
|
|
|
693
|
-
|
|
822
|
+
function querySelector(element, selector) {
|
|
823
|
+
if (!element) return null;
|
|
824
|
+
return selector.endsWith("[]")
|
|
825
|
+
? element.querySelectorAll(selector.slice(0, -2))
|
|
826
|
+
: element.querySelector(selector);
|
|
694
827
|
}
|
|
695
828
|
|
|
696
829
|
const mediaRanges = {
|
|
@@ -1119,7 +1252,9 @@
|
|
|
1119
1252
|
checkValue,
|
|
1120
1253
|
isValidDate,
|
|
1121
1254
|
dotNotationToObject,
|
|
1255
|
+
objectToDotNotation,
|
|
1122
1256
|
getValueFromObject,
|
|
1257
|
+
objectToSearchParams,
|
|
1123
1258
|
domParser,
|
|
1124
1259
|
parseTextToHtml,
|
|
1125
1260
|
escapeHtml,
|
package/webpack.config.js
CHANGED
|
@@ -1,90 +1,65 @@
|
|
|
1
|
-
const path = require("path")
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
module.exports = (env, argv) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
parallel: true,
|
|
67
|
-
// sourceMap: true, // Must be set to true if using source-maps in production
|
|
68
|
-
terserOptions: {
|
|
69
|
-
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
|
|
70
|
-
// extractComments: 'all',
|
|
71
|
-
compress: {
|
|
72
|
-
drop_console: true,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
}),
|
|
76
|
-
],
|
|
77
|
-
splitChunks: {
|
|
78
|
-
chunks: "all",
|
|
79
|
-
minSize: 200,
|
|
80
|
-
// maxSize: 99999,
|
|
81
|
-
//minChunks: 1,
|
|
82
|
-
|
|
83
|
-
cacheGroups: {
|
|
84
|
-
defaultVendors: false,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
}
|
|
89
|
-
return config
|
|
90
|
-
}
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
3
|
+
const { EsbuildPlugin } = require("esbuild-loader");
|
|
4
|
+
const { FileUploader } = require("@cocreate/webpack");
|
|
5
|
+
|
|
6
|
+
module.exports = async (env, argv) => {
|
|
7
|
+
const isProduction = argv && argv.mode === "production";
|
|
8
|
+
const config = {
|
|
9
|
+
entry: {
|
|
10
|
+
"CoCreate-utils": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
output: {
|
|
13
|
+
path: path.resolve(__dirname, "dist"),
|
|
14
|
+
filename: isProduction ? "[name].min.js" : "[name].js",
|
|
15
|
+
libraryExport: "default",
|
|
16
|
+
library: ["CoCreate", "utils"],
|
|
17
|
+
clean: true
|
|
18
|
+
},
|
|
19
|
+
plugins: [
|
|
20
|
+
new MiniCssExtractPlugin({
|
|
21
|
+
filename: isProduction ? "[name].min.css" : "[name].css"
|
|
22
|
+
}),
|
|
23
|
+
new FileUploader(env, argv)
|
|
24
|
+
],
|
|
25
|
+
mode: isProduction ? "production" : "development",
|
|
26
|
+
devtool: isProduction ? "source-map" : "eval-source-map",
|
|
27
|
+
module: {
|
|
28
|
+
rules: [
|
|
29
|
+
{
|
|
30
|
+
test: /.js$/,
|
|
31
|
+
exclude: /node_modules/,
|
|
32
|
+
use: {
|
|
33
|
+
loader: "esbuild-loader",
|
|
34
|
+
options: {
|
|
35
|
+
loader: "js",
|
|
36
|
+
target: "es2017"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
test: /.css$/i,
|
|
42
|
+
use: [MiniCssExtractPlugin.loader, "css-loader"]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
optimization: {
|
|
47
|
+
minimize: isProduction,
|
|
48
|
+
minimizer: [
|
|
49
|
+
new EsbuildPlugin({
|
|
50
|
+
target: "es2017",
|
|
51
|
+
css: true
|
|
52
|
+
})
|
|
53
|
+
],
|
|
54
|
+
splitChunks: {
|
|
55
|
+
cacheGroups: {
|
|
56
|
+
defaultVendors: false
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
performance: {
|
|
61
|
+
hints: isProduction ? "warning" : false
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return config;
|
|
65
|
+
};
|