What is limiting the JavaScript files the Phoenix server can see?

The helpers in my template result in this code when I view the source of my site while it’s serving at localhost:

<script src="/js/app.js"></script>
<script src="/js/nav.js"></script>

The local file structure is …


But while the app.js file serves fine, the nav.js shows a 404 in the developer console. Why is the Phoenix server refusing to serve this file and how do I fix it?

Uh, but Phoenix doesn’t host out of assets by default, it hosts out of ./priv/static by default, do you have a nav.js in there?

Whatever build system you use at the very least either needs to concat nav into app (the default one that phoenix uses, brunch, does that automatically) or you need to have it copy nav to the output priv/static directory.

My brunch file has

javascripts: {
      joinTo: {
        'app.js': /^js/,
        'nav.js': /^js\/navigation/

The priv subdirectories don’t actually have the app.js file, which is what’s confusing me even more.

I’m currently just using the default Phoenix development settings. I don’t dare push to production without being sure.

This means that everything in the js/navigation directory in assets will be compiled to nav.js, but your listing had no such directory, so that does nothing. Currently app.js is taking in everything under js, so nav is being put into it too.

Should be in something like priv/static/js/app.js or so, and only once you either start the dev server or so.

My apologies for not including full details of my solution:


Exists in my /js directory.

I can remove the js subdirectories, but at the moment I’m just testing that brunch works and I wanted to see master.js compiled to nav.js but I’m not seeing that.

I doubt it still would, the app.js is grabbing everything under js, including the things in the navigation folder, so when the nav.js entry is hit there is nothing left for it to take. Fixup the app regex to exclude the navigation directory to start. :slight_smile:

Wow. I wouldn’t have thought of it as ‘grabbing everything’ in the sense of removing stuff (would have thought it works more cp than mv). I thought it was just spidering the directories. I have a few things I need to do right now but if your solution works I’ll be very impressed! :blush:

Brunch is powerful, but it does have a few specific things to be aware of, all in its documentation though. :slight_smile:

Yeah. When you’re unemployed and trying to put a showcase site together you tend to go with getting functionality up first. I did read some of the documentation but urg, sometimes it’s difficult to juggle stuff :/. Will have more of a look tomorrow.

1 Like

Ok, I now have this:

javascripts: {
      joinTo: {
        'nav.js': /^js\/navigation/

in my brunch file, and have even removed all of the import statements in my app.js file, but it’s still compiling all the JavaScript into a single app.js file :neutral_face::expressionless: :neutral_face:

I think one of the issues you are battling is that the second pattern covers files that are already included in the first pattern. The easiest way to deal with that is to move everything that is under /js but not in /js/navigation into a separate folder like /js/app. Then rewrite the configuration as:

      joinTo: {
        'app.js': /^js\/app/,
        'nav.js': /^js\/navigation/

According to documentation that should give you two separate files.


Current Brunch config:

javascripts: {
  joinTo: {
    'app.js': /^js\/app/,
    'nav.js': /^js\/navigation/

When I move the app.js and socket.js file into an app subdirectory the output of mix phx.server includes:

16:47:07 - error: Processing of js/app.js failed. Error: Could not load module './socket' from '/Users/user/haaksploits7/assets/js'. Make sure the file actually exists.

As you can see, the app.js file is in the same location as the socket.js file, so it’s odd that the import statement seems to be parsed, yet either this is not actually the app.js in the js/app directory, or something is going awry with the routing? Particularly, it’s odd that Phoenix/Brunch is telling me the js/app.js file even exists, since it is now located at /js/app/app.js.

$ pwd
$ tree
├── app
│   └── socket.js
└── app.js
  files: {
    javascripts: {
      joinTo: {
        "js/app.js": /^js\/app/
import "phoenix_html";

// Import local files
// Local files can be imported directly using relative
// paths "./socket" or full ones "web/static/js/socket".

import socket from "./app/socket";
MacBook-Pro:js user$ pwd
MacBook-Pro:js user$ tree
├── app
│   ├── app.js
│   └── socket.js
├── intro
│   └── intro.js
├── multiple-choice
│   └── multiple-choice.js
├── navigation
│   └── master.js
└── scoring
    └── scoring.js

5 directories, 6 files

I also tried deleting all of the JavaScript in the intro.js file, then running the intro again. It works, which makes me suspect caching of some kind, but I have hard reloaded the browser cache, restarted the phoenix server process and even deleted the file in .mix/archive, so I’m not sure what other cache might be responsible, if that is indeed the problem.

According to the configuration app.js and nav.js have to already exist directly under /js (i.e. move app.js up from /js/app (and change the import paths ) and create a /js/nav.js). /js/nav.js may have to import something from /js/navigation in order for brunch to include any of it (though it may be enough for some code referenced by app.js to need it (and not get it because it isn’t in that bundle)).

You can specify multiple subdirectories using arrays for the joinTo pattern match.

Hhhhmmm. Not sure if it’s that. I just noticed this line in the brunch config:

modules: {
    autoRequire: {
      "js/app.js": ["js/app"]

I think we might have the culprit…

Nope, that’s not it either.

I noticed that in the browser I see this:

Yet I’ve deleted all the requires from the app.js file except import socket from "./socket", so it shouldn’t still be requiring in these additional files, but for some reason it is. Making changes to the brunch file and app.js no-longer seems to affect what I’m seeing in the browser at localhost.

Even weirder:

Note that in Atom (run from the $user account via the command line) the static files folder does not even exist, yet in the terminal they do, making it quite difficult to figure out where these files were being compiled and stored to…

Can you please double-check if both, atom and the terminal are on the same folder? Please change a file in atom and cat it in the terminal and check for the change.

Yep. Changes persist. There’s also an Elixir error showing in Atom when I load it via the launcher. This error does not appear when Atom is launched via the command line. Atom also fails to launch via the command line intermittently.