Skip to content

Separate the (Python) server from the frontend in the source tree #1952

Description

@justvanrossum

This is with @simoncozens: to clean up the Fontra source tree, and clearly separate the Python server source code from the front end code and assets, with the purpose of opening up more deployment options for Fontra, such as a serverless version.

Possible breakage that we must keep in mind

  • Fontra Pak
  • Fontra RCJK deployment

Steps:

  • Rework URL scheme so the "project identifier" becomes a query key/value #1960
  • Move script imports and inline JS in HTML files into view-specific start.js files (Move JS code from HTML to start.js #1984)
  • Add scaffolding which does not interact with existing development (new webpack.config.js, package subdirectory structure, etc.) (JS package scaffolding #1985)
  • Rename bundle-rollup to build in package.json, make build hook similarly generically named (Make bundler actions generically named #1983)
  • Update Node requirement to >=20, in mention in README.md, set GH Actions workflow Node to 20.x (or latest?)
    • Make test-js/test-classes.js use "with", now that we require Node >=20
  • Update README.md:
    • Build instructions for deployment
    • Build/watch instructions for development cycle
  • Update .gitignore to ignore src/fontra/client/
  • A check that we have Node >=20, rather than confusing syntax error with npm test
  • Implement solution for fontra-rcjk's project manager (does it need its own little big-bang?)
  • Commit correct package-lock.json
  • Schedule a big-bang migration of JS files into packages plus server modifications

(To be edited...)

Activity

  1. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    OK, I think I am getting close to this. Everything is working nicely locally; you can test my js-split branch.

    To answer the remaining question about JS tracebacks, I've added two build modes - when Fontra is installed with pip install ., it runs npm run bundle which runs webpack in production mode. This gives you minified JS and tracebacks like start.1a2b3c.js:17839. When you run in development mode (npm run bundle-watch), then you get sourcemaps, sensible backtraces, and original JS code in the developer tools console. There are apparently many options between those two extremes if we want to tweak things.

    FontraPak works with a small change to the fontoverview URL.

    I think I need to check that other projectmanager implementations also work.

  2. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    Oh... and the renaming of JavaScript imports is now scripted, so we can quickly recreate the "big-bang" commit whenever we decide to do it.

  3. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    the renaming of JavaScript imports is now scripted

    Do you mean the "making all JS imports consistent as well as working in the new environment"?

  4. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    Right. Once the JS scripts are moved into their new src-js/ locations, this script can be used to make the imports consistent and to use absolute package names (@fontra/core/... etc.).

  5. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    Lovely.

  6. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    If I start the server in the js-split branch:

    python -Wall -m fontra filesystem path/to/folder/with/fonts/
    

    ...and go to http://localhost:8000/, the server errors:

    FileNotFoundError: [Errno 2] No such file or directory: '/Users/just/code/git/BlackFoundry/fontra/src/fontra/client/landing.html
    

    I did pip install -e . before I launched the server. Is there something I missed to do on my end?

  7. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    I'll try it from a clean checkout but it feels like the npm run bundle step didn't put anything into src/fontra/client.

  8. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    src/fontra/client is populated, and Fontra Pak (with fontoverview/ -> fontoverview.html change) actually works (awesome!), so it seems to be isolated to the landing stuff?

  9. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    npm test does not work, though:

    $ npm test
    
    > test
    > mocha tests --reporter spec
    
    Error: No test files found: "tests"
    
  10. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    Nope, I haven't done that bit yet. (I did it in the first PoC, I'll bring that change over.)

  11. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    src/fontra/client is populated, and Fontra Pak (with fontoverview/ -> fontoverview.html change) actually works (awesome!), so it seems to be isolated to the landing stuff?

    Yeah, I'd forgotten a package.json file for the filesystem projectmanager. Added now.

  12. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    That works, great!

  13. justvanrossum commented on Jan 24, 2025

    @justvanrossum
    MemberAuthor

    The RCJK project manager isn't working, but it sounds like it isn't expected to be yet. I do see some login fields, but the CSS is missing so the layout is all garbled. I'll send you an email with a private server location so you can test.

  14. simoncozens commented on Jan 24, 2025

    @simoncozens
    Contributor

    Thank you. I've just done a new (force) push and tests are working.

  15. simoncozens commented on Jan 27, 2025

    @simoncozens
    Contributor

    I think I need to think a bit more deeply about how to make pluggable project managers like fontra-rcjk work. They need to ship their own HTML/JS assets, but we can't expect them to be bundled into the fontra.client package; so they probably need to do their own bundling. But at the same time they have to be able to access JS API stuff in @fontra/core.

  16. 9 remaining items

  17. justvanrossum commented on Jan 31, 2025

    @justvanrossum
    MemberAuthor

    That works! Thanks.

    If I look into fontra-rcjk's package-lock.json files, I see entries like this:

        "node_modules/@fontra/core": {
          "version": "0.0.1",
          "resolved": "https://gitpkg.vercel.app/simoncozens/fontra/src-js/fontra-core?js-split",
          "integrity": "sha512-z6MSlkveHndgmlxceVm8e5cDoc52aXyNA6PN1jBcOAURUMetgPp6W/cGXhbXFHlZ6rHn9r5cR3yb8cjMrKPf7A==",
          "dependencies": {
            "@fontra/core": "file:",
            "bezier-js": "^6.1.4",
            "fflate": "^0.8.2",
            "lib-font": "^2.4.3",
            "tsc": "^2.0.4"
          }
        },

    Can you elaborate a bit on how this works and why it needs to refer to an external fontra-core?

  18. simoncozens commented on Jan 31, 2025

    @simoncozens
    Contributor

    Currently fontra-rcjk does this:

    import { parseCookies } from "/core/utils.js";
    import { startupLandingPage } from "/filesystem/landing.js";
    

    assuming that it will be able to find those individual JS files in the server's deployment directory. This is no longer true in the new model, because (a) core/utils.js may not be at the server root, and (b) bundling.

    Post-change, fontra-cjk will do this:

    import { parseCookies } from "@fontra/core/utils.js";
    import { startupLandingPage } from "@fontra/projectmanager-filesystem/landing.js";
    

    That is, it will import these two functions from JS dependencies, and the code for these two functions will be bundled into the single JS file which makes up @fontra/projectmanager-rcjk. So the idea is that @fontra/core and @fontra/projectmanager-filesystem (etc.) become "ordinary" Javascript packages, which means they get added as dependencies to the @fontra/projectmanager-rcjk package which can then use their functionality.

    For that to happen, @fontra/core and friends need to be hosted somewhere that npm install can get them. Eventually they may become plain npmjs.com packages; or they may get their own independent repositories - or they may stay where they are and get served from GitHub subdirectories. For the proof-of-concept, I'm serving them as npm modules inside a GitHub subdirectory, and gitpkg.vercel.com is currently the best way to do that.

  19. justvanrossum commented on Jan 31, 2025

    @justvanrossum
    MemberAuthor

    Understood, so these would ultimately point to our own repos via the gitpkg.vercel.com tool.

    Does this also imply that in the fontra-views-features demo, all needed bits of fontra/core will be bundled for that view, and not be shared with the builtin views? (Assuming fontra/core is at least shared among builtin views)

  20. simoncozens commented on Jan 31, 2025

    @simoncozens
    Contributor

    It does, yes. Once I have a useful demo plugin we can see how much of @fontra/core is actually used and how much that adds to the JS, but in a way it's irrelevant; if we're going with this approach, that's the price of entry.

  21. justvanrossum commented on Jan 31, 2025

    @justvanrossum
    MemberAuthor

    Is it the same for builtin views, as in, are they each bundled individually?

  22. simoncozens commented on Jan 31, 2025

    @simoncozens
    Contributor

    Yes and no; webpack can be configured to split out common code. I haven't played with the different ways to optimise this yet.

  23. simoncozens commented on Jan 31, 2025

    @simoncozens
    Contributor

    I have now played with this, and we really can save whatever chunks we like - all the node_modules code in one file, or separate files per module, or all the fontra code in one file, or separate, or whatever. An absolutely minimal strategy would bundle everything into a single shared fontra.js and have start.js files per view:

    936K	src/fontra/client/fontra.42214453495ccb6be1cb.js
    4.0K	src/fontra/client/landing.d241fa29fae71d17c6b5.js
     12K	src/fontra/client/start.1.2990ddbb954cd4f579b9.js
     12K	src/fontra/client/start.2.0563f2d1b27f7c3ccf10.js
     12K	src/fontra/client/start.3.ddc68521d2c65abcb40a.js
    4.0K	src/fontra/client/start.b6cadb84a938fb042a43.js
    

    Or we can configure it to do essentially what we have right now:

    408K	src/fontra/client/fontra-core.c0048cffdc78fdd0ff85.js
     80K	src/fontra/client/fontra-webcomponents.a3aa8cc120bdcc2093a5.js
    4.0K	src/fontra/client/landing.73d0884b25a7361863be.js
     24K	src/fontra/client/npm.bezier-js.73670c411a8fe613569a.js
     12K	src/fontra/client/npm.fflate.cceee27831537519ed53.js
     68K	src/fontra/client/npm.lib-font.e5b84eee0ebdbd281895.js
     12K	src/fontra/client/start.1.057ee13d4324786d95e5.js
     12K	src/fontra/client/start.2.adcc93048ec82893a629.js
     12K	src/fontra/client/start.3.edf99d18e2131f545b5e.js
    4.0K	src/fontra/client/start.f5838803d9fc8821c52e.js
     16K	src/fontra/client/views-applicationsettings.772c9f4c138f93e6c2eb.js
    268K	src/fontra/client/views-editor.eb5ec121d0e084c9d8b3.js
     48K	src/fontra/client/views-fontinfo.2d2d2f1d4d5a58a960f8.js
     24K	src/fontra/client/views-fontoverview.bada1fdd6c8943263707.js
    

    It's all tweakable.

  24. justvanrossum commented on Feb 5, 2025

    @justvanrossum
    MemberAuthor

    Is there a way to (temporarily) npm install from a local npm package? Roughly equivalent to pip install path/to/package? I assume this would mess with package-lock.json, but it may be useful for debugging.

    (Running "npm run bundle-watch" for the first time: that works really well, including tracebacks in the console / dev tools.)

  25. simoncozens commented on Feb 5, 2025

    @simoncozens
    Contributor

    npm install <directory> works fine.

  26. simoncozens commented on Feb 5, 2025

    @simoncozens
    Contributor

    I've just rebased both js-scaffolding and js-split branches and finished off the remaining todo items.

  27. justvanrossum commented on Feb 6, 2025

    @justvanrossum
    MemberAuthor

    Am I right that the next steps would be:

    ?

    Or are there things on your end that still need work?

    I would love to time it in such a way that we are both (at least somewhat) available in the days after to respond to problems we might have overlooked.

  28. simoncozens commented on Feb 6, 2025

    @simoncozens
    Contributor

    Yes, those are the next steps. First one can be done any time; the js-split PR needs to be done when there's no work (or minimal) going on in the JS files as it will cause conflicts. I'll be at BITS next week, so maybe after I get back?

  29. justvanrossum commented on Feb 6, 2025

    @justvanrossum
    MemberAuthor

    I'll be at BITS next week, so maybe after I get back?

    Sounds good, thanks.

  30. justvanrossum commented on Mar 5, 2025

    @justvanrossum
    MemberAuthor

    This has been implemented in #2053 and related PRs.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions