Skip to content

Commit c62fe6a

Browse files
authored
Fix crash in browser when running alongside NextJS (#2114)
* Fix crash in browser when running alongside NextJS Fixes #2113 * update sass_api pubspec
1 parent 887c511 commit c62fe6a

18 files changed

+62
-70
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 1.69.2
2+
3+
### JS API
4+
5+
* Fix a bug where Sass crashed when running in the browser if there was a global
6+
variable named `process`.
7+
18
## 1.69.1
29

310
* No user-visible changes.

lib/src/async_compile.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:convert';
66

7+
import 'package:cli_pkg/js.dart';
78
import 'package:path/path.dart' as p;
89

910
import 'ast/sass.dart';

lib/src/async_import_cache.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:cli_pkg/js.dart';
56
import 'package:collection/collection.dart';
67
import 'package:meta/meta.dart';
78
import 'package:package_config/package_config_types.dart';

lib/src/compile.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
// DO NOT EDIT. This file was generated from async_compile.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: c2982db43bcd56f81cab3f51b5669e0edd3cfafb
8+
// Checksum: 5178e366228bde7854df12221393857bb3022628
99
//
1010
// ignore_for_file: unused_import
1111

1212
export 'async_compile.dart';
1313

1414
import 'dart:convert';
1515

16+
import 'package:cli_pkg/js.dart';
1617
import 'package:path/path.dart' as p;
1718

1819
import 'ast/sass.dart';

lib/src/deprecation.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5+
import 'package:cli_pkg/js.dart';
56
import 'package:collection/collection.dart';
67
import 'package:pub_semver/pub_semver.dart';
78

8-
import 'io.dart';
99
import 'util/nullable.dart';
1010

1111
/// A deprecated feature in the language.

lib/src/import_cache.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
// DO NOT EDIT. This file was generated from async_import_cache.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: ff52307a3bc93358ddc46f1e76120894fa3e071f
8+
// Checksum: 342e907cf10e1dd80d7045fc32db43c74376654e
99
//
1010
// ignore_for_file: unused_import
1111

12+
import 'package:cli_pkg/js.dart';
1213
import 'package:collection/collection.dart';
1314
import 'package:meta/meta.dart';
1415
import 'package:package_config/package_config_types.dart';

lib/src/io/interface.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@ bool get isMacOS => throw '';
1919
/// Returns whether or not stdout is connected to an interactive terminal.
2020
bool get hasTerminal => throw '';
2121

22-
/// Whether we're running as JS (browser or Node.js).
23-
const bool isJS = false;
24-
25-
/// Whether we're running as Node.js (not browser or Dart VM).
26-
bool get isNode => throw '';
27-
28-
/// Whether we're running as browser (not Node.js or Dart VM).
29-
bool get isBrowser => throw '';
30-
3122
/// Whether this process is connected to a terminal that supports ANSI escape
3223
/// sequences.
3324
bool get supportsAnsiEscapes => throw '';

lib/src/io/js.dart

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
import 'dart:async';
66
import 'dart:convert';
7-
import 'dart:js_util';
87

8+
import 'package:cli_pkg/js.dart';
99
import 'package:js/js.dart';
1010
import 'package:node_interop/fs.dart';
1111
import 'package:node_interop/node_interop.dart' hide process;
12+
import 'package:node_interop/util.dart';
1213
import 'package:path/path.dart' as p;
1314
import 'package:source_span/source_span.dart';
1415
import 'package:watcher/watcher.dart';
@@ -17,7 +18,12 @@ import '../exception.dart';
1718
import '../js/chokidar.dart';
1819

1920
@JS('process')
20-
external final Process? process; // process is null in the browser
21+
external final Process? _nodeJsProcess; // process is null in the browser
22+
23+
/// The Node.JS [Process] global variable.
24+
///
25+
/// This value is `null` when running the script is not run from Node.JS
26+
Process? get _process => isNodeJs ? _nodeJsProcess : null;
2127

2228
class FileSystemException {
2329
final String message;
@@ -29,23 +35,23 @@ class FileSystemException {
2935
}
3036

3137
void safePrint(Object? message) {
32-
if (process case var process?) {
38+
if (_process case var process?) {
3339
process.stdout.write("${message ?? ''}\n");
3440
} else {
3541
console.log(message ?? '');
3642
}
3743
}
3844

3945
void printError(Object? message) {
40-
if (process case var process?) {
46+
if (_process case var process?) {
4147
process.stderr.write("${message ?? ''}\n");
4248
} else {
4349
console.error(message ?? '');
4450
}
4551
}
4652

4753
String readFile(String path) {
48-
if (!isNode) {
54+
if (!isNodeJs) {
4955
throw UnsupportedError("readFile() is only supported on Node.js");
5056
}
5157
// TODO(nweiz): explicitly decode the bytes as UTF-8 like we do in the VM when
@@ -69,23 +75,23 @@ Object? _readFile(String path, [String? encoding]) =>
6975
_systemErrorToFileSystemException(() => fs.readFileSync(path, encoding));
7076

7177
void writeFile(String path, String contents) {
72-
if (!isNode) {
78+
if (!isNodeJs) {
7379
throw UnsupportedError("writeFile() is only supported on Node.js");
7480
}
7581
return _systemErrorToFileSystemException(
7682
() => fs.writeFileSync(path, contents));
7783
}
7884

7985
void deleteFile(String path) {
80-
if (!isNode) {
86+
if (!isNodeJs) {
8187
throw UnsupportedError("deleteFile() is only supported on Node.js");
8288
}
8389
return _systemErrorToFileSystemException(() => fs.unlinkSync(path));
8490
}
8591

8692
Future<String> readStdin() async {
87-
var process_ = process;
88-
if (process_ == null) {
93+
var process = _process;
94+
if (process == null) {
8995
throw UnsupportedError("readStdin() is only supported on Node.js");
9096
}
9197
var completer = Completer<String>();
@@ -96,15 +102,15 @@ Future<String> readStdin() async {
96102
});
97103
// Node defaults all buffers to 'utf8'.
98104
var sink = utf8.decoder.startChunkedConversion(innerSink);
99-
process_.stdin.on('data', allowInterop(([Object? chunk]) {
105+
process.stdin.on('data', allowInterop(([Object? chunk]) {
100106
sink.add(chunk as List<int>);
101107
}));
102-
process_.stdin.on('end', allowInterop(([Object? _]) {
108+
process.stdin.on('end', allowInterop(([Object? _]) {
103109
// Callback for 'end' receives no args.
104110
assert(_ == null);
105111
sink.close();
106112
}));
107-
process_.stdin.on('error', allowInterop(([Object? e]) {
113+
process.stdin.on('error', allowInterop(([Object? e]) {
108114
printError('Failed to read from stdin');
109115
printError(e);
110116
completer.completeError(e!);
@@ -121,7 +127,7 @@ String _cleanErrorMessage(JsSystemError error) {
121127
}
122128

123129
bool fileExists(String path) {
124-
if (!isNode) {
130+
if (!isNodeJs) {
125131
throw UnsupportedError("fileExists() is only supported on Node.js");
126132
}
127133
return _systemErrorToFileSystemException(() {
@@ -142,7 +148,7 @@ bool fileExists(String path) {
142148
}
143149

144150
bool dirExists(String path) {
145-
if (!isNode) {
151+
if (!isNodeJs) {
146152
throw UnsupportedError("dirExists() is only supported on Node.js");
147153
}
148154
return _systemErrorToFileSystemException(() {
@@ -163,7 +169,7 @@ bool dirExists(String path) {
163169
}
164170

165171
void ensureDir(String path) {
166-
if (!isNode) {
172+
if (!isNodeJs) {
167173
throw UnsupportedError("ensureDir() is only supported on Node.js");
168174
}
169175
return _systemErrorToFileSystemException(() {
@@ -180,7 +186,7 @@ void ensureDir(String path) {
180186
}
181187

182188
Iterable<String> listDir(String path, {bool recursive = false}) {
183-
if (!isNode) {
189+
if (!isNodeJs) {
184190
throw UnsupportedError("listDir() is only supported on Node.js");
185191
}
186192
return _systemErrorToFileSystemException(() {
@@ -202,15 +208,15 @@ Iterable<String> listDir(String path, {bool recursive = false}) {
202208
}
203209

204210
DateTime modificationTime(String path) {
205-
if (!isNode) {
211+
if (!isNodeJs) {
206212
throw UnsupportedError("modificationTime() is only supported on Node.js");
207213
}
208214
return _systemErrorToFileSystemException(() =>
209215
DateTime.fromMillisecondsSinceEpoch(fs.statSync(path).mtime.getTime()));
210216
}
211217

212218
String? getEnvironmentVariable(String name) {
213-
var env = process?.env;
219+
var env = _process?.env;
214220
return env == null ? null : getProperty(env as Object, name) as String?;
215221
}
216222

@@ -229,36 +235,21 @@ T _systemErrorToFileSystemException<T>(T callback()) {
229235
/// from `node_interop` declares `isTTY` as always non-nullably available, but
230236
/// in practice it's undefined if stdout isn't a TTY.
231237
/// See: https://github.com/pulyaevskiy/node-interop/issues/93
232-
bool get hasTerminal => process?.stdout.isTTY == true;
233-
234-
bool get isWindows => process?.platform == 'win32';
235-
236-
bool get isMacOS => process?.platform == 'darwin';
237-
238-
const bool isJS = true;
239-
240-
/// The fs module object, used to check whether this has been loaded as Node.
241-
///
242-
/// It's safest to check for a library we load in manually rather than one
243-
/// that's ambiently available so that we don't get into a weird state in
244-
/// environments like VS Code that support some Node.js libraries but don't load
245-
/// Node.js entrypoints for dependencies.
246-
@JS('fs')
247-
external final Object? _fsNullable;
238+
bool get hasTerminal => _process?.stdout.isTTY == true;
248239

249-
bool get isNode => _fsNullable != null;
240+
bool get isWindows => _process?.platform == 'win32';
250241

251-
bool get isBrowser => isJS && !isNode;
242+
bool get isMacOS => _process?.platform == 'darwin';
252243

253244
// Node seems to support ANSI escapes on all terminals.
254245
bool get supportsAnsiEscapes => hasTerminal;
255246

256-
int get exitCode => process?.exitCode ?? 0;
247+
int get exitCode => _process?.exitCode ?? 0;
257248

258-
set exitCode(int code) => process?.exitCode = code;
249+
set exitCode(int code) => _process?.exitCode = code;
259250

260251
Future<Stream<WatchEvent>> watchDir(String path, {bool poll = false}) {
261-
if (!isNode) {
252+
if (!isNodeJs) {
262253
throw UnsupportedError("watchDir() is only supported on Node.js");
263254
}
264255
var watcher = chokidar.watch(

lib/src/io/vm.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ bool get isMacOS => io.Platform.isMacOS;
2222

2323
bool get hasTerminal => io.stdout.hasTerminal;
2424

25-
const bool isJS = false;
26-
27-
bool get isNode => false;
28-
29-
bool get isBrowser => false;
30-
3125
bool get supportsAnsiEscapes {
3226
if (!hasTerminal) return false;
3327

lib/src/js/compile.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import 'utils.dart';
2727
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
2828
/// details.
2929
NodeCompileResult compile(String path, [CompileOptions? options]) {
30-
if (!isNode) {
30+
if (!isNodeJs) {
3131
jsThrow(JsError("The compile() method is only available in Node.js."));
3232
}
3333
var color = options?.alertColor ?? hasTerminal;
@@ -88,7 +88,7 @@ NodeCompileResult compileString(String text, [CompileStringOptions? options]) {
8888
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
8989
/// details.
9090
Promise compileAsync(String path, [CompileOptions? options]) {
91-
if (!isNode) {
91+
if (!isNodeJs) {
9292
jsThrow(JsError("The compileAsync() method is only available in Node.js."));
9393
}
9494
var color = options?.alertColor ?? hasTerminal;

0 commit comments

Comments
 (0)