Announcing `pkg:` Importers
Posted 16 February 2024 by Natalie Weizenbaum
Several months ago, we asked for feedback on a proposal for a new standard for
importers that could load packages from various different package managers using
the shared pkg:
scheme, as well as a built-in pkg:
importer that supports
Node.js’s module resolution algorithm. Today, I’m excited to announce that this
feature has shipped in Dart Sass 1.71.0!
No longer will you have to manually add node_modules
to your loadPaths
option and worry about whether nested packages will work at all. No longer will
you need to add ~
s to your URLs and give up all portability. Now you can just
pass importers: [new NodePackageImporter()]
and write @use 'pkg:library'
and
it’ll work just how you want out of the box.
What is a pkg:
importer?What is a pkg: importer? permalink
Think of a pkg:
importer like a specification that anyone can implement by
writing a custom importer that follows a few rules. We’ve implemented one for
the Node.js module algorithm, but you could implement one that loads Sass files
from RubyGems or PyPI or Composer. This way, a Sass file doesn’t have to
change the URLs it loads no matter where it’s loading them from.
What do pkg:
URLs look like?What do pkg: URLs look like? permalink
The simplest URL is just pkg:library
. This will find the library
package in
your package manager and load its primary entrypoint file, however that’s
defined. You can also write pkg:library/path/to/file
, in which case it will
look for path/to/file
in the package’s source directory instead. And as with
any Sass importer, it’ll do the standard resolution to handle file extensions,
partials, and index files.
How do I publish an npm package that works with the Node.js pkg:
importer?How do I publish an npm package that works with the Node.js pkg: importer? permalink
The Node.js pkg:
importer supports all the existing conventions for declaring
Sass files in package.json
, so it should work with existing Sass packages out
of the box. If you’re writing a new package, we recommend using the "exports"
field with a "sass"
key to define which stylesheet to load by default:
{
"exports": {
"sass": "styles/index.scss"
}
}
The Node.js pkg:
importer supports the full range of "exports"
features, so
you can also specify different locations for different subpaths:
{
"exports": {
".": {
"sass": "styles/index.scss",
},
"./button.scss": {
"sass": "styles/button.scss",
},
"./accordion.scss": {
"sass": "styles/accordion.scss",
}
}
}
…or even patterns:
{
"exports": {
".": {
"sass": "styles/index.scss",
},
"./*.scss": {
"sass": "styles/*.scss",
},
}
}