From 387f42cbea9c2169c11c4b17f56ce49e29129b88 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Thu, 19 Sep 2024 14:23:07 -0700 Subject: [PATCH 1/3] Add breaking change page for legacy-js-api --- .../_includes/silencing_deprecations.liquid | 6 -- .../breaking-changes/legacy-js-api.md | 95 +++++++++++++++++++ 2 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 source/documentation/breaking-changes/legacy-js-api.md diff --git a/source/_includes/silencing_deprecations.liquid b/source/_includes/silencing_deprecations.liquid index 2e4d1c1c0..ea34d0e7c 100644 --- a/source/_includes/silencing_deprecations.liquid +++ b/source/_includes/silencing_deprecations.liquid @@ -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 %} diff --git a/source/documentation/breaking-changes/legacy-js-api.md b/source/documentation/breaking-changes/legacy-js-api.md new file mode 100644 index 000000000..0f4b0cc69 --- /dev/null +++ b/source/documentation/breaking-changes/legacy-js-api.md @@ -0,0 +1,95 @@ +--- +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. 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 +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. + +[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. From d07f58601504b7254a8bee8396b0b850b63e813f Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Thu, 19 Sep 2024 14:26:41 -0700 Subject: [PATCH 2/3] Add TOC entry --- source/_data/documentation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/source/_data/documentation.yml b/source/_data/documentation.yml index a6d1bcbec..3692c775c 100644 --- a/source/_data/documentation.yml +++ b/source/_data/documentation.yml @@ -76,6 +76,7 @@ toc: - Functions and Mixins Beginning with --: /documentation/breaking-changes/css-function-mixin/ - Mixed Declarations: /documentation/breaking-changes/mixed-decls/ - meta.feature-exists: /documentation/breaking-changes/feature-exists/ + - Legacy JS API: /documentation/breaking-changes/legacy-js-api/ - Command Line: /documentation/cli/ :children: - Dart Sass: /documentation/cli/dart-sass/ From e20b2dd9057c5caab1e480dba170916a0df0a402 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Thu, 19 Sep 2024 15:13:11 -0700 Subject: [PATCH 3/3] Code review --- .../breaking-changes/legacy-js-api.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/documentation/breaking-changes/legacy-js-api.md b/source/documentation/breaking-changes/legacy-js-api.md index 0f4b0cc69..1bfd64c05 100644 --- a/source/documentation/breaking-changes/legacy-js-api.md +++ b/source/documentation/breaking-changes/legacy-js-api.md @@ -33,16 +33,17 @@ 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. Asynchronous importers have both of these methods -return promises. +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/ +[`Importer`]: /documentation/js-api/interfaces/Importer/ +[`ImporterResult`]: /documentation/js-api/interfaces/ImporterResult/ +[`FileImporter`]: /documentation/js-api/interfaces/FileImporter/ ### Custom Functions @@ -52,10 +53,10 @@ 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 -type assertions and easy map and list lookups. +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/ +[`Value`]: /documentation/js-api/classes/Value/ ### Bundlers @@ -71,6 +72,9 @@ 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