Skip to content

Build mode footgun: make web-apps-dev produces a production build; add explicit dev/prod targets #259

Description

@moodyjmz

What we found

While fixing the mobile editor regression (web-apps, follows DocumentServer#258),
we hit a build-mode footgun that nearly invalidated the fix's testing. Three
overlapping problems:

  1. The Makefile target names lie. In develop/setup/Makefile, web-apps and
    web-apps-dev produce identical output — both production. The only
    difference is web-apps runs npm ci and web-apps-dev skips it
    (CHECK_WEBAPPS_DEPS). So -dev means "skip dependency install," NOT
    "development mode." Anyone reading the name expects a dev build and gets prod.

  2. The two webpack pipelines default NODE_ENV oppositely.

    • desktop web-apps/build/webpack.editor.factory.mjsNODE_ENV || 'production'
    • mobile web-apps/vendor/framework7-react/build/webpack.config.jsNODE_ENV || 'development'
      So with NODE_ENV unset, desktop builds prod and mobile builds dev unless
      something forces it. A manual mobile build silently came out dev — esbuild's
      minimizer never runs in dev, so the production-only transforms (ES target
      downlevel, drop_console) don't execute.
  3. The validation trap. Because a dev mobile build skips the minifier, a
    crash that only occurs in production (esbuild lowering i18next 25's class
    internals → TypeError: we is not a function) appears fixed in a dev build
    — the broken transform simply never ran. "It works in my rebuild" can mean
    "esbuild didn't run," not "the fix works." This cost real debugging time.

Fixes already landed in web-apps (companion PR)

  • build-pipeline.js now sets NODE_ENV once in CHILD_ENV
    (process.env.NODE_ENV || 'production'), passed to every child — desktop and
    mobile now agree, defaulting to production, overridable with NODE_ENV=development.
  • build-pipeline.js echoes the build mode in its banner (green production,
    red ⚠ DEV BUILD warning) so the mode is never silent again.
  • Mobile watch decoupled from NODE_ENV (WATCH=1 opt-in) so a dev-mode build
    is a one-shot that exits, instead of hanging the pipeline in watch mode.

Proposed change here (DocumentServer Makefile)

Make the target suffix mean the mode, self-documenting, so the shell
environment can't silently flip it:

target install mode use
web-apps npm ci production canonical / first build
web-apps-prod skip production fast re-test of the shipping build
web-apps-dev skip development fast debuggable iteration
web-apps-dev:  NODE_ENV := development
web-apps-prod: NODE_ENV := production
web-apps-dev web-apps-prod:
	$(CHECK_WEBAPPS_DEPS)
	cd $(EO_DEV)/web-apps/translation && python3 merge_and_check.py && \
	cd $(EO_DEV)/web-apps/build && \
	BUILD_ROOT=$(EO_ROOT) PRODUCT_VERSION=$(PRODUCT_VERSION) THEME=euro-office \
	SKIP_MOBILE=$(SKIP_MOBILE) NODE_ENV=$(NODE_ENV) \
	node scripts/build-pipeline.js
	$(FLUSH_CACHE)

Heads-up / acceptance

  • Behaviour change: make web-apps-dev flips from production → development.
    The dev-container docs (and web-apps CLAUDE.md) that point at make web-apps-dev must be updated: use web-apps-prod (or web-apps) to test the
    shipping build; web-apps-dev to debug.
  • A dev build is unminified, keeps console, inlines CSS via style-loader, and
    does NOT exercise the production transforms — by design. Never sign off a fix on
    a dev build.
  • web-apps-prod and web-apps produce the same bundle; web-apps-prod just
    skips npm ci for speed.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingbuildBuild process related changes

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
📄 To do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions