Fontsource Error - Unexpected character '@'

Hey all,

Trying to use GitHub - fontsource/fontsource: Self-host Open Source fonts in neatly bundled NPM packages. to import fonts. I’m placing the following in my app.js file.

import "@fontsource/libre-franklin";

Which results in the following error:

┌ error ──────────────────────────────────────────────────────────────────┐
│                                                                         │
│ Module parse failed: Unexpected character '@' (2:0)                     │
│ You may need an appropriate loader to handle this file type, currently  │
│ no loaders are configured to process this file. See                     │
│ https://webpack.js.org/concepts#loaders                                 │
│ | /* libre-franklin-vietnamese-400-normal*/                             │
│ > @font-face {                                                          │
│ |   font-family: 'Libre Franklin';                                      │
│ |   font-style: normal;                                                 │
└─────────────────────────────────────────────────────────────────────────┘

Any thoughts on how to resolve? First time using bud, but I’ve used fontsource many times in Laravel Mix projects without issue.

Not many people want to load source code from node_modules so bud doesn’t bother to look for source code there. Bud will only pass code off to loaders that originates in the app.path('@src') directory (by default: 'src'; with sage: resources).

This is 95% of the time what people want. And, by narrowing down the places a module can be resolved from, we end up with a much faster build.

In contrast, mix tries literally every module (file) in the project. This is the opposite approach so as to avoid making everybody’s project slower.

I think this overhead is worth it and so that’s the way Bud is built. But, I also know that people are going to want to load all kinds of things from node_modules, so there is an API to help.

Registering additional module paths with loaders

Looking in the @fontsource/libre-franklin directory I can see we want to load css. So we need to tell bud to try and load .css from that directory.

Options

Ordered from most forgiving to most optimal:

  1. Try to load modules from anywhere in the project:
app.build.rules.css.setInclude([app.path()]);
  1. Try to load modules from the source directory or the node_modules directory:
app.build.rules.css.setInclude([
  app.path('@src'),
  app.path('@modules'),
]);
  1. Try to load modules from the source directory or the @fontsource directory:
app.build.rules.css.setInclude([
  app.path('@src'),
  app.path('@modules/@fontsource'),
]);
  1. Try to load modules from the source directory or the @fontsource/libre-franklin directory:
app.build.rules.css.setInclude([
  app.path('@src'),
  app.path('@modules/@fontsource/libre-franklin'),
]);

Any of these will allow you to resolve css files from node_modules.

Note: app.build.rules.css.setInclude does not chain. You will want to wrap it in bud.tap if you want to keep your configuration file functional:

    // ...config
    .tap((app) => {
      app.build.rules.css.setInclude([
        app.path("@src"),
        app.path("@modules"),
      ]);
    });
6 Likes

Went with option 1 and it worked. Thanks for the detailed response!