Change publicPath

Description

Right now Webpack’s publicPath is hardcoded to /static. We need to add a way to change it. We should allow people to change it when they run npx frontity build.

User Stories

As a Frontity developer
I want to change the publicPath at build time
so that I am not restricted to the /static folder

As a Frontity developer
I want to change the publicPath at runtime
so that I am not restricted to the /static folder

Moved to: Change publicPath dynamically at runtime

Possible solution

Even though people will be able to change this once we relesae the frontity.config.js file with support to modify Webpack, I think this is important enough to add a CLI arg to change it, like this:

> npx frontity build --publicPath="/other/folder"
# or
> npx frontity build --publicPath="https://external-domain.com/folder"

It should be possible to configure it with ENV variables:

> FRONTITY_PUBLIC_PATH=/other/folder && npx frontity build

Implementation proposal

When you had it working as a query string before ?frontity_publicPath=/other/folder, was that on each user request (cache notwithstanding)?

Only reason I ask is that a common configuration of FastCGI cache or Varnish is to exclude ?arg from cache. Just curious more than anything.

Frontity is not as new as it seems :slight_smile:

We developed the first version of the framework for our own use during 2017 and 2018. We did it because we were working with some big Spanish publishers and they wanted to improve the performance and UX of their mobile version. It worked great but they didn’t have access to change the code, so at the beginning of 2019, we decided to discontinue the product and launch an open-source framework. This new version is based on the old one, but we took the opportunity to simplify the APIs and do some performance/size optimizations.

There are still some things we haven’t ported from the all framework, like analytics packages, ads packages, comments packages, AMP support, server extensibility, Slot and Fill extensibility… but all those things were working great in the old version.

Yes, because the HTML changes to accomodate the new publicPath. The publicPath query would need to be removed from the URL of course. I have added a FD for a system called Router Converters which will allow to do so.

Also, take into account that with the Theme Bridge architecture, WordPress should be the one caching (or using a CDN). You don’t want to cache twice because that could lead to invalidation problems.

Draw

2 Likes

Implementation Proposal

Add a new option called publicPath to the build command in: https://github.com/frontity/frontity/blob/dev/packages/frontity/src/cli/index.ts#L80-L88

Pass down that option to the real build command. If it’s not present, the default should be /static: https://github.com/frontity/frontity/blob/dev/packages/core/src/scripts/build.ts#L12-L18

Pass down that option to webpack: https://github.com/frontity/frontity/blob/dev/packages/core/src/config/webpack/output.ts#L67

Repeate the process for the dev command.


We are also going to take this opportunity to add the ENV variables to build, dev and serve, like we did in the last CLI refactor: https://github.com/frontity/frontity/pull/262

For that, we need to add build, dev and serve to the CLI folder (https://github.com/frontity/frontity/tree/dev/packages/frontity/src/cli) and create variables for:

  • target: FRONTITY_TARGET.
  • port: FRONTITY_PORT.
  • https: FRONTITY_HTTPS.
  • production: FRONTITY_PRODUCTION.
  • development: FRONTITY_DEVELOPMENT.
  • publicPath: FRONTITY_PUBLIC_PATH.

It needs to be similar to what we are doing here: https://github.com/frontity/frontity/blob/dev/packages/frontity/src/cli/create.ts#L23-L26

Issues Proposal

  • Add publicPath option to CLI and pass it down to Webpack in both the build and dev commands.
  • Add ENV variables for the build, dev and serve commands.

Documentation

1 Like

The publicPath options it’s implemented just as it was explained in the implementation proposal (code can be reviewed in frontity/frontity#420):


The environment variables were added as specified in the implementation proposal.

Also, an extra env var was added ( FRONTITY_DONT_OPEN_BROWSER ) for the --dont-open-brower argument of the npx frontity dev command.

2 Likes

I wonder if we should add the command name to the ENV variables to avoid collisions:

FRONTITY_DEV_PORT=3001

instead of

FRONTITY_PORT=3001

We already have some clashing names:

  • FRONTITY_NAME
    • npx frontity create
    • npx frontity create-package
  • Most of them for:
    • npx frontity dev
    • npx frontity build
    • npx frontity serve

If we keep adding commands with args, I guess we may get to a point where someone wants to have more than one ENV variable configured for more than one command but they can’t do it.

@dev-team what do you think?

I think that:

  1. The user should always have the chance to set the env variables before running the command, right? So they could do FRONTITY_PORT=3333; npx frontity dev. This works in npm scripts as well. Is there a use case where that’s not the case?

  2. At the same time, we could just go with FRONTITY_DEV_PORT, it’s kinda ugly but it solves the problem and if we think of a better solution we can always still keep backwards compatibility and promote the “new” solution

Yes, but I think a lot of people right now is using dotenv to define their env variables in a .env file, so maybe they want to define all of them for different commands and they clash.

Which, by the way, I think that running dotenv ourselves would be pretty cool. I think is getting the standard. I’ve seen several tools that do it lately, like changesets and docker-compose, and it’s cool not to have to install and run dotenv yourself, just create the .env file.

@david, what do you think about the naming?

Well, to have a stronger opinion here I’ve writen an example of how the .env file would look:

# `dev` command variables
FRONTITY_DEV_TARGET='module'
FRONTITY_DEV_PORT=3001
FRONTITY_DEV_HTTPS=false
FRONTITY_DEV_PRODUCTION=false
FRONTITY_DEV_PUBLIC_PATH='/public/path'
FRONTITY_DEV_DONT_OPEN_BROWSER=true

# `build` command variables.
FRONTITY_BUILD_TARGET='both'
FRONTITY_BUILD_DEVELOPMENT=false
FRONTITY_BUILD_PUBLIC_PATH='/public/path'

# `serve` command variables.
FRONTITY_SERVE_PORT=80
FRONTITY_SERVE_HTTPS=true

Which I think it looks nice. :slight_smile:

It would be a problem if you had to use such long names in a command:

 FRONTITY_DEV_TARGET='module' FRONTITY_DEV_PORT=3001 FRONTITY_DEV_DONT_OPEN_BROWSER=true npx frontity dev

But why not to use the command arguments in that case?

npx frontity dev --target 'module' --port 3001 --dont-open-browser

Also, I understanded that the use case for the env variables is to change the “default” value of each argument so you can call just npx frontity dev and use whatever values you have specified for the env variables. And you can overwrite those values too passing new arguments explicitly.

My vote is for adding the command to the var names. :raised_hand:

Thanks guys. I’m going to unblock the issue then :slightly_smiling_face:

This feature has been included in the latest release. It was implemented according to the implementation proposal in this Pull Request, and now Frontity allows dev , build and serve commands to be configured using environment variables.

I made a mistake in my implementation proposal. None of our CLI args are in camelcase (--use-cwd or --no-prompt) and our commands are neither (create-package).

I think we should rename this to --public-path. I’ll make a PR to fix it while maintaining backward compatibility.

EDIT: This is the PR: https://github.com/frontity/frontity/pull/541