More file structure, this time webpack flavoured!
Thought I'd make another thread as this is kind of a different, but very related, question
I've been developing locally using webpack and vanillajs. My server is hosted on digitalocean with ubuntu. As mentioned in my last question I build locally, push to a github repo, and then pull that repo in to my server. I plan to use github actions from next week thanks to @joao6246 advice, but for the time being that's the (maybe less than ideal?) set-up I learnt from frontend masters
My Server folder structure:
I'm just wondering both where should I put my express app that's going to serve my html, and how I can better structure webpack's output?
As you can see it has just output everything in to one folder. Should I have a script that moves files after every
git pull
? Or should I be specifying better paths in my webpack config?
This is my webpack config at the moment, I guess I could add path.resolve(__dirname, 'dist/js')
for my js content, look for an output path option for each of the relevant module rules (for example for images), and do similar with HtmlWebpackPlugin
(or add a path before the filename)?
I guess I could then place a simple express app in the route directory?
Sorry, I'm just a little confused! Appreciate any help, am so close to getting my first self-hosted website up and running!67 Replies
// webpack config
If you are using express to serve content (html, css, images, etc...) you need to specify a folder using
express.static
(I think that's the function, right?). In that case all you need to do is make sure the output of the build process from webpack is inside this folder.
As an aside, you can apply conditional logic on your webpack.config.js file based on whether you are running on development or for production. Although in this case, as far as deployment is concerned, it shouldn't matter too much.Hmm... interesting. So I guess
res.sendFile()
won't work as I expect then? Yeah I guess it won't serve the files needed in the html...
And yeah, I use a different webpack config file for production vs dev with webpack merge, so I think I've got that side of things covered 🙂
Problem is, how can I tell webpack to put files into that folder XD
Like this?
The javascript gods don't like me that much XD
Edit: whisper it quietly: they do!
lol, the dist folder is kind of redundant now but has to exist (I think).The problem, in this case, with
res.sendFile()
is that it only sends one file. You could send the index.html
file but then it will make requests for additional files for things like images, fonts or scripts. Then you'd have to setup routes for each of those files, or create some route handler that is flexible enough to detect this sort of requests... which of course is just unnecessarily complex. Setting up a static folder that Express.js knows to look into is much better (and also what other web servers do).
so you got it working then? That config looks fine to me. Since it's all in the same repo Webpack should have access to whatever folder you want to use as the public to serve files from the server.I'm just trying to implement it now. The problem is using those paths then breaks my devServer, so I've just split the config between dev and prod.webpack.js, which seems to work.
Ideally I'd have some way to move
express-app.js
to the correct folder, but as it's not a webpack entry point, I'm not entirely sure how to do that - I think there's a copy plugin or loader, but I've said to my friend I'd show him the site in 2 hours so that can wait! 😆 (I'm just editing that file locally on the server for the time being)
Fingers crossed I'm on track! (I don't want to jinx it, but I'm getting on with webpack ok this morning!)
of course pm2 now keeps erroring 😭 edit- now fixed, and replaced with 504 Gateway Time-out
. The route works, but sending the file doesn't:
Well, that was just the path 😄
Now I've got the problem that I'm cache busting the html. I guess for the moment I can stop doing that on webpack's side.res.sendFile(path.join(__dirname, './public/html/index.html'));
You don't need to dot when joining pathsYeah, without the dot also gets the same error
does the mime type error mean at least it's finding the file, right?
without the dot:
// express-app/public/html/index.html
Well, that's an interesting script tag...
I guess my webpack config wasn't as clever as I thought
So it was both the path above & that when I pulled the repo it overwrote
use(express.static(...))
. It's now loading the site, but without images. I think I'm going to strip my stupid production webpack config and just copy the files across from the build folder manually
----------------------
Update: Success?
I dumped all my build files on the server as they were in one big list in the public folder.
The weird thing now is I've this list:
and an express-app.js file like this:
and it's serving ADMIN.HTML 😆 😭Do you have a git repo to take a look at?
yeah, but the express file above isn't part of it
I can link it anyway if it helps?
but in my build folder if I click click on index.html and choose 'live-server' locally it serves the right file
so it feels like an issue with express/the server rather than my build files?
That's what I want to understand, why are you using webpack at all?
I'm not for the express side of things any more. I'm manually copying them into the public folder
Try this:
still the admin.html XD
Ok, let's take a look at the repo 😄
I literally have to laugh at this point 😁
1 second
thanks btw
GitHub
GitHub - NickWoodward/sub1
Contribute to NickWoodward/sub1 development by creating an account on GitHub.
there is a rogue express-app.js file in there, but it's not om the server
^ the site on my server. basically the repo + an
express-app
folder// public:
So the public folder is
/var/www/sub1/express-app/public
? And the node.js server is the file at /var/www/sub1/express-app/app.js
?yup
/var/www/sub1/express-app/public
:I mean, I'm very close to switching the names of the files round 😆
You mentioned you are using pm2 right?
yeah
Try shutdown and restart. It's probably some caching issue somewhere
i could just shut down the whole server, just to make sure
?
Also try
app.use(express.static(path.join(__dirname, 'public')))
why not, better be safe at this point 😄no luck, still the admin page 😦
let me delete the pm2 app
nope 🤷♂️
/etc/nginx/sites-available/default
:
Are you sure admin.html and index.html aren't the same file?
Pretty sure. I'm just copying across the file from the build folder, and locally it opens the main index page. Also it references index.js:
Well, try to setup different routes then and see if they work:
Also try to run the server with node, instead of pm2, as a test
node app.js
Not run with node yet, but
/
goes to admin, /admin
is cannot get, /admin.html
goes to admin
let me try nodeJust in case I've made a silly error:
Btw, is there a reason why you are using express AND nginx?
You can do the same with nginx only
I was following a guide, and thought i'd stick to what I knew. That's worked out well XD
Make sure it's the right path, console.log the result of
path.join(__dirname, public, admin.html)
(same problem with
node app.js
)And also try removing the
/
route now that you have one for admin.sub1.io/admin
:wait...
sub1.io
: no output
tried with an index route too. Cannot GET /index
(but it said that about /admin
to start off with)
restarted node. Both routes point to the correct pathIf I remove
admin.html
express throws the error from my error handler on the /admin
route... but serves the admin page on every other route
-------------------
So I deleted the code in index.html
and it started serving the right content, so it's an issue with how it's being bundled I guess?
I've reworked the issue here, but I'm so tired of fighting this for 8 hours now it's probably terribly written and about to be closed 😁Stack Overflow
Webpack building the wrong file?
So I've a bug I've been chasing all day, and I've narrowed it down to my webpack config (I think).
I run my app locally using webpack server and index.html is displayed correctly (with index.js).
I
Hey, sorry I had to go earlier... I'm not sure what's going on, I'm suspecting it has to do with the static folder.
Either webpack or express it's probably some silly typo somewhere that we missed
Try setting up a route in nginx instead:
Oh no worries at all, I appreciate whatever help I can get!.
I'm starting to think it isn't
Express
though. I now think it was serving the correct file (I deleted the contents of the file and replace it with new code it works)
let me try it again quickly before we start looking at switching to nginx
--------------
So I've just got index.html
and index.js
in my public folder now, and I've just changed the contents to a boilerplate html doc and it's displaying it.
So it must be webpack, right? I just don't understand how webpack-server
and live-server
can both display the file correctly?
got to sub1.io XDI think there was something hard-coded in there for an api endpoint
?
But I don't think it's the problem
either way express/nginx is displaying index.html
at least that's something (for 7 hours bug testing!)
Well if you figure it out let me know I'm curious now 😄
Will do! It'll be one of those things where I'll have a good sleep and it'll take me 3 minutes in the morning 😁
(I hope)
That's how it works 😂
I wish I had a proper answer for you @joao6246 .
From what I can tell it was serving the right
html
file, but the wrong js
file (which produces the content). That doesn't explain why not finding the index.js
file (indicated by the MIME type error) would result in it defaulting to admin.js
though 🤷♂️ . I still think that it was a bug in webpack. I read a couple of accounts of somesort of 'blank space' bug in the config that could produce errors, so maybe I removed part of the config that was causing an issue.
Either way, after messing about in the config, chrome started complaining about the config file not being found at .src/blah/blah
which obviously wasn't right and indicated that html-webpack-plugin was injecting the wrong script links, and it was. Still, I've no idea why that meant it was serving the wrong file.
BUT IT'S WORKING! 🥳 ...and that's all that matters, right? 😆
(I also managed this fix while drunk 😁 )If it works for martial arts, no reason why it shouldn't work for programming right? 😂
I still think it wassome caching issue somewhere (it always is...)
"works"
Anyway, good job getting things to work is the most important part
yeah, it's still now complaining about that MIME type every other time I run locally now. Refreshing it fixes it. TBH I'm ok with that as long as it's working!
thanks again for your help bud, appreciate it
Try adding this to the express server if you are still using it:
res.setHeader('X-Content-Type-Options', 'nosniff');
I'll give that a try, thanks 🙂