-
Notifications
You must be signed in to change notification settings - Fork 355
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
Support running in a browser #25
Comments
We already isolate our This is something that would be nice to have, but I don't think I'm going to have time to implement or maintain it myself. |
I think just having the capability would be enough, for now. A sass_browser package could always implement the gritty bits. |
Since this is handled by a configured import, we can't really expose hooks for an external package. It has to be done in our codebase, since we handle the JS compilation. |
Would love to make SASS available natively to shared hosting, even if slow, by using a JS version in the site's files. DreamHost shared doesn't (easily, if at all) provide Ruby and has a cap on processes running, so nodeJS won't fly. I love SASS's simplistic syntax and would love to run/compile it "natively" from my website, instead of uploading CSS files. Also, I don't know enough about Dart/node/JS to do this myself, otherwise I would. I'm struggling to figure out whether to learn Dart or Go, Dart seems to be more tempting PR/marketing-wise. Oh, and as a student I don't have the resources to pay for a VPS or anything above, as I'm lucky to have shared hosting to begin with. I'm really tempted to learn Dart to see if this is possible... |
I think that one option could be if this module will ignore file parameter in compile api and use only data if there is no file system available as in case of browser. There is also a drop-in replacement of node file system api for browsers: https://github.com/jvilk/BrowserFS . But even after enabling this module for fs replacement in webpack sass npm is not usable due to other globals misses in browser. I have no previous experience with dart: is it something like target (node or browser) we could change to fix result js? I've not found any information for npm build in readme. |
@yatsyk It's more complicated than just dropping in a filesystem implementation. We'd probably want to do a separate compilation that targets the web. You'd need to start by adding a web-compatible implementation of the IO functions, but it's also not clear that the |
In terms of what sort of importers would be necessary for the web, I can think of two possibilities:
Do both of these sound reasonable? Are there others we'd want to support? Also, is the goal here just to have a Dart library that can be imported on the web, or would we also want to distribute a compiled JS library that could be depended on by non-Dart web apps? |
Based on @jathak's suggestion, I could also imagine an implementation agnostic file system abstraction "interface" that allows for asynchronous answers to request. On top of that, Sass code could be stored, fetched or even generated on the fly. |
I think for starters, it's fine to just do this without any importers at all, and leave it up to end-users to write importers if they want them. If we do add first-party importers, I think they should probably be distributed separately from Dart Sass itself. Running client-side is already kind of a niche feature, and I don't want to devote a ton of API surface in this package to it.
Ideally both. For example, it would be super cool to be able to make examples on the Sass site editable by users, and that would be a lot easier if it was available as just a chunk of JS. But starting with Dart support is probably a good idea. |
Has in-browser use been added? |
I would love to support and give some time to make this possible if you can show me how it should be done. |
See #25 (comment) for an overview of how to get started. |
It seems like renderSync could be run in the browser, if it relied solely on a custom importer to resolve all the file paths, used with a giant map of pathNames to scss contents. example: data.json "files": [
{
"filePath": "test.scss",
"scss": "@import 'demo';"
},
{
"filePath": "demo.scss",
"scss": "SCSS_FILE_CONTENTS"
}, renderSync({
data: "@import 'test",
importer: (url, prev, done) => {
const foundIndex = data.files.findIndex(file => file.filePath === url);
return {
file: data.files[foundIndex].filePath,
contents: data.files[foundIndex].scss,
}
},
}) The problem I hit was I can't just import renderSync. When importing
This assumes I'm running in node and not the browser. |
./node_modules/sass/sass.dart.js |
This comment has been minimized.
This comment has been minimized.
Could the getEnvironmentVariable environment be made optional? Line 91 in 55cb4fd
Edit: |
Some advances. Created an issue to node_preamble mbullington/node_preamble.dart#28 to fix an issue with wrapped global object that breaks access to self/window.location. |
@Pantura I have been trying to get some official support for this into Dart-SASS. |
I'm interested in taking a stab at this. Does anyone have a WIP repo/PR to share that gets half way there? I've done a browser build for ShareDB that has worked out well, maybe some techniques from there can be leveraged https://github.com/vizhub-core/sharedb-client-browser Notable tools I'm thinking of trying:
|
Just tried the custom file importer but it's badly documented with very few examples. I tried running this in the browser, to see if any console log would appear var {default: sass} = await import('https://jspm.dev/sass')
sass.compile('style.scss', {
// An importer for URLs like `bgcolor:orange` that generates a
// stylesheet with the given background color.
importers: [{
findFileUrl(url) {
console.log(url)
},
canonicalize(url) {
console.log(url)
},
load(canonicalUrl) {
console.log(url)
}
}]
}) there where 0 logs with one error that I was faced with:
that corsponds to this line: Guess it assumes that stuff is in a NodeJS env with a global process... Would be nice if things could get less dependent on NodeJS modules to also work in browser and also in Deno |
Is there a way to stub out Similar to what this does https://www.npmjs.com/package/rollup-plugin-polyfill-node |
Woop woop! 🎉 |
This is exciting! How can we run it in a browser? Is there a working reference example to study? Thanks! |
See: https://github.com/sass/dart-sass#dart-sass-in-the-browser. TLDR: you only need to load the |
I want to use |
You can pass your own importers as part of the settings object when calling function canonicalize(url) {
return new URL(url, window.location.toString())
}
async function load(canonicalUrl) {
console.log(`Importing ${canonicalUrl} (async)`)
const response = await fetch(canonicalUrl)
if (!response.ok) throw new Error(`Failed to fetch ${canonicalUrl}: ${response.status} (${response.statusText})`);
const contents = await response.text()
return {
contents,
syntax: canonicalUrl.pathname.endsWith('.sass') ? 'indented' : 'scss'
}
}
const importers = [{ canonicalize, load }]
const compiled = await sass.compileStringAsync('...', { importers }) And the sync version function canonicalize(url) {
return new URL(url, window.location.toString())
}
function load(canonicalUrl) {
console.log(`Importing ${canonicalUrl} (sync)`)
const request = new XMLHttpRequest();
request.onreadystatechange = () => {
if (request.readyState === 4 && request.status !== 200)
throw new Error(`Failed to fetch ${canonicalUrl}: ${request.status} (${request.statusText})`);
};
request.open("GET", canonicalUrl, false);
request.send();
return {
contents: request.responseText,
syntax: canonicalUrl.pathname.endsWith('.sass') ? 'indented' : 'scss'
};
}
const importers = [{ canonicalize, load }]
const compiled = sass.compileString('...', { importers }) |
Thx for this async demo. tried with some content delivers that would be able to convert cjs to esm on the fly. but everyone seems to fail await import('https://esm.sh/sass') // fail
await import('https://cdn.jsdelivr.net/npm/sass/+esm') // fail
await import('https://unpkg.com/sass') // fail
var {default: sass} = await import('https://jspm.dev/sass')
sass.compileString('') // fail sass.dart.js:18277 Uncaught TypeError: Cannot read properties of undefined (reading 'isTTY') Seems like it tries to load so many unnecessary stuff into the browser fs, chokidar, util, buffer, streams, readline which to me seems all pointless to have in a browser bundle |
@jimmywarting I don't think the version of Dart Sass with browser support has been released yet -- can you confirm @nex3? |
i would be nice to see a official ESM release that isn't in cjs in any form |
@jgerigmeyer is correct, this will be released as part of Dart Sass 1.63.0 in a week or two. As the README indicates, it will be able to run in pure ESM mode without any bundling. |
This would enable in-browser use, use in a service worker, etc.
The text was updated successfully, but these errors were encountered: