Changes
4 changed files (+44/-59)
-
-
@@ -9,7 +9,8 @@ "name": "@pocka/rollup-plugin-gleam","version": "0.1.0", "license": "Apache-2.0", "dependencies": { "js-toml": "^1.0.0" "js-toml": "^1.0.0", "readdirp": "^4.0.2" }, "devDependencies": { "@rollup/plugin-typescript": "^12.1.1",
-
@@ -1101,6 +1102,19 @@ "source-map-js": "^1.2.1"}, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/readdirp": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "license": "MIT", "engines": { "node": ">= 14.16.0" }, "funding": { "type": "individual", "url": "https://paulmillr.com/funding/" } }, "node_modules/regenerator-runtime": {
-
-
-
@@ -35,7 +35,8 @@ "optional": true} }, "dependencies": { "js-toml": "^1.0.0" "js-toml": "^1.0.0", "readdirp": "^4.0.2" }, "devDependencies": { "@rollup/plugin-typescript": "^12.1.1",
-
-
-
@@ -10,6 +10,7 @@ import { promisify } from "node:util";import { fileURLToPath } from "node:url"; import * as toml from "js-toml"; import readdirp from "readdirp"; import type { Plugin } from "rollup"; interface GleamTOML {
-
@@ -116,64 +117,7 @@ }gleamToml = parsed; }, // FIXME: While Vite does trigger `watchChange`, it does not implement it correctly. // As a result, compile error crashes the process, which differs from what Rollup does. async watchChange(id, _change) { // Whenever indirectly imported .gleam file is changed, build the whole project. // Gleam compiler does the incremental compilation (we don't have a way to partially compile.) if (id.endsWith(".gleam")) { await buildProject(); return; } }, async transform(_code, id) { // Associate .mjs file generated by Gleam compiler to its source .gleam file. // This enables changing **imported** .gleam files to trigger rebuild. if (id.startsWith(jsOutDir) && id.endsWith(".mjs")) { if (!gleamToml) { this.warn( "Detected access to Gleam build artifacts without `gleam.toml` loaded.", ); return null; } if (id.endsWith("/gleam.mjs")) { // Skip if the file is Gleam runtime one (no corresponding .gleam file). return null; } if (!id.startsWith(path.resolve(jsOutDir, gleamToml.name))) { // Skip third-party packages, as users are not supposed to edit those source files directly. return null; } /** * Module namespace and module name. * * "build/dev/javascript/my_package/foo/bar.mjs" * -> "foo/bar" */ const modulePath = id // `+1` ... removing path separator .slice(path.resolve(jsOutDir, gleamToml.name).length + 1) .replace(/\.mjs$/, ""); /** * Gleam source code file that produces this .mjs file. * * "build/dev/javascript/my_package/foo/bar.mjs" * -> "src/foo/bar.gleam" */ const gleamSrc = path.resolve(srcDir, modulePath) + ".gleam"; if (!this.getWatchFiles().includes(gleamSrc)) { this.addWatchFile(gleamSrc); } // Do not touch code. Only important thing here is `addWatchFiles(gleamSrc)`. return null; } // .gleam files imported by non-Gleam modules (e.g. .js, .ts) run through this branch. // This branch triggers a build then returns proxy code that re-exports everything from // the generated .mjs file.
-
@@ -196,6 +140,29 @@ .replace(/\.gleam$/, ".mjs");const transpiledMjsPath = path.resolve(jsOutDir, gleamToml.name, modulePath); // Scan every .gleam files and watch them. This might be slow when the number // of files got large. However, manually watching comes with performance cost // too and it also brings management cost (properly closing watcher, reducing // the number of watch targets). Since this logic doesn't need file contents, // I believe the performance cost it brings is tolerable. for await (const entry of readdirp(srcDir)) { const resolved = path.resolve(srcDir, entry.path); if (!resolved.endsWith(".gleam")) { continue; } // The .gleam file pointed by `id` is already (or will be) in watched files. // Adding this results in duplicated watched file. if (resolved === id) { continue; } this.addWatchFile(resolved); } // Build after starting watching other .gleam files. // Otherwise fixing an error in another file does not trigger rebuild, which // leaves bundler stucked in an error state. await buildProject(); return {
-
-
-
@@ -48,6 +48,9 @@// Vite seems to have no way to test HMR/watch things from outside. // Unfortunately polling is the most reliable option. await vitest.waitFor(async () => { // We have to request a module that triggers transform, for some reasons... await server.transformRequest("/src/app.gleam"); const appMjsAfter = await server.transformRequest( "/build/dev/javascript/test_vite/app.mjs", );
-