@mochi-css/next 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +53 -21
- package/dist/index.mjs +54 -22
- package/dist/loader.js +8 -6
- package/dist/loader.mjs +8 -6
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -38,6 +38,30 @@ async function writeCssFiles(css, tmpDir) {
|
|
|
38
38
|
for (const existingPath of existingCssFiles) if (!writtenCssPaths.has(existingPath)) await fs.default.promises.unlink(existingPath);
|
|
39
39
|
await writeIfChanged(path.default.resolve(tmpDir, "manifest.json"), JSON.stringify(diskManifest));
|
|
40
40
|
}
|
|
41
|
+
function resolveAbsoluteRoots(cwd, roots) {
|
|
42
|
+
const posixCwd = __mochi_css_builder.path.fromSystemPath(cwd);
|
|
43
|
+
return roots.map((root) => typeof root === "string" ? __mochi_css_builder.path.resolve(posixCwd, root) : {
|
|
44
|
+
...root,
|
|
45
|
+
path: __mochi_css_builder.path.resolve(posixCwd, root.path)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function createBuilder(resolved, roots) {
|
|
49
|
+
const context = new __mochi_css_config.FullContext(resolved.onDiagnostic ?? (() => {}));
|
|
50
|
+
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
51
|
+
return new __mochi_css_builder.Builder({
|
|
52
|
+
roots,
|
|
53
|
+
stages: [...context.stages.getAll()],
|
|
54
|
+
bundler: new __mochi_css_builder.RolldownBundler(),
|
|
55
|
+
runner: new __mochi_css_builder.VmRunner(),
|
|
56
|
+
splitCss: resolved.splitCss,
|
|
57
|
+
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
58
|
+
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
59
|
+
emitHooks: [...context.emitHooks.getAll()],
|
|
60
|
+
cleanup: () => {
|
|
61
|
+
context.cleanup.runAll();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
41
65
|
let watcherStarted = false;
|
|
42
66
|
/**
|
|
43
67
|
* Sets up a file watcher that rebuilds Mochi CSS whenever source files change.
|
|
@@ -47,34 +71,18 @@ let watcherStarted = false;
|
|
|
47
71
|
async function startCssWatcher(tmpDir) {
|
|
48
72
|
if (watcherStarted) return;
|
|
49
73
|
watcherStarted = true;
|
|
74
|
+
process["__mochiWatcherActive"] = true;
|
|
50
75
|
const cwd = process.cwd();
|
|
51
76
|
const resolved = await (0, __mochi_css_config.resolveConfig)(await (0, __mochi_css_config.loadConfig)(), void 0, {});
|
|
52
77
|
const effectiveTmpDir = resolved.tmpDir ? path.default.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
53
78
|
const debug = resolved.debug ?? false;
|
|
54
|
-
const absoluteRoots =
|
|
55
|
-
...root,
|
|
56
|
-
path: path.default.resolve(cwd, root.path)
|
|
57
|
-
});
|
|
79
|
+
const absoluteRoots = resolveAbsoluteRoots(cwd, resolved.roots);
|
|
58
80
|
if (debug) console.log(`[mochi-css] watcher: roots=${JSON.stringify(absoluteRoots)}, tmpDir=${effectiveTmpDir}`);
|
|
59
81
|
if (absoluteRoots.length === 0) {
|
|
60
82
|
console.warn("[mochi-css] watcher: no roots configured — add `roots` to mochi.config.ts");
|
|
61
83
|
return;
|
|
62
84
|
}
|
|
63
|
-
const
|
|
64
|
-
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
65
|
-
const builder = new __mochi_css_builder.Builder({
|
|
66
|
-
roots: absoluteRoots,
|
|
67
|
-
stages: [...context.stages.getAll()],
|
|
68
|
-
bundler: new __mochi_css_builder.RolldownBundler(),
|
|
69
|
-
runner: new __mochi_css_builder.VmRunner(),
|
|
70
|
-
splitCss: resolved.splitCss,
|
|
71
|
-
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
72
|
-
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
73
|
-
emitHooks: [...context.emitHooks.getAll()],
|
|
74
|
-
cleanup: () => {
|
|
75
|
-
context.cleanup.runAll();
|
|
76
|
-
}
|
|
77
|
-
});
|
|
85
|
+
const builder = createBuilder(resolved, absoluteRoots);
|
|
78
86
|
let rebuildTimer;
|
|
79
87
|
let rebuildGuard = Promise.resolve();
|
|
80
88
|
const scheduleRebuild = () => {
|
|
@@ -88,7 +96,7 @@ async function startCssWatcher(tmpDir) {
|
|
|
88
96
|
}, 50);
|
|
89
97
|
};
|
|
90
98
|
scheduleRebuild();
|
|
91
|
-
const rootDirs = absoluteRoots.map((root) => typeof root === "string" ? root : root.path);
|
|
99
|
+
const rootDirs = absoluteRoots.map((root) => __mochi_css_builder.path.toSystemPath(typeof root === "string" ? root : root.path));
|
|
92
100
|
for (const dir of rootDirs) {
|
|
93
101
|
if (!fs.default.existsSync(dir)) {
|
|
94
102
|
console.warn(`[mochi-css] watcher: root not found: ${dir}`);
|
|
@@ -100,6 +108,22 @@ async function startCssWatcher(tmpDir) {
|
|
|
100
108
|
});
|
|
101
109
|
}
|
|
102
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Runs a single CSS build and writes the manifest to `tmpDir`.
|
|
113
|
+
* Used by `withMochi()` as a webpack `beforeRun` hook in production
|
|
114
|
+
* to ensure the manifest is populated before webpack processes any files.
|
|
115
|
+
*/
|
|
116
|
+
async function buildCssOnce(tmpDir) {
|
|
117
|
+
const cwd = process.cwd();
|
|
118
|
+
const resolved = await (0, __mochi_css_config.resolveConfig)(await (0, __mochi_css_config.loadConfig)(), void 0, {});
|
|
119
|
+
const effectiveTmpDir = resolved.tmpDir ? path.default.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
120
|
+
const absoluteRoots = resolveAbsoluteRoots(cwd, resolved.roots);
|
|
121
|
+
if (absoluteRoots.length === 0) {
|
|
122
|
+
console.warn("[mochi-css] buildCssOnce: no roots configured — add `roots` to mochi.config.ts");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
await writeCssFiles(await createBuilder(resolved, absoluteRoots).collectMochiCss(), effectiveTmpDir);
|
|
126
|
+
}
|
|
103
127
|
|
|
104
128
|
//#endregion
|
|
105
129
|
//#region src/index.ts
|
|
@@ -117,7 +141,8 @@ const MANIFEST_FILE = "manifest.json";
|
|
|
117
141
|
*/
|
|
118
142
|
function withMochi(nextConfig, opts) {
|
|
119
143
|
const manifestPath = opts?.manifestPath ?? path.default.resolve(MOCHI_DIR, MANIFEST_FILE);
|
|
120
|
-
|
|
144
|
+
const tmpDir = path.default.dirname(manifestPath);
|
|
145
|
+
if (process.env["NODE_ENV"] !== "production") startCssWatcher(tmpDir).catch((err) => {
|
|
121
146
|
console.error("[mochi-css] watcher error:", err instanceof Error ? err.message : err);
|
|
122
147
|
});
|
|
123
148
|
const loaderPath = require.resolve("@mochi-css/next/loader");
|
|
@@ -172,6 +197,13 @@ function withMochi(nextConfig, opts) {
|
|
|
172
197
|
mod.rules ??= [];
|
|
173
198
|
mod.rules.push(loaderRule);
|
|
174
199
|
} else result["module"] = { rules: [loaderRule] };
|
|
200
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
201
|
+
const plugins = result["plugins"] ?? [];
|
|
202
|
+
plugins.push({ apply(compiler) {
|
|
203
|
+
compiler.hooks.beforeRun.tapPromise("mochi-css", () => buildCssOnce(tmpDir));
|
|
204
|
+
} });
|
|
205
|
+
result["plugins"] = plugins;
|
|
206
|
+
}
|
|
175
207
|
return result;
|
|
176
208
|
}
|
|
177
209
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import { FullContext, loadConfig, resolveConfig } from "@mochi-css/config";
|
|
5
|
-
import { Builder, RolldownBundler, VmRunner, fileHash } from "@mochi-css/builder";
|
|
5
|
+
import { Builder, RolldownBundler, VmRunner, fileHash, path as path$1 } from "@mochi-css/builder";
|
|
6
6
|
|
|
7
7
|
//#region rolldown:runtime
|
|
8
8
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
@@ -38,6 +38,30 @@ async function writeCssFiles(css, tmpDir) {
|
|
|
38
38
|
for (const existingPath of existingCssFiles) if (!writtenCssPaths.has(existingPath)) await fs.promises.unlink(existingPath);
|
|
39
39
|
await writeIfChanged(path.resolve(tmpDir, "manifest.json"), JSON.stringify(diskManifest));
|
|
40
40
|
}
|
|
41
|
+
function resolveAbsoluteRoots(cwd, roots) {
|
|
42
|
+
const posixCwd = path$1.fromSystemPath(cwd);
|
|
43
|
+
return roots.map((root) => typeof root === "string" ? path$1.resolve(posixCwd, root) : {
|
|
44
|
+
...root,
|
|
45
|
+
path: path$1.resolve(posixCwd, root.path)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function createBuilder(resolved, roots) {
|
|
49
|
+
const context = new FullContext(resolved.onDiagnostic ?? (() => {}));
|
|
50
|
+
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
51
|
+
return new Builder({
|
|
52
|
+
roots,
|
|
53
|
+
stages: [...context.stages.getAll()],
|
|
54
|
+
bundler: new RolldownBundler(),
|
|
55
|
+
runner: new VmRunner(),
|
|
56
|
+
splitCss: resolved.splitCss,
|
|
57
|
+
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
58
|
+
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
59
|
+
emitHooks: [...context.emitHooks.getAll()],
|
|
60
|
+
cleanup: () => {
|
|
61
|
+
context.cleanup.runAll();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
41
65
|
let watcherStarted = false;
|
|
42
66
|
/**
|
|
43
67
|
* Sets up a file watcher that rebuilds Mochi CSS whenever source files change.
|
|
@@ -47,34 +71,18 @@ let watcherStarted = false;
|
|
|
47
71
|
async function startCssWatcher(tmpDir) {
|
|
48
72
|
if (watcherStarted) return;
|
|
49
73
|
watcherStarted = true;
|
|
74
|
+
process["__mochiWatcherActive"] = true;
|
|
50
75
|
const cwd = process.cwd();
|
|
51
76
|
const resolved = await resolveConfig(await loadConfig(), void 0, {});
|
|
52
77
|
const effectiveTmpDir = resolved.tmpDir ? path.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
53
78
|
const debug = resolved.debug ?? false;
|
|
54
|
-
const absoluteRoots =
|
|
55
|
-
...root,
|
|
56
|
-
path: path.resolve(cwd, root.path)
|
|
57
|
-
});
|
|
79
|
+
const absoluteRoots = resolveAbsoluteRoots(cwd, resolved.roots);
|
|
58
80
|
if (debug) console.log(`[mochi-css] watcher: roots=${JSON.stringify(absoluteRoots)}, tmpDir=${effectiveTmpDir}`);
|
|
59
81
|
if (absoluteRoots.length === 0) {
|
|
60
82
|
console.warn("[mochi-css] watcher: no roots configured — add `roots` to mochi.config.ts");
|
|
61
83
|
return;
|
|
62
84
|
}
|
|
63
|
-
const
|
|
64
|
-
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
65
|
-
const builder = new Builder({
|
|
66
|
-
roots: absoluteRoots,
|
|
67
|
-
stages: [...context.stages.getAll()],
|
|
68
|
-
bundler: new RolldownBundler(),
|
|
69
|
-
runner: new VmRunner(),
|
|
70
|
-
splitCss: resolved.splitCss,
|
|
71
|
-
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
72
|
-
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
73
|
-
emitHooks: [...context.emitHooks.getAll()],
|
|
74
|
-
cleanup: () => {
|
|
75
|
-
context.cleanup.runAll();
|
|
76
|
-
}
|
|
77
|
-
});
|
|
85
|
+
const builder = createBuilder(resolved, absoluteRoots);
|
|
78
86
|
let rebuildTimer;
|
|
79
87
|
let rebuildGuard = Promise.resolve();
|
|
80
88
|
const scheduleRebuild = () => {
|
|
@@ -88,7 +96,7 @@ async function startCssWatcher(tmpDir) {
|
|
|
88
96
|
}, 50);
|
|
89
97
|
};
|
|
90
98
|
scheduleRebuild();
|
|
91
|
-
const rootDirs = absoluteRoots.map((root) => typeof root === "string" ? root : root.path);
|
|
99
|
+
const rootDirs = absoluteRoots.map((root) => path$1.toSystemPath(typeof root === "string" ? root : root.path));
|
|
92
100
|
for (const dir of rootDirs) {
|
|
93
101
|
if (!fs.existsSync(dir)) {
|
|
94
102
|
console.warn(`[mochi-css] watcher: root not found: ${dir}`);
|
|
@@ -100,6 +108,22 @@ async function startCssWatcher(tmpDir) {
|
|
|
100
108
|
});
|
|
101
109
|
}
|
|
102
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Runs a single CSS build and writes the manifest to `tmpDir`.
|
|
113
|
+
* Used by `withMochi()` as a webpack `beforeRun` hook in production
|
|
114
|
+
* to ensure the manifest is populated before webpack processes any files.
|
|
115
|
+
*/
|
|
116
|
+
async function buildCssOnce(tmpDir) {
|
|
117
|
+
const cwd = process.cwd();
|
|
118
|
+
const resolved = await resolveConfig(await loadConfig(), void 0, {});
|
|
119
|
+
const effectiveTmpDir = resolved.tmpDir ? path.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
120
|
+
const absoluteRoots = resolveAbsoluteRoots(cwd, resolved.roots);
|
|
121
|
+
if (absoluteRoots.length === 0) {
|
|
122
|
+
console.warn("[mochi-css] buildCssOnce: no roots configured — add `roots` to mochi.config.ts");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
await writeCssFiles(await createBuilder(resolved, absoluteRoots).collectMochiCss(), effectiveTmpDir);
|
|
126
|
+
}
|
|
103
127
|
|
|
104
128
|
//#endregion
|
|
105
129
|
//#region src/index.ts
|
|
@@ -117,7 +141,8 @@ const MANIFEST_FILE = "manifest.json";
|
|
|
117
141
|
*/
|
|
118
142
|
function withMochi(nextConfig, opts) {
|
|
119
143
|
const manifestPath = opts?.manifestPath ?? path.resolve(MOCHI_DIR, MANIFEST_FILE);
|
|
120
|
-
|
|
144
|
+
const tmpDir = path.dirname(manifestPath);
|
|
145
|
+
if (process.env["NODE_ENV"] !== "production") startCssWatcher(tmpDir).catch((err) => {
|
|
121
146
|
console.error("[mochi-css] watcher error:", err instanceof Error ? err.message : err);
|
|
122
147
|
});
|
|
123
148
|
const loaderPath = __require.resolve("@mochi-css/next/loader");
|
|
@@ -172,6 +197,13 @@ function withMochi(nextConfig, opts) {
|
|
|
172
197
|
mod.rules ??= [];
|
|
173
198
|
mod.rules.push(loaderRule);
|
|
174
199
|
} else result["module"] = { rules: [loaderRule] };
|
|
200
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
201
|
+
const plugins = result["plugins"] ?? [];
|
|
202
|
+
plugins.push({ apply(compiler) {
|
|
203
|
+
compiler.hooks.beforeRun.tapPromise("mochi-css", () => buildCssOnce(tmpDir));
|
|
204
|
+
} });
|
|
205
|
+
result["plugins"] = plugins;
|
|
206
|
+
}
|
|
175
207
|
return result;
|
|
176
208
|
}
|
|
177
209
|
};
|
package/dist/loader.js
CHANGED
|
@@ -21,8 +21,6 @@ function readManifest(manifestPath) {
|
|
|
21
21
|
return manifest;
|
|
22
22
|
}
|
|
23
23
|
function injectImports(ctx, manifest, source) {
|
|
24
|
-
const cssPath = manifest.files[ctx.resourcePath];
|
|
25
|
-
if (!cssPath) return source;
|
|
26
24
|
const imports = [];
|
|
27
25
|
const sourceDir = path.default.dirname(ctx.resourcePath);
|
|
28
26
|
function toImportPath(absPath) {
|
|
@@ -30,14 +28,18 @@ function injectImports(ctx, manifest, source) {
|
|
|
30
28
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
31
29
|
return rel;
|
|
32
30
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const cssPath = manifest.files[ctx.resourcePath.replaceAll("\\", "/")];
|
|
32
|
+
if (cssPath) {
|
|
33
|
+
const absoluteCssPath = path.default.resolve(cssPath);
|
|
34
|
+
imports.push(`import ${JSON.stringify(toImportPath(absoluteCssPath))};`);
|
|
35
|
+
ctx.addDependency(absoluteCssPath);
|
|
36
|
+
}
|
|
36
37
|
if (manifest.global) {
|
|
37
38
|
const absoluteGlobalPath = path.default.resolve(manifest.global);
|
|
38
39
|
imports.push(`import ${JSON.stringify(toImportPath(absoluteGlobalPath))};`);
|
|
39
40
|
ctx.addDependency(absoluteGlobalPath);
|
|
40
41
|
}
|
|
42
|
+
if (imports.length === 0) return source;
|
|
41
43
|
return imports.join("\n") + "\n" + source;
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
@@ -56,7 +58,7 @@ function mochiLoader(source) {
|
|
|
56
58
|
callback(null, source);
|
|
57
59
|
return;
|
|
58
60
|
}
|
|
59
|
-
const sourcemod = manifest.sourcemods?.[resourcePath];
|
|
61
|
+
const sourcemod = manifest.sourcemods?.[resourcePath.replaceAll("\\", "/")];
|
|
60
62
|
const transformed = sourcemod ? (0, diff.applyPatch)(source, sourcemod) || source : source;
|
|
61
63
|
callback(null, injectImports(this, manifest, transformed));
|
|
62
64
|
} catch (err) {
|
package/dist/loader.mjs
CHANGED
|
@@ -17,8 +17,6 @@ function readManifest(manifestPath) {
|
|
|
17
17
|
return manifest;
|
|
18
18
|
}
|
|
19
19
|
function injectImports(ctx, manifest, source) {
|
|
20
|
-
const cssPath = manifest.files[ctx.resourcePath];
|
|
21
|
-
if (!cssPath) return source;
|
|
22
20
|
const imports = [];
|
|
23
21
|
const sourceDir = path.dirname(ctx.resourcePath);
|
|
24
22
|
function toImportPath(absPath) {
|
|
@@ -26,14 +24,18 @@ function injectImports(ctx, manifest, source) {
|
|
|
26
24
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
27
25
|
return rel;
|
|
28
26
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
const cssPath = manifest.files[ctx.resourcePath.replaceAll("\\", "/")];
|
|
28
|
+
if (cssPath) {
|
|
29
|
+
const absoluteCssPath = path.resolve(cssPath);
|
|
30
|
+
imports.push(`import ${JSON.stringify(toImportPath(absoluteCssPath))};`);
|
|
31
|
+
ctx.addDependency(absoluteCssPath);
|
|
32
|
+
}
|
|
32
33
|
if (manifest.global) {
|
|
33
34
|
const absoluteGlobalPath = path.resolve(manifest.global);
|
|
34
35
|
imports.push(`import ${JSON.stringify(toImportPath(absoluteGlobalPath))};`);
|
|
35
36
|
ctx.addDependency(absoluteGlobalPath);
|
|
36
37
|
}
|
|
38
|
+
if (imports.length === 0) return source;
|
|
37
39
|
return imports.join("\n") + "\n" + source;
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
@@ -52,7 +54,7 @@ function mochiLoader(source) {
|
|
|
52
54
|
callback(null, source);
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
|
-
const sourcemod = manifest.sourcemods?.[resourcePath];
|
|
57
|
+
const sourcemod = manifest.sourcemods?.[resourcePath.replaceAll("\\", "/")];
|
|
56
58
|
const transformed = sourcemod ? applyPatch(source, sourcemod) || source : source;
|
|
57
59
|
callback(null, injectImports(this, manifest, transformed));
|
|
58
60
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mochi-css/next",
|
|
3
3
|
"repository": "git@github.com:Niikelion/mochi-css.git",
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"coverage": "vitest run --coverage"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@mochi-css/builder": "^4.0.
|
|
40
|
+
"@mochi-css/builder": "^4.0.1",
|
|
41
41
|
"@mochi-css/config": "^4.0.0",
|
|
42
42
|
"diff": "^8.0.3"
|
|
43
43
|
},
|