Skip to content

Commit

Permalink
fix: handle importing Sass partials in node_modules (#90)
Browse files Browse the repository at this point in the history
* fix: handle importing Sass partials in node_modules

* tweaks
  • Loading branch information
ryanoglesby08 authored and egoist committed Apr 17, 2018
1 parent 283aac4 commit 347d570
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 16 deletions.
58 changes: 43 additions & 15 deletions src/sass-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import importCwd from 'import-cwd'

const moduleRe = /^~([a-z0-9]|@).+/i

const getUrlOfPartial = url => {
const parsedUrl = path.parse(url)
return `${parsedUrl.dir}${path.sep}_${parsedUrl.base}`
}

const resolvePromise = pify(resolve)

export default {
name: 'sass',
test: /\.s[ac]ss$/,
Expand All @@ -16,22 +23,43 @@ export default {
data: code,
indentedSyntax: /\.sass$/.test(this.id),
sourceMap: this.sourceMap,
importer: [(url, importer, done) => {
if (!moduleRe.test(url)) return done({ file: url })

resolve(url.slice(1), {
basedir: path.dirname(importer),
extensions: ['.scss', '.sass', '.css']
}, (err, id) => {
if (err) {
return Promise.reject(err)
importer: [
(url, importer, done) => {
if (!moduleRe.test(url)) return done({ file: url })

const moduleUrl = url.slice(1)
const partialUrl = getUrlOfPartial(moduleUrl)

const options = {
basedir: path.dirname(importer),
extensions: ['.scss', '.sass', '.css']
}
done({
// Do not add `.css` extension in order to inline the file
file: id.endsWith('.css') ? id.replace(/\.css$/, '') : id
})
})
}].concat(this.options.importer || [])
const finishImport = id => {
done({
// Do not add `.css` extension in order to inline the file
file: id.endsWith('.css') ? id.replace(/\.css$/, '') : id
})
}

const next = () => {
// Catch all resolving errors, return the original file and pass responsibility back to other custom importers
done({ file: url })
}

// Give precedence to importing a partial
resolvePromise(partialUrl, options)
.then(finishImport)
.catch(err => {
if (err.code === 'MODULE_NOT_FOUND' || err.code === 'ENOENT') {
resolvePromise(moduleUrl, options)
.then(finishImport)
.catch(next)
} else {
next()
}
})
}
].concat(this.options.importer || [])
})

return {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/sass-import/_partial.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$color: magenta;
4 changes: 3 additions & 1 deletion test/fixtures/sass-import/foo.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import "partial";

.foo {
color: magenta;
color: $color;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/sass-import/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "~foo/bar/a";
@import "~foo/bar/b";
@import "~foo/bar/c";
@import "~foo/bar/partial";
@import "foo.scss";

0 comments on commit 347d570

Please sign in to comment.