Skip to content

Commit

Permalink
Add breaking change page for legacy-js-api (#1193)
Browse files Browse the repository at this point in the history
  • Loading branch information
jathak authored Sep 19, 2024
1 parent fabc033 commit a9b0cd1
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 6 deletions.
1 change: 1 addition & 0 deletions source/_data/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ toc:
- Mixed Declarations: /documentation/breaking-changes/mixed-decls/
- <code>meta.feature-exists</code>: /documentation/breaking-changes/feature-exists/
- Color Functions: /documentation/breaking-changes/color-functions/
- Legacy JS API: /documentation/breaking-changes/legacy-js-api/
- Command Line: /documentation/cli/
:children:
- Dart Sass: /documentation/cli/dart-sass/
Expand Down
6 changes: 0 additions & 6 deletions source/_includes/silencing_deprecations.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,3 @@ option] in the JavaScript API.

[`--silence-deprecation` flag]: /documentation/cli/dart-sass/#silence-deprecation
[`silenceDeprecations` option]: /documentation/js-api/interfaces/Options/#silenceDeprecations

{% headsUp %}
This option is only available in the [modern JS API].

[modern JS API]: /documentation/js-api/#md:usage
{% endheadsUp %}
99 changes: 99 additions & 0 deletions source/documentation/breaking-changes/legacy-js-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: "Breaking Change: Legacy JS API"
introduction: |
Dart Sass originally used an API based on the one used by Node Sass, but
replaced it with a new, modern API in Dart Sass 1.45.0. The legacy JS API is
now deprecated and will be removed in Dart Sass 2.0.0.
---

## Migrating Usage

### Entrypoints

The legacy JS API had two entrypoints for compiling Sass: `render` and
`renderSync`, which took in an options object that included either `file` (to
compile a file) or `data` (to compile a string). The modern API has four:
`compile` and `compileAsync` for compiling a file and `compileString` and
`compileStringAsync` for compiling a string. These functions take a path or
source string as their first argument and then an object of all other options
as their second argument. Unlike `render`, which used a callback, `compileAsync`
and `compileStringAsync` return a promise instead.

See the [usage documentation] for more details.

[usage documentation]: /documentation/js-api/#md:usage

### Importers

Importers in the legacy API consisted of a single function that took in the
dependency rule URL and the URL of the containing stylesheet (as well as a
`done` callback for asynchronous importers) and return an object with either
a `file` path on disk or the `contents` of the stylesheet to be loaded.

Modern API [`Importer`]s instead contain two methods: `canonicalize`, which takes
in a rule URL and returns the canonical form of that URL; and `load`, which
takes in a canonical URL and returns an object with the contents
of the loaded stylesheet. This split ensures that the same module is only
loaded once and that relative URLs work consistently. Asynchronous importers
have both of these methods return promises.

There's also a special [`FileImporter`] that redirects all loads to existing
files on disk, which should be used when migrating from legacy importers that
returned a `file` instead of `contents`.

[`Importer`]: /documentation/js-api/interfaces/Importer/
[`ImporterResult`]: /documentation/js-api/interfaces/ImporterResult/
[`FileImporter`]: /documentation/js-api/interfaces/FileImporter/

### Custom Functions

In the legacy JS API, custom functions took a separate JS argument for each
Sass argument, with an additional `done` callback for asynchronous custom
functions. In the modern API, custom functions instead take a single JS argument
that contains a list of all Sass arguments, with asynchronous custom functions
returning a promise.

The modern API also uses a much more robust [`Value`] class that supports all
Sass value stypes, type assertions, and easy map and list lookups.

[`Value`]: /documentation/js-api/classes/Value/

### Bundlers

If you're using a bundler or other tool that calls the Sass API rather than
using it directly, you may need to change the configuration you pass to that
tool to tell it to use the modern API.

Webpack should already use the modern API by default, but if you're getting
warnings, set `api` to `"modern"` or `"modern-compiler"`.
See [Webpack's documentation] for more details.

Vite still defaults to the legacy API, but you can similarly switch it by
setting `api` to `"modern"` or `"modern-compiler"`. See [Vite's documentation]
for more details.

For other tools, check their documentation or issue tracker for information
about supporting the modern Sass API.

[Webpack's documentation]: https://webpack.js.org/loaders/sass-loader/#api
[Vite's documentation]: https://vitejs.dev/config/shared-options.html#css-preprocessoroptions

## Silencing Warnings

While the legacy JS API was marked as deprecated in Dart Sass 1.45.0 alongside
the release of the modern API, we began emitting warnings for using it starting
in Dart Sass 1.79.0. If you're not yet able to migrate to the modern API but
want to silence the warnings for now, you can pass `legacy-js-api` in the
`silenceDeprecations` option:

```js
const sass = require('sass');

const result = sass.renderSync({
silenceDeprecations: ['legacy-js-api'],
...
});
```

This will silence the warnings for now, but the legacy API will be removed
entirely in Dart Sass 2.0.0, so you should still plan to migrate off of it soon.

0 comments on commit a9b0cd1

Please sign in to comment.