Skip to content

Conversation

@moonglum
Copy link
Member

@moonglum moonglum commented Mar 8, 2025

Goals of this PR:

  • Make this plugin compatible with core v2 and v3 by vendoring FileFinder
  • Make it possible for -images to build on top of this

Breaking Change:

  • If we want to support ESM configurations, we need to rename this plugin as 'static' is a reserved word.
  • Revert the change to require 22, and instead require 20.19.0 as a minimum version once it is released

While doing it, two secondary goals emerged:

Copy link
Contributor

@FND FND left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good work - thank you!

Here's a first-pass review; mostly just FNDian details.

@moonglum
Copy link
Member Author

moonglum commented Mar 9, 2025

While transforming this module, I ran into a major problem 🙈 I think we need to rename this plugin 😅

If you do what we say on our homepage, it will not work:

export const static = [{                                                                                                                                              
    source: "./src",                                                                                                                                                    
    target: "./dist"                                                                                                                                                    
}];

This leads to this error:

export const static = [{
             ^^^^^^

SyntaxError: Unexpected strict mode reserved word

Turns out: Reserved words are not the best identifiers. I guess we need to deprecate faucet-pipeline-static and rename it to faucet-pipeline-files (or faucet-pipeline-copy): I implemented this in b8cbb64.

Sidenote:
As you can see, it fails on node 20 but works in 22 🙈 This is because the backport of require(ESM) will be released next week:
nodejs/node#57349

@moonglum
Copy link
Member Author

moonglum commented Mar 9, 2025

Okay, so I'm done with the contract now. This allows images to build on top of this pipeline. The exposed utility is a single function: buildProcessPipeline. It handles all the shenanigans of handling a directory of files as an input (leveraging FileFinder). It takes a function processFile that is specific to the pipeline and processes a single file. That function takes the filename, source, target, targetFolder and the assetManager. The function will also write the file. Why? Because in the case of images, for example, a single input file could produce multiple output files.

Looking forward to your feedback, @FND 🙇

@moonglum
Copy link
Member Author

moonglum commented Mar 9, 2025

Created the first version of images that uses the utils exported here:
faucet-pipeline/faucet-pipeline-images#77

* Improvements to FileFinder
* Doc improvement
* fileName => filename
* determineCompactors
* Inline processFiles
* Code organization
* Remove last `then`
* Inline isDotfile
import { readFile } from "node:fs/promises";
import * as path from "node:path";

export const key = "static";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FND Do you remember what this name is actually used for? I'm not sure it is used for plugins that are in the default list, only for the ones that are not:
https://github.com/faucet-pipeline/faucet-pipeline-core/blob/main/lib/plugins.js#L5

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused by this as well and haven't investigated it yet (or rather: I don't understand our implementation anymore without investing a fair amount of effort), but tests suggest that a plugin can override faucet-core's defaults. I'm not 100 % sure that interpretation is correct tough.

But yes, this value is most likely inert unless it differs from faucet-core's baked-in defaults. It still seems proper for plugins to be self-descriptive though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't really need this option for the plugins that are defined in core, but only for those that are not.

Copy link
Contributor

@FND FND left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is excellent work, thank you!

I only have a few more observations, most of it details or just generally sharing perspectives and expressing my own uncertainties. None of it seems worth blocking, so proceed on your own recognizance.

(I have to admit it's quite possible that the whole type stuff distracted me from actually reviewing the core functionality: While I've come to accept types as useful in some circumstances, as in this case, they also tend to make reviews much more onerous.)

import { readFile } from "node:fs/promises";
import * as path from "node:path";

export const key = "static";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused by this as well and haven't investigated it yet (or rather: I don't understand our implementation anymore without investing a fair amount of effort), but tests suggest that a plugin can override faucet-core's defaults. I'm not 100 % sure that interpretation is correct tough.

But yes, this value is most likely inert unless it differs from faucet-core's baked-in defaults. It still seems proper for plugins to be self-descriptive though.


export interface Filter {
(filename: string): boolean
}
Copy link
Contributor

@FND FND Mar 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I generally try to keep things local to the respective file, i.e. *.ts is a last resort for me.

In this case, I would have added the following to the bottom of util.js:

/** @typedef {{ skipDotfiles: boolean, filter?: Filter }} FileFinderOptions */

This not only reduces indirections (which can become quite taxing for the mind), it's also in line with deletability and means you need less expansive @import statements. In fact, I would argue that the need for multi-line @import is a potential smell.

That smell also suggests we might want to move FileFinder to a separate module (finder.js?) and break up types.ts into separate modules (e.g. util.types.ts and finder.types.ts) - that, too, comes down to deletability.

However, that's just me; YMMV.

tsconfig.json Outdated
"strict": true,
"allowImportingTsExtensions": true,
"lib": ["dom", "es2023"],
"module": "nodenext"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Are allowImportingTsExtensions and module necessary?

That's a genuine question: My JSDoc-typed projects exclusively use Deno for type checking, so I'm never entirely sure whether regular TypeScript works exactly the same way.

Relatedly, I've long been wondering whether TypeScript configuration should include isolatedModules and now erasableSyntaxOnly (though the latter should only be relevant for .ts source code anyway).

Basically, I'm perennially insecure about the non-obvious nuances of TypeScript configuration (module is a good example of that), so I obsessively try to reduce it to the bare minimum.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • allowImportingTsExtensions: If I remove it, TS fails 😅 From my understanding this is because we are importing ts files from the comments of JS files.
  • module option: Not adding it leads to the error Module '"node:path"' can only be default-imported using the 'esModuleInterop' flag
  • Activated the two options 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger, thanks. (That suggests using Deno for type checking is not a great idea because obscure abstractions vs. using the respective tool directly.)

@moonglum moonglum changed the title Dual core v2.2.0 Apr 23, 2025
@moonglum moonglum marked this pull request as ready for review April 23, 2025 09:20
@moonglum
Copy link
Member Author

I think the remaining question for static is, if it is worth it to keep the types around. As explained in the images PR, it doesn't really work for our setup :(

@moonglum moonglum requested a review from FND April 23, 2025 09:21
@moonglum
Copy link
Member Author

I want to close this in favor of faucet-pipeline-assets, @FND. I do not plan to update faucet-pipeline-static for core 3.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants