1

I am working on an NPM package (an internal design library) which distributes CSS, SASS mixins and static assets to other projects.

A problem which I am facing is that my host application's Webpack build is failing when I try to include a SASS mixin coming from my NPM package which references a static asset. This is happening because Webpack tries to resolve all urls relative to the output Webpack file (read more here). This works well when I am building the NPM package but is not when I am building the host application.

I have setup a repo where the problem could be easily reproduced - https://github.com/dobrinov/playground/tree/main/webpack/npm-distribute-assets

The solutions which I have found for this problems are:

Inline your assets in the distributed CSS and SASS files

This is the approach which Twitter Bootstrap 5 uses for distributing SVGs.

URL rewriting

This could be achieved by the resolve-url-loader Webpack loader which will rewrite urls to be relative to the file that contain them and not to the Webpack output file.

SASS variables

This is something which Twitter Bootstrap did in its old SASS implementation. It is not ideal because in order to achieve it you have to use SASS @import (it puts variables in the global space) instead of @use, which is discouraged.

Does anyone have a better solution to this problem?

dobrinov
  • 594
  • 4
  • 11

1 Answers1

0

I found a solution which works well for me. It couples my host application with Webpack but this is fine for my case. You can view an implementation of it in the "solution" branch of my sample project.

tl;dr;

I created a SASS variable holding the root path and placed it in a SCSS file. In development its value is ./. When I am building the distributable version of the package I am replacing this file with another one which sets the variable value to ~distributable/dist/scss/. The trick here is that when the css-loader tries to resolve the asset paths the ~ will make it look in the resolve paths and since there will be a distributable directory in node_modules this will work fine.

This will work fine only if:

  1. You are using Webpack in your host application
  2. The node_modules directory is in modules.resolve
  3. webpackImporter is not turned off for sass-loader
dobrinov
  • 594
  • 4
  • 11