From e4d0b6e9e6f14cfe64b935169519e89bf5c7dbff Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 9 Jun 2023 16:31:08 -0700 Subject: [PATCH 1/2] Re-enable support for default exports See #2008 --- CHANGELOG.md | 9 +++++++++ tool/grind.dart | 38 ++++++++++++++++++++++++++++++++++++++ tool/grind/utils.dart | 20 ++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 747deb5d2..09720dc0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## 1.63.4 +### JavaScript API + +* Re-enable support for `import sass from 'sass'` when loading the package from + an ESM module in Node.js. However, this syntax is now deprecated; ESM users + should use `import * as sass from 'sass'` instead. + + On the browser and other ESM-only platforms, only `import * as sass from + 'sass'` is supported. + ### Embedded Sass * Fix a race condition where closing standard input while requests are in-flight diff --git a/tool/grind.dart b/tool/grind.dart index 84bec47c6..95cd60a8b 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -101,6 +101,10 @@ void main(List args) { }; pkg.addAllTasks(); + + afterTask("pkg-npm-dev", _addDefaultExport); + afterTask("pkg-npm-release", _addDefaultExport); + grind(args); } @@ -243,3 +247,37 @@ dart run protoc_plugin "\$@" Platform.environment["PATH"]! })); } + +/// After building the NPM package, add default exports to +/// `build/npm/sass.node.mjs`. +/// +/// See sass/dart-sass#2008. +void _addDefaultExport() { + var buffer = StringBuffer(); +buffer.writeln(File("build/npm/sass.node.mjs").readAsStringSync()); + +buffer.writeln(""" +let printedDefaultExportDeprecation = false; +function defaultExportDeprecation() { + if (printedDefaultExportDeprecation) return; + printedDefaultExportDeprecation = true; + console.error( + "`import sass from 'sass'` is deprecated.\\n" + + "Please use `import * as sass from 'sass'` instead."); +} +"""); + +buffer.writeln("export default {"); +for (var export in pkg.jsEsmExports.value!) { + buffer.write(""" + get $export() { + defaultExportDeprecation(); + return _cliPkgExports.$export; + }, +"""); +} + +buffer.writeln("};"); + +File("build/npm/sass.node.mjs").writeAsStringSync(buffer.toString()); +} diff --git a/tool/grind/utils.dart b/tool/grind/utils.dart index 1135865ee..9d230cb0a 100644 --- a/tool/grind/utils.dart +++ b/tool/grind/utils.dart @@ -2,6 +2,7 @@ // MIT-style license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -9,6 +10,9 @@ import 'package:cli_pkg/cli_pkg.dart' as pkg; import 'package:grinder/grinder.dart'; import 'package:path/path.dart' as p; +// Work around the lack of google/grinder.dart#402. +import 'package:grinder/src/singleton.dart'; + /// Options for [run] that tell Git to commit using SassBot's name and email. final sassBotEnvironment = RunOptions(environment: { "GIT_AUTHOR_NAME": pkg.botName.value, @@ -75,3 +79,19 @@ String cloneOrCheckout(String url, String ref, {String? name}) { return path; } + +/// Registers [callback] to run after the task named [taskName]. +/// +/// This must be called after the base [taskName] is registered. +void afterTask(String taskName, FutureOr callback()) { + // This takes advantage of the fact that Grinder's task list is mutable to + // override the existing task with our new one. + var index = grinder.tasks.indexWhere((task) => task.name == taskName); + if (index == -1) fail("There is no task named $taskName."); + + var oldTask = grinder.tasks[index]; + grinder.tasks[index] = GrinderTask(taskName, description: oldTask.description, depends: oldTask.depends, taskFunction: (TaskArgs args) async { + await oldTask.execute(context, args); + await callback(); + }); +} From 5ba656bc49d9659c506b2e0f5af73ca0517458fd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 9 Jun 2023 16:44:54 -0700 Subject: [PATCH 2/2] Reformat --- tool/grind.dart | 16 ++++++++-------- tool/grind/utils.dart | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tool/grind.dart b/tool/grind.dart index 95cd60a8b..2a6692c54 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -254,9 +254,9 @@ dart run protoc_plugin "\$@" /// See sass/dart-sass#2008. void _addDefaultExport() { var buffer = StringBuffer(); -buffer.writeln(File("build/npm/sass.node.mjs").readAsStringSync()); + buffer.writeln(File("build/npm/sass.node.mjs").readAsStringSync()); -buffer.writeln(""" + buffer.writeln(""" let printedDefaultExportDeprecation = false; function defaultExportDeprecation() { if (printedDefaultExportDeprecation) return; @@ -267,17 +267,17 @@ function defaultExportDeprecation() { } """); -buffer.writeln("export default {"); -for (var export in pkg.jsEsmExports.value!) { - buffer.write(""" + buffer.writeln("export default {"); + for (var export in pkg.jsEsmExports.value!) { + buffer.write(""" get $export() { defaultExportDeprecation(); return _cliPkgExports.$export; }, """); -} + } -buffer.writeln("};"); + buffer.writeln("};"); -File("build/npm/sass.node.mjs").writeAsStringSync(buffer.toString()); + File("build/npm/sass.node.mjs").writeAsStringSync(buffer.toString()); } diff --git a/tool/grind/utils.dart b/tool/grind/utils.dart index 9d230cb0a..56b9b7458 100644 --- a/tool/grind/utils.dart +++ b/tool/grind/utils.dart @@ -90,7 +90,9 @@ void afterTask(String taskName, FutureOr callback()) { if (index == -1) fail("There is no task named $taskName."); var oldTask = grinder.tasks[index]; - grinder.tasks[index] = GrinderTask(taskName, description: oldTask.description, depends: oldTask.depends, taskFunction: (TaskArgs args) async { + grinder.tasks[index] = GrinderTask(taskName, + description: oldTask.description, + depends: oldTask.depends, taskFunction: (TaskArgs args) async { await oldTask.execute(context, args); await callback(); });