Best way to import dependencies, post-Embroider?

What’s the best practice for importing dependencies for Embroider enabled apps?

One of our projects is using a @fontsource font. The package has some .css that needs to be imported, which references font files using relative paths (eg src: url(“./files/my-font.woff”)).

The @fontsource docs say to add import “@fontsource/my-font.css” to the app’s entry point and “that’s all folks”.

Today, with Embroider enabled I can add an asset/resource module to my Webpack config and all is well. :partying_face:

As I understand it, the only way to achieve this pre-Embroider would involve a series of app.import() statements in the ember-cli-build. Some to import the css, and others to import the font files and put them in a place that matched the relative paths from the css.

What I’m not clear about is which approach is “better”.

The app.import approach is less ergonomic (requires more lines of code) but I’m not sure if that’s still the preferred way of importing.

Can anyone shed a bit of light? Thanks :pray:t2:

1 Like

IIRC app.import is the “legacy” way of adding arbitrary modules to the build. Even with ember auto import a lot of that was becoming unnecessary, and Embroider can further leverage all the great build tools that have been created in the meantime (since ember-cli was created and there were no standards around modules and build tools) and all the benefits they can provide (tree shaking, code splitting, etc). So if you’re already on Embroider and it’s working I’d go with that. I’d assume ember-cli-build and all the associated APIs will be slimmed down and/or deprecated once Embroider is widely adopted.

Many thanks @dknutsen, that’s what my gut was saying too. :+1:t2:

@roomman Can you share the webpack configuration you needed to make this work? I’m facing the exact same problem. Thank you!

Sure, happy to. :grinning:

If you are using Webpack 5, you can take advantage of Asset Modules and add something like this to your config:

module: {
  rules: [
    {
      test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
      type: 'asset/resource',
      generator: {
        filename: 'fonts/[hash][ext][query]',
      },
    },
  ],
},

In this case, filename determines where things land in your dist folder.

If your project is < Webpack 5 then you will need to add file-loader as a dev dependency, and this to your config instead:

module: {
  rules: [
    {
      test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts/',
          },
        },
      ],
    },
  ],
}

This time, outputPath determines where files land in your dist folder.

Let me know if it works for you :+1:t2: