With the introduction of Sass
's Package Importer feature
, loading Sass
files has become simpler and more flexible. This article explains how to use Vite
in combination with Sass
's Package Importer
and how to deal with errors you may encounter when doing so.
What is Sass's Package Importer?
The Package Importer feature
in Sass
, released in 2024, is a revolutionary feature that allows you to import Node.js
packages directly. It is more convenient than the traditional @import statement and is suitable for modern Sass projects. This feature simplifies project dependency management and eliminates the need to manually specify the Sass
file for a package.
More details are explained in an announcement on the official Sass
blog. It seems that most CSS frameworks can use it without any changes at the publisher.
https://sass-lang.com/blog/announcing-pkg-importers/
Also, in line with Package Importer support,
Vite and Sass Integration
Vite
is a module bundler popular for its speed and ease of use. It is particularly well suited for front-end development and integrates smoothly with Sass
.
Starting with Vite:5.4.0
, support for the Sass
moder api has been added. If you want to use it, you need to upgrade to version 5.4.0 or higher.
https://github.com/vitejs/vite/blob/v5.4.6/packages/vite/CHANGELOG.md#540-beta0-2024-07-30
You also need to set importers
in vite.config.ts
as follows
https://sass-lang.com/documentation/js-api/classes/nodepackageimporter/
import { defineConfig } from “vite”;.
import { NodePackageImporter } from “sass-embedded”;
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
api: “modern”, { scss: { preprocessorOptions: { scss: { preprocessorOptions
importers: [new NodePackageImporter()], }
}, }
}, }
}, }
});
Internally at build time, the compile function is now called.
Build errors that occur with Vite and their causes
When using the Package Importer
with Vite
using the sass
package, I encountered the following error at build time.
[vite:css] [sass] Error: TypeError: importer.findFileUrl is not a function
This is due to a conflict when trying to use the Vite
dependency sass-embedded
and the traditional Sass
package, as they are recognized as different instances of NodePackageImporter
. This error is due to the fact that the instances used inside Sass
and Vite
do not match.
It is hard to tell from the error, but the error is actually in the following section
https://github.com/sass/embedded-host-node/blob/59dde59163a58a33aa8180dbf8e23d2216913712/lib/src/importer-registry.ts#L84-L109
Solution to the error
To work around this error, you need to change your Vite
settings appropriately. Specifically, it is best to proceed with development assuming that Vite does not import Sass packages separately, but uses sass-embedded
provided by Vite
. official.
This issue is also raised in GitHub Issue #16438. Instead of using the traditional Sass
package, you should set css.preprocessorOptions
to assume sass-embedded. Note that it is or sass
but it doesn't work.
I thought I didn't get an error not too long ago?
I checked and sass-embedded
was included in peerDependencies
at this time, so it must have been an error since then.
https://github.com/vitejs/vite/commit/1025bb6d8f21c0cb9fe72405d42e0f91bb3f1d8e
Also, it seems that sass-embedded
is preferred, so you need to use sass-embedded
when using modern
in any case.
https://github.com/vitejs/vite/blob/f9691767ad763720065cc7c5c7f369f97b4e7ea8/packages/vite/src/node/plugins/css.ts#L2030-L2046
Since I was using npm
at the time of verification, I think the result would have been different if I had resolved peerDependencies
and used pnpm
for the installation.
Later, I also confirmed that if I actually used pnpm
and installed only sass
, the build finished successfully with the following code.
import { defineConfig } from “vite”;.
import { NodePackageImporter } from “sass”;
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
api: “modern”, { importers:[new NodePackageImporter } from “sass”; export default
importers: [new NodePackageImporter()], }
}, }
}, }
}, }
});
Efficient CSS loading
This should go without saying, but when using the Sass
package importer, if you load the entire package like @use “pkg:bulma”;
all CSS will be included in the build. This may result in a large CSS file after the build, as many unnecessary styles are included.
In such cases, it is recommended to specify and load only the necessary components. For example, if you want to use only some components of Bulma
, specify as follows
@use “pkg:bulma/sass/components/breadcrumb”;.
This way, only the necessary CSS is included in the build, thus compressing the post-build stylesheet and optimizing file size. Even so, unnecessary css will probably be included. In that case, you may need to write your own purge process.
If you want to use only common functions
or utilities
, it is better to set them to additionalData
and load them as before.
import { defineConfig } from “vite”;.
import react from “@vitejs/plugin-react”;
import { NodePackageImporter } from “sass-embedded”;
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
api: “modern”, importers: [new NodePackageImporter()], {
importers: [new NodePackageImporter()], { additionalData: `@use “pkg:bulma/sass/utilities” as
additionalData: `@use “pkg:bulma/sass/utilities” as utilities;;`,
}, }
}, }
}, }
plugins: [react()], `@use “pkg:bulma/sass/utilities” as utilities;;`, }, }
});
Top comments (0)