The curious case of /public/assets/ in a Meteor project

Viewed 145

In my Meteor 1.10.2 project, I have created a folder called assets inside the /public/ folder. When the Meteor application is built, I find this assets folder has been copied to these locations, as a direct child of the web.browser... folders:

/.meteor/local/build/programs/web.browser/assets/
/.meteor/local/build/programs/web.browser.legacy/assets

However, if I rename the folder to Assets (or if I give it any other name), when the application is built, I find it deeper in, inside the app folder at:

/.meteor/local/build/programs/web.browser/app/Assets/
/.meteor/local/build/programs/web.browser.legacy/app/Assets/

What is the logic behind this? What is the intention? What are the best practices for working with a folder at /public/assets/? Are there any other words that are given special treatment when used as names for folders inside the /public/ folder?

2 Answers

FWIW, this behaviour is specifically due to meteor tools bundler:

https://github.com/meteor/meteor/blob/release/METEOR%401.10.2/tools/isobuild/bundler.js#L719-L725

  setTargetPathFromRelPath(relPath) {
    // XXX hack
    if (relPath.match(/^(packages|assets|dynamic)\//)) {
      this.targetPath = relPath;
    } else {
      this.targetPath = files.pathJoin('app', relPath);
    }

Therefore we can see that there are 3 special directory names that exhibit this special behaviour:

  • packages
  • assets
  • dynamic

Example with public assets:

public assets

These assets bundled in build:

assets copied in build

For "packages", while we can understand that this is how Meteor ships the static assets of packages (i.e. when they call api.addAssets(), we can also see that there is a potential for collision, in the (however unlikely) case we use a pathname like "public/packages/my-package-name".

As for "assets", the initial name was "static", but I do not think it was publicly documented either.

And for "dynamic", I do not know yet what is its exact purpose, but we can see that it serves its content as "javascript" type (at least SVG files), whereas the first 2 serve them as "text/plain".

SVG file in dynamic served as javascript

What Meteor does is build your project multiple times. Once for legacy web browsers, and again for a modern browser, and also for other platforms such as IOS or Android. It does all this inside the .meteor/local folder as you have observed.

Meteor has the concept of a /private folder, which is similar to /public, except that Meteor thinks of them as assets. This might explain why your folder appears in different locations, depending on the name.

Personally I wouldn't worry too much about how Meteor handles files, unless you want to become a contributor, in which case you are welcome to poke around :)

Related