chocola 1.5.2 → 2.0.0-next.1
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/compiler/component-processor.js +55 -9
- package/compiler/dom-processor.js +9 -1
- package/compiler/index.js +208 -99
- package/compiler/pipeline.js +2 -15
- package/dev/index.js +24 -1
- package/index.js +0 -31
- package/package.json +3 -2
- package/.gitattributes +0 -2
|
@@ -22,6 +22,28 @@ function scopeSelector(sel, cssId) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function scopeCss(cssString, cssId) {
|
|
25
|
+
const keyframeRegex = /@(-webkit-)?keyframes\s+(\S+)/gi;
|
|
26
|
+
const animNames = new Set();
|
|
27
|
+
let match;
|
|
28
|
+
while ((match = keyframeRegex.exec(cssString))) {
|
|
29
|
+
animNames.add(match[2]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (animNames.size > 0) {
|
|
33
|
+
const sorted = [...animNames].sort((a, b) => b.length - a.length);
|
|
34
|
+
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
35
|
+
for (const name of sorted) {
|
|
36
|
+
cssString = cssString.replace(
|
|
37
|
+
new RegExp(`(@(?:-webkit-)?keyframes\\s+)${esc(name)}`, "gi"),
|
|
38
|
+
`$1${name}-${cssId}`
|
|
39
|
+
);
|
|
40
|
+
cssString = cssString.replace(
|
|
41
|
+
new RegExp(`((?:animation|animation-name)\\s*:\\s*[^;{]*?)\\b${esc(name)}\\b`, "gi"),
|
|
42
|
+
`$1${name}-${cssId}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
25
47
|
function findMatchingBrace(s, openIndex) {
|
|
26
48
|
let depth = 0;
|
|
27
49
|
for (let i = openIndex; i < s.length; i++) {
|
|
@@ -35,6 +57,8 @@ function scopeCss(cssString, cssId) {
|
|
|
35
57
|
return s.length - 1;
|
|
36
58
|
}
|
|
37
59
|
|
|
60
|
+
const scopeInnerAtRules = new Set(["@media", "@supports", "@container", "@layer"]);
|
|
61
|
+
|
|
38
62
|
function processBlock(str) {
|
|
39
63
|
str = str.replaceAll(":root", `.${cssId}`);
|
|
40
64
|
|
|
@@ -49,11 +73,16 @@ function scopeCss(cssString, cssId) {
|
|
|
49
73
|
const header = str.substring(i, braceIndex);
|
|
50
74
|
const endBrace = findMatchingBrace(str, braceIndex);
|
|
51
75
|
const inner = str.substring(braceIndex + 1, endBrace);
|
|
52
|
-
const innerScoped = processBlock(inner);
|
|
53
76
|
|
|
54
77
|
if (header.trim().startsWith("@")) {
|
|
55
|
-
|
|
78
|
+
const atKeyword = header.trim().split(/\s+/)[0].toLowerCase();
|
|
79
|
+
if (scopeInnerAtRules.has(atKeyword)) {
|
|
80
|
+
out += header + "{" + processBlock(inner) + "}";
|
|
81
|
+
} else {
|
|
82
|
+
out += header + "{" + inner + "}";
|
|
83
|
+
}
|
|
56
84
|
} else {
|
|
85
|
+
const innerScoped = processBlock(inner);
|
|
57
86
|
const selectors = header
|
|
58
87
|
.split(",")
|
|
59
88
|
.map(s => s.trim())
|
|
@@ -72,6 +101,23 @@ function scopeCss(cssString, cssId) {
|
|
|
72
101
|
return processBlock(cssString);
|
|
73
102
|
}
|
|
74
103
|
|
|
104
|
+
const warnedDeprecated = new Set();
|
|
105
|
+
function hasDelIfAttr(el, sourceLoc) {
|
|
106
|
+
if (el.hasAttribute("del-if") && !el.hasAttribute("del:if") && !warnedDeprecated.has(sourceLoc)) {
|
|
107
|
+
warnedDeprecated.add(sourceLoc);
|
|
108
|
+
const name = sourceLoc ? sourceLoc.split(/[\\/]/).pop() : "unknown";
|
|
109
|
+
console.warn(chalk.yellow(`[deprecation] "del-if" is deprecated in ${chalk.cyan(name)} and will be removed in Chocola 2. Use "del:if" instead.`));
|
|
110
|
+
}
|
|
111
|
+
return el.hasAttribute("del-if") || el.hasAttribute("del:if");
|
|
112
|
+
}
|
|
113
|
+
function getDelIfAttr(el) {
|
|
114
|
+
return el.getAttribute("del:if") ?? el.getAttribute("del-if");
|
|
115
|
+
}
|
|
116
|
+
function removeDelIfAttr(el) {
|
|
117
|
+
el.removeAttribute("del-if");
|
|
118
|
+
el.removeAttribute("del:if");
|
|
119
|
+
}
|
|
120
|
+
|
|
75
121
|
function interpolateNode(node, ctxProxy) {
|
|
76
122
|
if (node.nodeType === 3) {
|
|
77
123
|
node.textContent = node.textContent.replace(/\{([^}]+)\}/g, (_, expr) => {
|
|
@@ -93,7 +139,7 @@ function validateChainStructure(parent, sourceFile, sourceContent, parentContent
|
|
|
93
139
|
|
|
94
140
|
for (const child of children) {
|
|
95
141
|
const hasIf = child.hasAttribute("if");
|
|
96
|
-
const hasDelIf = child
|
|
142
|
+
const hasDelIf = hasDelIfAttr(child, sourceFile);
|
|
97
143
|
const hasElif = child.hasAttribute("elif");
|
|
98
144
|
const hasElse = child.hasAttribute("else");
|
|
99
145
|
|
|
@@ -224,7 +270,7 @@ export function processComponentElement(
|
|
|
224
270
|
const condChain = condChains.get(parent);
|
|
225
271
|
|
|
226
272
|
const hasIf = child.hasAttribute("if");
|
|
227
|
-
const hasDelIf = child.
|
|
273
|
+
const hasDelIf = hasDelIfAttr(child, instance.__sourceFile || compName);
|
|
228
274
|
const hasElif = child.hasAttribute("elif");
|
|
229
275
|
const hasElse = child.hasAttribute("else");
|
|
230
276
|
|
|
@@ -257,8 +303,8 @@ export function processComponentElement(
|
|
|
257
303
|
condChain.active = false;
|
|
258
304
|
}
|
|
259
305
|
} else if (hasIf || hasDelIf) {
|
|
260
|
-
const
|
|
261
|
-
const expr =
|
|
306
|
+
const raw = hasIf ? child.getAttribute("if") : getDelIfAttr(child);
|
|
307
|
+
const expr = raw.slice(1, -1);
|
|
262
308
|
const fn = new Function("ctx", `with(ctx) { return (${expr}); }`);
|
|
263
309
|
condChain.active = true;
|
|
264
310
|
if (fn(ctxProxy)) {
|
|
@@ -276,7 +322,7 @@ export function processComponentElement(
|
|
|
276
322
|
return;
|
|
277
323
|
}
|
|
278
324
|
|
|
279
|
-
const reservedAttrs = ["if", "del-if", "elif", "else"];
|
|
325
|
+
const reservedAttrs = ["if", "del-if", "del:if", "elif", "else"];
|
|
280
326
|
|
|
281
327
|
Array.from(child.attributes).forEach(attribute => {
|
|
282
328
|
if (!attribute || attribute === undefined) return;
|
|
@@ -321,7 +367,7 @@ export function processComponentElement(
|
|
|
321
367
|
}
|
|
322
368
|
child.removeAttribute("if");
|
|
323
369
|
} else if (hasDelIf) {
|
|
324
|
-
const expr = child
|
|
370
|
+
const expr = getDelIfAttr(child).slice(1, -1);
|
|
325
371
|
const fn = new Function("ctx", `with(ctx) { return (${expr}); }`);
|
|
326
372
|
condChain.active = true;
|
|
327
373
|
if (fn(ctxProxy)) {
|
|
@@ -330,7 +376,7 @@ export function processComponentElement(
|
|
|
330
376
|
child.remove();
|
|
331
377
|
condChain.rendered = false;
|
|
332
378
|
}
|
|
333
|
-
child
|
|
379
|
+
removeDelIfAttr(child);
|
|
334
380
|
} else if (hasElif) {
|
|
335
381
|
const expr = child.getAttribute("elif").slice(1, -1);
|
|
336
382
|
const fn = new Function("ctx", `with(ctx) { return (${expr}); }`);
|
|
@@ -44,7 +44,15 @@ export function extractContextFromElement(element) {
|
|
|
44
44
|
const ctx = {};
|
|
45
45
|
for (const attr of element.attributes) {
|
|
46
46
|
const key = attr.name;
|
|
47
|
-
|
|
47
|
+
const val = attr.value;
|
|
48
|
+
const matches = [...val.matchAll(/\{([^}]+)\}/g)];
|
|
49
|
+
if (matches.length === 1 && matches[0][0] === val) {
|
|
50
|
+
try {
|
|
51
|
+
ctx[key] = Function(`"use strict"; return (${matches[0][1]})`)();
|
|
52
|
+
continue;
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
ctx[key] = val;
|
|
48
56
|
}
|
|
49
57
|
return ctx;
|
|
50
58
|
}
|
package/compiler/index.js
CHANGED
|
@@ -2,26 +2,26 @@ import { promises as fs } from "fs";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { loadConfig, resolvePaths } from "./config.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
createDOM,
|
|
6
|
+
validateAppContainer,
|
|
7
|
+
getAppElements,
|
|
8
|
+
getAssetLinks,
|
|
9
|
+
appendRuntimeScript,
|
|
10
|
+
appendStylesheetLink,
|
|
11
|
+
serializeDOM,
|
|
12
|
+
writeHTMLOutput,
|
|
13
|
+
writeCSSOutput,
|
|
14
14
|
} from "./dom-processor.js";
|
|
15
15
|
import { processAllComponents } from "./component-processor.js";
|
|
16
16
|
import { generateRuntimeScript } from "./runtime-generator.js";
|
|
17
17
|
import { genRandomId, throwError } from "./utils.js";
|
|
18
18
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
copyResources,
|
|
20
|
+
copyStaticDir,
|
|
21
|
+
getComponents,
|
|
22
|
+
getSrcIndex,
|
|
23
|
+
processIcons,
|
|
24
|
+
processStylesheet,
|
|
25
25
|
} from "./pipeline.js";
|
|
26
26
|
|
|
27
27
|
|
|
@@ -31,10 +31,10 @@ ________________________________________________________________________
|
|
|
31
31
|
`);
|
|
32
32
|
|
|
33
33
|
function logBanner() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
console.log(chalk.bold.hex("#945e33")(`\n RUNNING CHOCOLA BUNDLER`));
|
|
35
|
+
console.log(logSeparation);
|
|
36
|
+
console.log(
|
|
37
|
+
chalk.hex("#945e33")(`
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
▄████▄ ██░ ██ ▒█████ ▄████▄ ▒█████ ██▓ ▄▄▄
|
|
@@ -46,64 +46,64 @@ function logBanner() {
|
|
|
46
46
|
░ ▒ ▒ ░▒░ ░ ░ ░ ▒ ▒░ ░ ▒ ░ ░ ▒░ ░ ░ ▒ ░ ░ ▒▒ ░
|
|
47
47
|
░ ░ ░░ ░░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒
|
|
48
48
|
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
|
|
49
|
-
|
|
49
|
+
░ ░
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
`)
|
|
53
|
-
|
|
53
|
+
);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function logSuccess(outDirPath) {
|
|
57
|
-
|
|
57
|
+
console.log(`
|
|
58
58
|
▄▄ ▄▄▄ ▄▄▄▄ ▄▄▄▄ ▄▄▄ ▄▄ ▄▄ ▄▄▄▄▄ ██
|
|
59
59
|
██ ██▀██ ██▄██ ██▀██ ██▀██ ███▄██ ██▄▄ ██
|
|
60
60
|
▄▄█▀ ▀███▀ ██▄█▀ ████▀ ▀███▀ ██ ▀██ ██▄▄▄ ▄▄
|
|
61
61
|
|
|
62
62
|
`);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
console.log(
|
|
64
|
+
chalk.bold.green(">"),
|
|
65
|
+
"Project bundled succesfully at",
|
|
66
|
+
chalk.green.underline(outDirPath) + "\n\n"
|
|
67
|
+
);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
async function setupOutputDirectory(outDirPath, emptyOutDir) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
if (emptyOutDir) {
|
|
72
|
+
await fs.rm(outDirPath, { recursive: true, force: true });
|
|
73
|
+
await fs.mkdir(outDirPath);
|
|
74
|
+
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
async function loadAndDisplayComponents(srcComponentsPath) {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const foundComponents = await getComponents(srcComponentsPath);
|
|
79
|
+
const { loadedComponents, notDefComps, componentsLib } = foundComponents;
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
console.log(` LOADING COMPONENTS`);
|
|
82
|
+
console.log(chalk.bold.green(">"), "Components found in", chalk.green.underline(srcComponentsPath) + ":");
|
|
83
|
+
console.log(" ", componentsLib, "\n");
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
if (notDefComps.length > 0) {
|
|
86
|
+
console.warn(chalk.bold.yellow("WARNING!"), "The following components don't include a default export:");
|
|
87
|
+
console.log(" ", notDefComps);
|
|
88
|
+
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
return loadedComponents;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
async function processAssets(doc, rootDir, srcDir, outDirPath) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const { stylesheets, icons } = getAssetLinks(doc);
|
|
95
|
+
const fileIds = [];
|
|
96
|
+
let cssContents = [];
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
for (const link of stylesheets) {
|
|
99
|
+
const css = await processStylesheet(link, rootDir, srcDir, outDirPath, fileIds);
|
|
100
|
+
cssContents.push(css);
|
|
101
|
+
}
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
for (const link of icons) {
|
|
104
|
+
await processIcons(link, rootDir, srcDir, outDirPath);
|
|
105
|
+
}
|
|
106
|
+
return cssContents
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/**
|
|
@@ -115,54 +115,163 @@ async function processAssets(doc, rootDir, srcDir, outDirPath) {
|
|
|
115
115
|
* >} config
|
|
116
116
|
*/
|
|
117
117
|
export default async function runtime(rootDir, buildConfig) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
118
|
+
const isHotReload = buildConfig?.isHotReload || null;
|
|
119
|
+
!isHotReload && logBanner();
|
|
120
|
+
|
|
121
|
+
const config = await loadConfig(rootDir);
|
|
122
|
+
const paths = resolvePaths(rootDir, config);
|
|
123
|
+
!isHotReload && console.log(logSeparation);
|
|
124
|
+
|
|
125
|
+
await setupOutputDirectory(paths.outDir, config.emptyOutDir);
|
|
126
|
+
|
|
127
|
+
const indexFiles = await getSrcIndex(paths.src);
|
|
128
|
+
const srcIndexContent = indexFiles.srcHtmlFile;
|
|
129
|
+
const pageSourcePath = indexFiles.srcPath;
|
|
130
|
+
|
|
131
|
+
const loadedComponents = await loadAndDisplayComponents(paths.components);
|
|
132
|
+
!isHotReload && console.log(logSeparation);
|
|
133
|
+
!isHotReload && console.log(` BUNDLING STATIC BUILD`);
|
|
134
|
+
!isHotReload && console.log(chalk.bold.green(">"), "Creating Chocola static build in directory", chalk.green.underline(paths.outDir) + "\n");
|
|
135
|
+
!isHotReload && console.log(logSeparation);
|
|
136
|
+
|
|
137
|
+
const dom = createDOM(srcIndexContent);
|
|
138
|
+
const doc = dom.window.document;
|
|
139
|
+
const appContainer = validateAppContainer(doc);
|
|
140
|
+
|
|
141
|
+
const warnedDeprecated = new Set();
|
|
142
|
+
function hasDelIfAttr(el, sourceLoc) {
|
|
143
|
+
if (el.hasAttribute("del-if") && !el.hasAttribute("del:if") && !warnedDeprecated.has(sourceLoc)) {
|
|
144
|
+
warnedDeprecated.add(sourceLoc);
|
|
145
|
+
const name = sourceLoc ? sourceLoc.split(/[\\/]/).pop() : "unknown";
|
|
146
|
+
console.warn(chalk.yellow(`[deprecation] "del-if" is deprecated in ${chalk.cyan(name)} and will be removed in Chocola 2. Use "del:if" instead.`));
|
|
147
|
+
}
|
|
148
|
+
return el.hasAttribute("del-if") || el.hasAttribute("del:if");
|
|
149
|
+
}
|
|
150
|
+
function getDelIfAttr(el) {
|
|
151
|
+
return el.getAttribute("del:if") ?? el.getAttribute("del-if");
|
|
152
|
+
}
|
|
153
|
+
function removeDelIfAttr(el) {
|
|
154
|
+
el.removeAttribute("del-if");
|
|
155
|
+
el.removeAttribute("del:if");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function processPageConditionals(parent) {
|
|
159
|
+
const children = [...parent.children];
|
|
160
|
+
let chainActive = false;
|
|
161
|
+
let chainRendered = false;
|
|
162
|
+
|
|
163
|
+
for (const child of children) {
|
|
164
|
+
const hasIf = child.hasAttribute("if");
|
|
165
|
+
const hasDelIf = hasDelIfAttr(child, pageSourcePath);
|
|
166
|
+
const hasElif = child.hasAttribute("elif");
|
|
167
|
+
const hasElse = child.hasAttribute("else");
|
|
168
|
+
|
|
169
|
+
if (hasElif || hasElse) {
|
|
170
|
+
if (!chainActive) continue;
|
|
171
|
+
if (chainRendered) { child.remove(); continue; }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (hasIf) {
|
|
175
|
+
const raw = child.getAttribute("if");
|
|
176
|
+
const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
|
|
177
|
+
const fn = new Function(`"use strict"; return (${expr})`);
|
|
178
|
+
const result = fn();
|
|
179
|
+
chainActive = true;
|
|
180
|
+
if (result) {
|
|
181
|
+
chainRendered = true;
|
|
159
182
|
} else {
|
|
160
|
-
|
|
183
|
+
child.remove();
|
|
184
|
+
chainRendered = false;
|
|
161
185
|
}
|
|
162
|
-
|
|
163
|
-
|
|
186
|
+
child.removeAttribute("if");
|
|
187
|
+
} else if (hasDelIf) {
|
|
188
|
+
const raw = getDelIfAttr(child);
|
|
189
|
+
const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
|
|
190
|
+
const fn = new Function(`"use strict"; return (${expr})`);
|
|
191
|
+
const result = fn();
|
|
192
|
+
chainActive = true;
|
|
193
|
+
if (result) {
|
|
194
|
+
chainRendered = true;
|
|
195
|
+
} else {
|
|
196
|
+
child.remove();
|
|
197
|
+
chainRendered = false;
|
|
198
|
+
}
|
|
199
|
+
removeDelIfAttr(child);
|
|
200
|
+
} else if (hasElif) {
|
|
201
|
+
const raw = child.getAttribute("elif");
|
|
202
|
+
const expr = raw.startsWith("{") ? raw.slice(1, -1) : raw;
|
|
203
|
+
const fn = new Function(`"use strict"; return (${expr})`);
|
|
204
|
+
const result = fn();
|
|
205
|
+
if (result) {
|
|
206
|
+
chainRendered = true;
|
|
207
|
+
} else {
|
|
208
|
+
child.remove();
|
|
209
|
+
}
|
|
210
|
+
child.removeAttribute("elif");
|
|
211
|
+
} else if (hasElse) {
|
|
212
|
+
chainRendered = true;
|
|
213
|
+
chainActive = false;
|
|
214
|
+
child.removeAttribute("else");
|
|
215
|
+
} else {
|
|
216
|
+
chainActive = false;
|
|
217
|
+
chainRendered = false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (child.parentNode) {
|
|
221
|
+
processPageConditionals(child);
|
|
222
|
+
}
|
|
164
223
|
}
|
|
224
|
+
}
|
|
225
|
+
processPageConditionals(appContainer);
|
|
226
|
+
|
|
227
|
+
const appElements = getAppElements(appContainer);
|
|
228
|
+
const { runtimeScript, scopesCss } = processAllComponents(appElements, loadedComponents, pageSourcePath, srcIndexContent);
|
|
229
|
+
const runtimeFilename = await generateRuntimeScript(runtimeScript, paths.outDir);
|
|
230
|
+
const globalCss = (await processAssets(doc, rootDir, config.srcDir, paths.outDir)).join("\n");
|
|
231
|
+
|
|
232
|
+
if (scopesCss) {
|
|
233
|
+
const fileName = "sc-" + genRandomId(null, 6) + ".css";
|
|
234
|
+
await writeCSSOutput(scopesCss, paths.outDir, fileName);
|
|
235
|
+
appendStylesheetLink(doc, fileName);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
appendRuntimeScript(doc, runtimeFilename);
|
|
239
|
+
const html = await serializeDOM(dom);
|
|
240
|
+
await writeHTMLOutput(html, paths.outDir);
|
|
165
241
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
242
|
+
try {
|
|
243
|
+
if (config.assetImport === "static") {
|
|
244
|
+
await copyStaticDir(paths.src, paths.outDir);
|
|
245
|
+
} else {
|
|
246
|
+
await copyResources(rootDir, scopesCss, globalCss, config.srcDir, paths.outDir);
|
|
247
|
+
}
|
|
248
|
+
} catch (err) {
|
|
249
|
+
throwError(err.message || err);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
!isHotReload && logSuccess(paths.outDir);
|
|
253
|
+
isHotReload && console.log("Dev server updated");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* An intrinsic object that contains the Chocola App methods.
|
|
258
|
+
*/
|
|
259
|
+
export const app = {
|
|
260
|
+
/**
|
|
261
|
+
* Initializes your Chocola App using a root directory.
|
|
262
|
+
*
|
|
263
|
+
* ```js
|
|
264
|
+
* import { app } from "chocola/compiler"
|
|
265
|
+
import path from "path";
|
|
266
|
+
import { fileURLToPath } from "url";
|
|
267
|
+
|
|
268
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
269
|
+
const __dirname = path.dirname(__filename);
|
|
270
|
+
|
|
271
|
+
app.build(__dirname);
|
|
272
|
+
```
|
|
273
|
+
* @example
|
|
274
|
+
* @param {PathLike} __rootdir the directory where your Chocola App is
|
|
275
|
+
*/
|
|
276
|
+
build(__rootdir) { runtime(__rootdir) }
|
|
277
|
+
};
|
package/compiler/pipeline.js
CHANGED
|
@@ -70,32 +70,19 @@ export async function getComponents(libDir) {
|
|
|
70
70
|
*/
|
|
71
71
|
export async function getSrcIndex(srcPath) {
|
|
72
72
|
const srcHtmlPath = path.join(srcPath, "index.html");
|
|
73
|
-
const srcChocoPath = path.join(srcPath, "index.choco");
|
|
74
73
|
|
|
75
74
|
const htmlExists = await checkFile(srcHtmlPath);
|
|
76
|
-
const chocoExists = await checkFile(srcChocoPath);
|
|
77
75
|
|
|
78
76
|
let srcHtmlFile = null;
|
|
79
|
-
let srcChocoFile = null;
|
|
80
|
-
|
|
81
|
-
if (htmlExists && chocoExists) {
|
|
82
|
-
throwError(
|
|
83
|
-
"Can't have both .choco and .html source index files at a time: please remove one of the two"
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
77
|
|
|
87
78
|
if (htmlExists) {
|
|
88
79
|
try {
|
|
89
80
|
srcHtmlFile = await readMyFile(srcHtmlPath);
|
|
90
|
-
return { srcHtmlFile,
|
|
81
|
+
return { srcHtmlFile, srcPath: srcHtmlPath };
|
|
91
82
|
} catch (err) {
|
|
92
83
|
throwError(err);
|
|
93
84
|
}
|
|
94
85
|
}
|
|
95
|
-
|
|
96
|
-
if (chocoExists) {
|
|
97
|
-
throwError(".choco files are not supported yet");
|
|
98
|
-
}
|
|
99
86
|
}
|
|
100
87
|
|
|
101
88
|
/**
|
|
@@ -244,7 +231,7 @@ export async function copyResources(rootDir, scopesCss, globalCss, srcDir, outDi
|
|
|
244
231
|
`Failed to copy resource from inline style on <${el.tagName.toLowerCase()}> url("${filePath}")` +
|
|
245
232
|
(getComponentSource(el) ? ` in component "${getComponentSource(el)}"` : "") +
|
|
246
233
|
`: ${err.message || err}`
|
|
247
|
-
);
|
|
234
|
+
);
|
|
248
235
|
}
|
|
249
236
|
}
|
|
250
237
|
}
|
package/dev/index.js
CHANGED
|
@@ -152,4 +152,27 @@ export async function serve(__rootdir) {
|
|
|
152
152
|
server.listen(__config.port, __config.hostname, () => {
|
|
153
153
|
console.log(`Chocola App running at http://${__config.hostname}:${__config.port}/`);
|
|
154
154
|
});
|
|
155
|
-
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* An intrinsic object that contains the Chocola Dev methods.
|
|
159
|
+
*/
|
|
160
|
+
export const dev = {
|
|
161
|
+
/**
|
|
162
|
+
* Initializes your Chocola dev server using a root directory.
|
|
163
|
+
*
|
|
164
|
+
* ```js
|
|
165
|
+
* import { app } from "chocola/compiler"
|
|
166
|
+
import path from "path";
|
|
167
|
+
import { fileURLToPath } from "url";
|
|
168
|
+
|
|
169
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
170
|
+
const __dirname = path.dirname(__filename);
|
|
171
|
+
|
|
172
|
+
app.build(__dirname);
|
|
173
|
+
```
|
|
174
|
+
* @example
|
|
175
|
+
* @param {PathLike} __rootdir the directory where your Chocola App is
|
|
176
|
+
*/
|
|
177
|
+
server(__rootdir) { serve(__rootdir) }
|
|
178
|
+
};
|
package/index.js
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import compile from "./compiler/index.js";
|
|
2
|
-
import * as development from "./dev/index.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* An intrinsic object that contains the Chocola App methods.
|
|
6
|
-
*/
|
|
7
|
-
export const app = {
|
|
8
|
-
/**
|
|
9
|
-
* Initializes your Chocola App using a root directory and a source directory.
|
|
10
|
-
*
|
|
11
|
-
* ```js
|
|
12
|
-
* import { app } from "chocola"
|
|
13
|
-
import path from "path";
|
|
14
|
-
import { fileURLToPath } from "url";
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = path.dirname(__filename);
|
|
18
|
-
|
|
19
|
-
app.build(__dirname, "src");
|
|
20
|
-
```
|
|
21
|
-
* @example
|
|
22
|
-
* @param {PathLike} __rootdir the directory where your Chocola App is
|
|
23
|
-
* @param {PathLike} __srcdir the directory where your app sources files are
|
|
24
|
-
* @returns {Object}
|
|
25
|
-
*/
|
|
26
|
-
build(__rootdir, __srcdir) { compile(__rootdir, __srcdir) }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const dev = {
|
|
30
|
-
server(__rootdir, __srcdir, port) { development.serve(__rootdir, __srcdir, port) }
|
|
31
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chocola",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-next.1",
|
|
4
4
|
"description": "The sweetest way to build the web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
32
32
|
},
|
|
33
33
|
"exports": {
|
|
34
|
-
"
|
|
34
|
+
"./compiler": "./compiler/index.js",
|
|
35
|
+
"./dev": "./dev/index.js",
|
|
35
36
|
"./types": "./types/index.js"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
package/.gitattributes
DELETED