Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS API: Create a method to get SASS AST #88

Open
AleshaOleg opened this issue Jan 3, 2017 · 26 comments
Open

JS API: Create a method to get SASS AST #88

AleshaOleg opened this issue Jan 3, 2017 · 26 comments
Labels
enhancement JavaScript Issues particular to the Node.js distribution low priority

Comments

@AleshaOleg
Copy link

I want to implement SASS parser for @postcss - written by @ai. But for this purpose I need convert SASS AST to PostCSS AST. It would be great, if I can use official parser from @sass (i'm really appreciate that you implemented SASS on compiled to JS language).

So, @nex3 - what you think if I will try to write a new method which return SASS AST? I'm newbie in @Dart, so it will take some time to learn it:D I think it will be a method very similar to render() from node-sass.

@ai
Copy link

ai commented Jan 3, 2017

I really like this idea. We could replace postcss-scss with 100% compatible PostCSS parser to SCSS and Sass syntaxes.

I think our users will happy. For example, Sass users will get a Stylelint support.

@nex3
Copy link
Contributor

nex3 commented Jan 6, 2017

Using our current compiler Dart to JavaScript, it's very difficult to expose Dart classes to JS in a usable way. I know @jmesserly was hoping to look into an alternate compiler that would make this easier, but it's fairly likely that it won't have the performance we need.

In the long term I hope this will get easier, but it's not a short-term goal. We're intentionally keeping the API surface small even in pure Dart; we don't want to commit to maintaining anything backwards-compatible while development is still so active.

@nex3 nex3 added enhancement JavaScript Issues particular to the Node.js distribution low priority labels Jan 6, 2017
@nex3 nex3 changed the title Create a method to get SASS AST. JS API: Create a method to get SASS AST Jan 6, 2017
@ai
Copy link

ai commented Jan 7, 2017

@nex3 sad to know that Dart classes problem :(. In this case we could return simple non-class object.

What we should do right now? What is the best way to parse Sass to PostCSS AST in current API?

Should we write a own parser from scratch (but I think it will be bad for Sass ecosystem). Or should we send PR todart-sass with extra methods?

@nex3
Copy link
Contributor

nex3 commented Jan 7, 2017

I suppose we could just dump a bunch of nested maps, but that sounds like it would be a pretty crummy API—and it would still have the same backwards-compatibility issues as a proper object-oriented API 😕. Or we could wait until we get real info on the performance implications of the alternative compiler and see if it makes sense to switch over.

If you're chomping at the bit to do some work here, though, you could create a Dart Sass visitor, written in Dart, that traverses a Sass AST and emits a PostCSS AST. Instantiating JS classes from Dart is easy. I'm not sure what the best way to expose that would be, since it would have to be compiled into the same JS blob as the rest of Dart Sass, but we could figure that out later.

@ai
Copy link

ai commented Jan 7, 2017

@nex3 Dart Sass visitor looks like great idea. Doyou have some docs or examples?

@nex3
Copy link
Contributor

nex3 commented Jan 7, 2017

You can look at the perform visitor as an example.

@nex3
Copy link
Contributor

nex3 commented Feb 1, 2017

There's no clean way to do this as a dependency, since the Dart package doesn't publicly export the AST types at the moment—I'd recommend just forking this repository and adding the visitor locally for the time being.

In general, you import Dart code from dependencies using package: URLs. For example:

import "package:sass/sass.dart" as sass;

void main(List<String> args) {
  print(sass.render(args.first));
}

You declare dependencies in a pubspec.yaml file at the root of your package:

name: my_pkg
version: 1.2.3

dependencies:
  sass:

and run pub get to fetch them in a way that can be imported using package: URLs.

@ai
Copy link

ai commented Feb 1, 2017

@nex3 Maybe it will be more easy to send PR with private visitor API? If you will find a better way, you will be able to change this visitor API without major updates, since it will be a private API for single use case.

@AleshaOleg
Copy link
Author

@nex3 sorry, for deleting comment which I wrote before. We don't wont to fork, because we'll need to update this fork every time, as you update your version. Is it really no other way to do this? Can you describe a "not clean" way?

@AleshaOleg
Copy link
Author

Please look to this example, is this ok to import files in this way from package?

@nex3
Copy link
Contributor

nex3 commented Feb 1, 2017

We don't currently have the resources to devote to making a nice, well-supported version of this. You're going to need to update your code frequently to deal with upstream changes—there's no way around this in the short term, because the APIs are still in flux. Whether you fork or import libraries from src/ (which indicates that they're private), you're likely to get broken down the line.

I encourage you to think about this work as a proof-of-concept or prototype for now. Once we release 1.0.0, I'll spend some time factoring this out into separate packages, including a sass_ast package (or something like that) which you can interface with in a more stable way.

@matthew-dean
Copy link

FYI: I wrote a Less-AST-to-PostCSS-AST plugin, and while it worked, according to at least one person who tested it, it ended up being slower to convert the ASTs then to simply output CSS and re-parse into PostCSS. So don't automatically assume you're saving any time by skipping stringifying / re-parsing. It may seem more direct in theory, but you can't make that assumption.

@octref
Copy link

octref commented Nov 18, 2019

Hi, this is Pine from VS Code team. I work on the builtin SCSS support in VS Code, and recently I started contributing to the SCSS extension.

A parser / AST would be very helpful for me to continue maintain SCSS support, because I no longer have to update it from time to time to accommodate new language syntax changes.

However, IMO, language team should really own the language server themselves. That's the reason why TypeScript has really good support in the editors. Many popular languages, such as Rust, Go, Swift have also realized this and start to develop their language servers based on the core parser / compiler APIs. I understand that SASS originally started with Ruby and C/C++ and providing these interfaces hasn't been a goal, but lack of such API means it's much harder to develop language tooling for it.

Also there's currently no language support for the indented SASS syntax by any editor. I really want to do it, but if that means I would have to write a parser for indented SASS to begin with, I really don't have enough time.

@nex3
Copy link
Contributor

nex3 commented Nov 19, 2019

Creating a language-server protocol implementation for Sass is on our roadmap, but it's non-trivial and we have a very small team with a lot of responsibilities. The Sass ecosystem relies heavily on user contributions; if this is something users want to see, the best way to make it happen is to contribute your time to its development or helping to find someone else who's interested in working on it. We'd be thrilled to collaborate.

@octref
Copy link

octref commented Nov 19, 2019

@nex3 Thanks for getting back to me! Your last comment was in 2017. Can you post an updated version as to what would it take to get a JS API for getting the AST from raw SCSS/SASS strings?

@nex3
Copy link
Contributor

nex3 commented Nov 19, 2019

Just to be clear, for the specific use-case of IDE support, I think creating an LSP implementation in Dart where it'll have access to static analysis information from the infrastructure we're building for the Sass migrator is a better path forward than exposing an AST to JS.

That said, I do still think exposing an AST to JS would generally be valuable. Doing that would involve using Dart's JS interop to define types for the JS classes we want to expose (like this), a visitor to traverse a Sass AST and return a JS AST, and some build infrastructure so we can create a separate package for that AST (that part I can handle).

@gregjacobs
Copy link

Just wanted to chime in here: this would also be useful for writing source code transformation utilities (like the one I'm trying to write!)

There doesn't currently seem to be a good parser out there for sass/scss:

  • postcss-scss (and postcss in general) doesn't parse property values
  • salesforce-ux/scss-parser has issues such that if whitespace is in a spot that it doesn't expect then it fails
  • gonzales-pe seems to be the closest to a fully-working implementation, but even it has some things missing like parsing interpolation between quotes (#301)

Would really be good to have the parser/AST exposed at the source of the language so that we can't go wrong!

@TheJaredWilcurt
Copy link

TheJaredWilcurt commented Jan 21, 2021

This would enable so much, better linting, code quality enforcement, code mods, reporting/analysis tools.

Even if the JS API outputs a Sass AST that doesn't match anything else, but is consistent, someone else could create a translation library that ports it to other AST streams. These tasks could even be done separately to make it easier to achieve. Outputting any AST, and then when time permits having the translation layer be built in later. This allows the community to contribute to the translation layer (which would be easier to help with).

@TheJaredWilcurt
Copy link

Still waiting on this. Sasslint (linter that supports .sass files) has been unmaintained for 2 years and is building up security vulnerabilities from it's older dependencies.

If this could be prioritized then it would unlock tons of tooling potential that isn't reliant on partially complete, buggy, home-made ASTs.

Any way to fund this or something, if it was all JS I'd help out, but I have no desire to learn Dart.

@nex3
Copy link
Contributor

nex3 commented May 24, 2021

We are unlikely to have time to implement this in the near future. For our purposes, the existing postcss-scss parser has generally been sufficient.

@forivall
Copy link

Thanks. I'll consider building my own parser then, at the very least, to support vscode tooling. Good to know, so that we're not doubling the effort.

@niksy
Copy link

niksy commented Aug 19, 2021

Now that there is sass_api Dart package, are there any plans for making it available in JS?

I’ve tried compiling Dart version to JS with dart2js but I’m getting errors such as:

sass_api.js:4460 Uncaught TypeError: J.getInterceptor$s(...).get$codeUnits is not a function
    at Object.get$codeUnits$s (sass_api.js:4460)
    at Object.SourceFile$fromString (file.dart:62)
    at Object.SpanScanner$ (span_scanner.dart:63)
    at Object.Parser$ (parser.dart:52)
    at Object.Parser_parseIdentifier (parser.dart:32)
    at Object.main (sass_api.dart:30)
    at callMain (js_helper.dart:2684)
    at js_helper.dart:2684
    at js_helper.dart:2684
    at dartProgram (js_helper.dart:2684)

@nex3
Copy link
Contributor

nex3 commented Aug 19, 2021

The existence of Dart's sass_api package doesn't make it particularly easier to expose a JS API. It would still require a manual implementation of a translation layer, which we are unlikely to have time to implement ourselves.

@TheJaredWilcurt
Copy link

I think it's worth noting that postcss-scss is an insufficient solution in comparison to an official AST provided by Sass.

  • It does not support .sass syntax - This is a huge blocker, half of the language just doesn't work
  • Has a homemade parser that is not in sync with the official language or implementation
    • Can get out of date
    • Prone to errors, bugs, and edge cases
    • Forces someone else to maintain a parser that could be automated, (resulting in only supporting half the language)
  • Requires adoption of much more tooling (not just a linter, but an entire postcss suite of libraries, far more effort to adopt and plug everything in).
    • I don't want to buy into the entire PostCSS ecosystem just so I can use a linter that doesn't work on 90% of my files (.sass).

Again, happy to fund this.

@nex3
Copy link
Contributor

nex3 commented Aug 23, 2021

It's not a question of whether it would be valuable, we simply don't have time to work on it. If you've got funding available, we'd be happy to work with a contractor you've funded to help make this happen.

@niksy
Copy link

niksy commented Sep 1, 2021

If anyone’s interested, I’ve created module which extracts render errors and deprecations to machine readable format (JSON), and it’s used in related Stylelint plugin.

There’s a proposal to make this part of the specification, but if anyone’s looking for something similar in the meantime, glad I could help. Suggestions welcome!

ctsstc added a commit to LogicHappens/musical-conquest that referenced this issue Nov 7, 2021
Fixes #41

Updates redundant styles to a new container in index. I like the component not owning the styling as well. The container in index also handles flex styling on the children elements that are contained.

Remove sass from prettier because it doesn't support sass 🤯

Relevant Discord Chat:
found out while digging a few things that even though sass and scss are super close there's a lot less tooling and underlying architecture issues that lacks sass support :' (
I guess prettier doesn't support it; and likely because of these other underlying issues, I guess google is running the dart sass team but doesn't have time to do what we all need : (
prettier/prettier#4948
mrmlnc/vscode-scss#127
sass/dart-sass#88
Interesting long technical read though
TLDR; needs to have support for ASTs which allow code tools to help code; dart has no easy way to expose it
It's finally on a roadmap but then they said they won't ever get to it lol
classic product things
ctsstc added a commit to LogicHappens/musical-conquest that referenced this issue Nov 7, 2021
Fixes #41

Updates redundant styles to a new container in index. I like the component not owning the styling as well. The container in index also handles flex styling on the children elements that are contained.

Remove sass from prettier because it doesn't support sass 🤯

Relevant Discord Chat:
found out while digging a few things that even though sass and scss are super close there's a lot less tooling and underlying architecture issues that lacks sass support :' (
I guess prettier doesn't support it; and likely because of these other underlying issues, I guess google is running the dart sass team but doesn't have time to do what we all need : (
prettier/prettier#4948
mrmlnc/vscode-scss#127
sass/dart-sass#88
Interesting long technical read though
TLDR; needs to have support for ASTs which allow code tools to help code; dart has no easy way to expose it
It's finally on a roadmap but then they said they won't ever get to it lol
classic product things
nex3 pushed a commit that referenced this issue May 10, 2023
nex3 added a commit to nex3/postcss that referenced this issue Jul 24, 2024
This makes it easier to extend these classes and override these fields
with information that's derived from other, internal fields.

This helps enable sass/dart-sass#88
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement JavaScript Issues particular to the Node.js distribution low priority
Projects
None yet
Development

No branches or pull requests

9 participants