← Blog

Serve Static Files during Development with Parcel

Web Development
published on:
📚  This article is part of a series on 
Web Development
:

Serving static files like images is an essential ingredient for front-end development. With bundlers such as webpack and Parcel, this task has become as easy as developers could wish for. While this holds for the production environment of a front-end, matters are a little more complicated during development. parcel serve does not copy static files to the output directory (i.e., dist) during development, leaving developers on the outlook for a custom solution.

For production environment emulation, Parcel has introduced an API proxy that allows specifying paths that should be proxied to another destination during development. Creating a .proxyrc.json in the project's root directory, we can configure a http-proxy-middleware options object according to our needs. Since serving static files is most conveniently accomplished with serve-static, using http-proxy-middleware is not sufficient, though. Luckily, we can also configure the API proxy through a .proxyrc.js in the project's root directory with any connect-compatible middleware that we are familiar with from express.

Leveraging the API proxy, we can serve static files at /static using Parcel from a directory called public with the following configuration in .proxyrc.js (based on the idea of subata on GitHub):

.proxyrc.js

_13
const path = require("path");
_13
const serveStatic = require("serve-static");
_13
_13
const assetsPath = path.join(__dirname, "public");
_13
// Beware the leading `/` before the path!
_13
const pathToServe = "/static";
_13
_13
module.exports = function (app) {
_13
app.use(pathToServe, serveStatic(assetsPath));
_13
_13
// Optionally, serve more static assets from another folder.
_13
// app.use(pathToServe, serveStatic(anotherAssetsPath));
_13
};

If we host more than one folder of assets, we can simply add further request handlers (i.e., calls to app.use) by copying line 8 (i.e., app.use(pathToServe, serveStatic(assetsPath))) and providing a different path instead of assetsPath. That is possible because app.use will pass a request on to the next handler in case of a failure (i.e., a file not being found).