@mochi-css/next 3.0.1 → 4.0.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/dist/index.js +47 -3
- package/dist/index.mjs +47 -3
- package/dist/loader.js +8 -6
- package/dist/loader.mjs +8 -6
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -18,9 +18,11 @@ async function writeIfChanged(filePath, content) {
|
|
|
18
18
|
async function writeCssFiles(css, tmpDir) {
|
|
19
19
|
await fs.default.promises.mkdir(tmpDir, { recursive: true });
|
|
20
20
|
const existingCssFiles = new Set((await fs.default.promises.readdir(tmpDir)).filter((f) => f.endsWith(".css") && f !== "global.css").map((f) => path.default.resolve(tmpDir, f)));
|
|
21
|
+
const normalizedSourcemods = {};
|
|
22
|
+
for (const [source, mod] of Object.entries(css.sourcemods ?? {})) normalizedSourcemods[source.replaceAll("\\", "/")] = mod;
|
|
21
23
|
const diskManifest = {
|
|
22
24
|
files: {},
|
|
23
|
-
sourcemods:
|
|
25
|
+
sourcemods: Object.keys(normalizedSourcemods).length > 0 ? normalizedSourcemods : void 0
|
|
24
26
|
};
|
|
25
27
|
const writtenCssPaths = /* @__PURE__ */ new Set();
|
|
26
28
|
if (css.global) {
|
|
@@ -32,7 +34,7 @@ async function writeCssFiles(css, tmpDir) {
|
|
|
32
34
|
const hash = (0, __mochi_css_builder.fileHash)(source);
|
|
33
35
|
const cssPath = path.default.resolve(tmpDir, `${hash}.css`);
|
|
34
36
|
await writeIfChanged(cssPath, fileCss);
|
|
35
|
-
diskManifest.files[source] = cssPath;
|
|
37
|
+
diskManifest.files[source.replaceAll("\\", "/")] = cssPath;
|
|
36
38
|
writtenCssPaths.add(cssPath);
|
|
37
39
|
}
|
|
38
40
|
for (const existingPath of existingCssFiles) if (!writtenCssPaths.has(existingPath)) await fs.default.promises.unlink(existingPath);
|
|
@@ -47,6 +49,7 @@ let watcherStarted = false;
|
|
|
47
49
|
async function startCssWatcher(tmpDir) {
|
|
48
50
|
if (watcherStarted) return;
|
|
49
51
|
watcherStarted = true;
|
|
52
|
+
process["__mochiWatcherActive"] = true;
|
|
50
53
|
const cwd = process.cwd();
|
|
51
54
|
const resolved = await (0, __mochi_css_config.resolveConfig)(await (0, __mochi_css_config.loadConfig)(), void 0, {});
|
|
52
55
|
const effectiveTmpDir = resolved.tmpDir ? path.default.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
@@ -100,6 +103,39 @@ async function startCssWatcher(tmpDir) {
|
|
|
100
103
|
});
|
|
101
104
|
}
|
|
102
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Runs a single CSS build and writes the manifest to `tmpDir`.
|
|
108
|
+
* Used by `withMochi()` as a webpack `beforeRun` hook in production
|
|
109
|
+
* to ensure the manifest is populated before webpack processes any files.
|
|
110
|
+
*/
|
|
111
|
+
async function buildCssOnce(tmpDir) {
|
|
112
|
+
const cwd = process.cwd();
|
|
113
|
+
const resolved = await (0, __mochi_css_config.resolveConfig)(await (0, __mochi_css_config.loadConfig)(), void 0, {});
|
|
114
|
+
const effectiveTmpDir = resolved.tmpDir ? path.default.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
115
|
+
const absoluteRoots = resolved.roots.map((root) => typeof root === "string" ? path.default.resolve(cwd, root) : {
|
|
116
|
+
...root,
|
|
117
|
+
path: path.default.resolve(cwd, root.path)
|
|
118
|
+
});
|
|
119
|
+
if (absoluteRoots.length === 0) {
|
|
120
|
+
console.warn("[mochi-css] buildCssOnce: no roots configured — add `roots` to mochi.config.ts");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const context = new __mochi_css_config.FullContext(resolved.onDiagnostic ?? (() => {}));
|
|
124
|
+
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
125
|
+
await writeCssFiles(await new __mochi_css_builder.Builder({
|
|
126
|
+
roots: absoluteRoots,
|
|
127
|
+
stages: [...context.stages.getAll()],
|
|
128
|
+
bundler: new __mochi_css_builder.RolldownBundler(),
|
|
129
|
+
runner: new __mochi_css_builder.VmRunner(),
|
|
130
|
+
splitCss: resolved.splitCss,
|
|
131
|
+
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
132
|
+
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
133
|
+
emitHooks: [...context.emitHooks.getAll()],
|
|
134
|
+
cleanup: () => {
|
|
135
|
+
context.cleanup.runAll();
|
|
136
|
+
}
|
|
137
|
+
}).collectMochiCss(), effectiveTmpDir);
|
|
138
|
+
}
|
|
103
139
|
|
|
104
140
|
//#endregion
|
|
105
141
|
//#region src/index.ts
|
|
@@ -117,7 +153,8 @@ const MANIFEST_FILE = "manifest.json";
|
|
|
117
153
|
*/
|
|
118
154
|
function withMochi(nextConfig, opts) {
|
|
119
155
|
const manifestPath = opts?.manifestPath ?? path.default.resolve(MOCHI_DIR, MANIFEST_FILE);
|
|
120
|
-
|
|
156
|
+
const tmpDir = path.default.dirname(manifestPath);
|
|
157
|
+
if (process.env["NODE_ENV"] !== "production") startCssWatcher(tmpDir).catch((err) => {
|
|
121
158
|
console.error("[mochi-css] watcher error:", err instanceof Error ? err.message : err);
|
|
122
159
|
});
|
|
123
160
|
const loaderPath = require.resolve("@mochi-css/next/loader");
|
|
@@ -172,6 +209,13 @@ function withMochi(nextConfig, opts) {
|
|
|
172
209
|
mod.rules ??= [];
|
|
173
210
|
mod.rules.push(loaderRule);
|
|
174
211
|
} else result["module"] = { rules: [loaderRule] };
|
|
212
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
213
|
+
const plugins = result["plugins"] ?? [];
|
|
214
|
+
plugins.push({ apply(compiler) {
|
|
215
|
+
compiler.hooks.beforeRun.tapPromise("mochi-css", () => buildCssOnce(tmpDir));
|
|
216
|
+
} });
|
|
217
|
+
result["plugins"] = plugins;
|
|
218
|
+
}
|
|
175
219
|
return result;
|
|
176
220
|
}
|
|
177
221
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -18,9 +18,11 @@ async function writeIfChanged(filePath, content) {
|
|
|
18
18
|
async function writeCssFiles(css, tmpDir) {
|
|
19
19
|
await fs.promises.mkdir(tmpDir, { recursive: true });
|
|
20
20
|
const existingCssFiles = new Set((await fs.promises.readdir(tmpDir)).filter((f) => f.endsWith(".css") && f !== "global.css").map((f) => path.resolve(tmpDir, f)));
|
|
21
|
+
const normalizedSourcemods = {};
|
|
22
|
+
for (const [source, mod] of Object.entries(css.sourcemods ?? {})) normalizedSourcemods[source.replaceAll("\\", "/")] = mod;
|
|
21
23
|
const diskManifest = {
|
|
22
24
|
files: {},
|
|
23
|
-
sourcemods:
|
|
25
|
+
sourcemods: Object.keys(normalizedSourcemods).length > 0 ? normalizedSourcemods : void 0
|
|
24
26
|
};
|
|
25
27
|
const writtenCssPaths = /* @__PURE__ */ new Set();
|
|
26
28
|
if (css.global) {
|
|
@@ -32,7 +34,7 @@ async function writeCssFiles(css, tmpDir) {
|
|
|
32
34
|
const hash = fileHash(source);
|
|
33
35
|
const cssPath = path.resolve(tmpDir, `${hash}.css`);
|
|
34
36
|
await writeIfChanged(cssPath, fileCss);
|
|
35
|
-
diskManifest.files[source] = cssPath;
|
|
37
|
+
diskManifest.files[source.replaceAll("\\", "/")] = cssPath;
|
|
36
38
|
writtenCssPaths.add(cssPath);
|
|
37
39
|
}
|
|
38
40
|
for (const existingPath of existingCssFiles) if (!writtenCssPaths.has(existingPath)) await fs.promises.unlink(existingPath);
|
|
@@ -47,6 +49,7 @@ let watcherStarted = false;
|
|
|
47
49
|
async function startCssWatcher(tmpDir) {
|
|
48
50
|
if (watcherStarted) return;
|
|
49
51
|
watcherStarted = true;
|
|
52
|
+
process["__mochiWatcherActive"] = true;
|
|
50
53
|
const cwd = process.cwd();
|
|
51
54
|
const resolved = await resolveConfig(await loadConfig(), void 0, {});
|
|
52
55
|
const effectiveTmpDir = resolved.tmpDir ? path.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
@@ -100,6 +103,39 @@ async function startCssWatcher(tmpDir) {
|
|
|
100
103
|
});
|
|
101
104
|
}
|
|
102
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Runs a single CSS build and writes the manifest to `tmpDir`.
|
|
108
|
+
* Used by `withMochi()` as a webpack `beforeRun` hook in production
|
|
109
|
+
* to ensure the manifest is populated before webpack processes any files.
|
|
110
|
+
*/
|
|
111
|
+
async function buildCssOnce(tmpDir) {
|
|
112
|
+
const cwd = process.cwd();
|
|
113
|
+
const resolved = await resolveConfig(await loadConfig(), void 0, {});
|
|
114
|
+
const effectiveTmpDir = resolved.tmpDir ? path.resolve(cwd, resolved.tmpDir) : tmpDir;
|
|
115
|
+
const absoluteRoots = resolved.roots.map((root) => typeof root === "string" ? path.resolve(cwd, root) : {
|
|
116
|
+
...root,
|
|
117
|
+
path: path.resolve(cwd, root.path)
|
|
118
|
+
});
|
|
119
|
+
if (absoluteRoots.length === 0) {
|
|
120
|
+
console.warn("[mochi-css] buildCssOnce: no roots configured — add `roots` to mochi.config.ts");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const context = new FullContext(resolved.onDiagnostic ?? (() => {}));
|
|
124
|
+
for (const plugin of resolved.plugins) plugin.onLoad?.(context);
|
|
125
|
+
await writeCssFiles(await new Builder({
|
|
126
|
+
roots: absoluteRoots,
|
|
127
|
+
stages: [...context.stages.getAll()],
|
|
128
|
+
bundler: new RolldownBundler(),
|
|
129
|
+
runner: new VmRunner(),
|
|
130
|
+
splitCss: resolved.splitCss,
|
|
131
|
+
filePreProcess: ({ content, filePath }) => context.filePreProcess.transform(content, { filePath }),
|
|
132
|
+
sourceTransforms: [...context.sourceTransforms.getAll()],
|
|
133
|
+
emitHooks: [...context.emitHooks.getAll()],
|
|
134
|
+
cleanup: () => {
|
|
135
|
+
context.cleanup.runAll();
|
|
136
|
+
}
|
|
137
|
+
}).collectMochiCss(), effectiveTmpDir);
|
|
138
|
+
}
|
|
103
139
|
|
|
104
140
|
//#endregion
|
|
105
141
|
//#region src/index.ts
|
|
@@ -117,7 +153,8 @@ const MANIFEST_FILE = "manifest.json";
|
|
|
117
153
|
*/
|
|
118
154
|
function withMochi(nextConfig, opts) {
|
|
119
155
|
const manifestPath = opts?.manifestPath ?? path.resolve(MOCHI_DIR, MANIFEST_FILE);
|
|
120
|
-
|
|
156
|
+
const tmpDir = path.dirname(manifestPath);
|
|
157
|
+
if (process.env["NODE_ENV"] !== "production") startCssWatcher(tmpDir).catch((err) => {
|
|
121
158
|
console.error("[mochi-css] watcher error:", err instanceof Error ? err.message : err);
|
|
122
159
|
});
|
|
123
160
|
const loaderPath = __require.resolve("@mochi-css/next/loader");
|
|
@@ -172,6 +209,13 @@ function withMochi(nextConfig, opts) {
|
|
|
172
209
|
mod.rules ??= [];
|
|
173
210
|
mod.rules.push(loaderRule);
|
|
174
211
|
} else result["module"] = { rules: [loaderRule] };
|
|
212
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
213
|
+
const plugins = result["plugins"] ?? [];
|
|
214
|
+
plugins.push({ apply(compiler) {
|
|
215
|
+
compiler.hooks.beforeRun.tapPromise("mochi-css", () => buildCssOnce(tmpDir));
|
|
216
|
+
} });
|
|
217
|
+
result["plugins"] = plugins;
|
|
218
|
+
}
|
|
175
219
|
return result;
|
|
176
220
|
}
|
|
177
221
|
};
|
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
|
+
"version": "4.0.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@mochi-css/builder": "^4.0.0",
|
|
41
|
-
"@mochi-css/config": "^
|
|
41
|
+
"@mochi-css/config": "^4.0.0",
|
|
42
42
|
"diff": "^8.0.3"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|