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

Default to Dart-Sass and add backwards compatibility for node-sass #1847

Merged
merged 2 commits into from
Aug 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@
"mocha": "^5.1.1",
"ncp": "^2.0.0",
"nib": "^1.1.2",
"node-sass": "^4.7.2",
"nyc": "^11.1.0",
"postcss-modules": "^1.1.0",
"posthtml-extend": "^0.2.1",
"posthtml-include": "^1.1.0",
"prettier": "^1.13.0",
"pug": "^2.0.3",
"rimraf": "^2.6.1",
"sass": "^1.10.2",
"sinon": "^5.0.1",
"sourcemap-validator": "^1.0.6",
"stylus": "^0.54.5",
Expand Down
40 changes: 35 additions & 5 deletions src/assets/SASSAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class SASSAsset extends Asset {
}

async parse(code) {
// node-sass should be installed locally in the module that's being required
let sass = await localRequire('node-sass', this.name);
// node-sass or dart-sass should be installed locally in the module that's being required
let sass = await getSassRuntime(this.name);
let render = promisify(sass.render.bind(sass));
const resolver = new Resolver({
extensions: ['.scss', '.sass'],
Expand All @@ -41,8 +41,8 @@ class SASSAsset extends Asset {
: type === 'sass';

opts.functions = Object.assign({}, opts.functions, {
url: node => {
let filename = this.addURLDependency(node.getValue());
'url($url)': url => {
let filename = this.addURLDependency(url.getValue());
return new sass.types.String(`url(${JSON.stringify(filename)})`);
}
});
Expand All @@ -61,7 +61,16 @@ class SASSAsset extends Asset {
.catch(err => done(normalizeError(err)));
});

return await render(opts);
try {
return await render(opts);
} catch (err) {
// Format the error so it can be handled by parcel's prettyError
if (err.formatted) {
throw sassToCodeFrame(err);
}
// Throw original error if there is no codeFrame
throw err;
}
}

collectDependencies() {
Expand All @@ -83,6 +92,27 @@ class SASSAsset extends Asset {

module.exports = SASSAsset;

async function getSassRuntime(searchPath) {
try {
return await localRequire('node-sass', searchPath, true);
} catch (e) {
// If node-sass is not used locally, install dart-sass, as this causes no freezing issues
return await localRequire('sass', searchPath);
}
}

function sassToCodeFrame(err) {
let error = new Error(err.message);
error.codeFrame = err.formatted;
error.stack = err.stack;
error.fileName = err.file;
error.loc = {
line: err.line,
column: err.column
};
return error;
}

// Ensures an error inherits from Error
function normalizeError(err) {
let message = 'Unknown error';
Expand Down
2 changes: 1 addition & 1 deletion test/integration/sass-advanced-import/bar.sass
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
.bar
color: green;
color: green
2 changes: 1 addition & 1 deletion test/integration/sass-advanced-import/foo.sass
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
.foo
color: blue;
color: blue
8 changes: 4 additions & 4 deletions test/integration/sass-advanced-import/index.sass
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import '~/foo';
@import '~/bar.sass';
@import "~/foo"
@import "~/bar.sass"

.index
background: #ffffff;
color: #000000;
background: #ffffff
color: #000000
5 changes: 3 additions & 2 deletions test/sass.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,11 @@ describe('sass', function() {

let output = await run(b);
assert.equal(typeof output, 'function');
assert.equal(output(), '_index_1a1ih_1');
let className = output();
assert.notStrictEqual(className, 'index');

let css = await fs.readFile(__dirname + '/dist/index.css', 'utf8');
assert(css.includes('._index_1a1ih_1'));
assert(css.includes(`.${className}`));
});

it('should support advanced import syntax', async function() {
Expand Down
Loading