Skip to content

Commit

Permalink
refactor: code
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Apr 24, 2020
1 parent 2a18d5b commit 006c02e
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 107 deletions.
10 changes: 5 additions & 5 deletions src/SassError.js
@@ -1,5 +1,5 @@
class SassError extends Error {
constructor(sassError, resourcePath) {
constructor(sassError) {
super();

this.name = 'SassError';
Expand All @@ -13,13 +13,13 @@ class SassError extends Error {
this.message = `${this.name}: ${this.originalSassError.message}`;

if (this.originalSassError.formatted) {
this.message = `${this.name}: ${this.originalSassError.formatted
.replace(/^Error: /, '')
.replace(/(\s*)stdin(\s*)/, `$1${resourcePath}$2`)}`;
this.message = `${this.name}: ${this.originalSassError.formatted.replace(
/^Error: /,
''
)}`;

// Instruct webpack to hide the JS stack from the console.
// Usually you're only interested in the SASS stack in this case.
// eslint-disable-next-line no-param-reassign
this.hideStack = true;

Error.captureStackTrace(this, this.constructor);
Expand Down
16 changes: 6 additions & 10 deletions src/getSassOptions.js
Expand Up @@ -2,14 +2,8 @@ import path from 'path';

import cloneDeep from 'clone-deep';

import proxyCustomImporters from './proxyCustomImporters';

function isProductionLikeMode(loaderContext) {
return (
loaderContext.mode === 'production' ||
!loaderContext.mode ||
loaderContext.minimize
);
return loaderContext.mode === 'production' || !loaderContext.mode;
}

/**
Expand Down Expand Up @@ -81,7 +75,7 @@ function getSassOptions(loaderContext, loaderOptions, content, implementation) {
// But since we're using the data option, the source map will not actually be written, but
// all paths in sourceMap.sources will be relative to that path.
// Pretty complicated... :(
options.sourceMap = path.join(process.cwd(), '/sass.map');
options.sourceMap = path.join(process.cwd(), '/sass.css.map');
options.sourceMapRoot = process.cwd();
options.sourceMapContents = true;
options.omitSourceMapUrl = true;
Expand All @@ -102,9 +96,11 @@ function getSassOptions(loaderContext, loaderOptions, content, implementation) {
options.indentedSyntax = Boolean(options.indentedSyntax);
}

// Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
// Allow passing custom importers to `sass`/`node-sass`. Accepts `Function` or an array of `Function`s.
options.importer = options.importer
? proxyCustomImporters(options.importer, resourcePath)
? Array.isArray(options.importer)
? options.importer
: [options.importer]
: [];

options.includePaths = []
Expand Down
39 changes: 5 additions & 34 deletions src/index.js
Expand Up @@ -17,7 +17,7 @@ import SassError from './SassError';
* @param {string} content
*/
function loader(content) {
const options = getOptions(this) || {};
const options = getOptions(this);

validateOptions(schema, options, {
name: 'Sass Loader',
Expand All @@ -39,28 +39,19 @@ function loader(content) {
}

const callback = this.async();

// Skip empty files, otherwise it will stop webpack, see issue #21
if (sassOptions.data.trim() === '') {
callback(null, '');

return;
}

const render = getRenderFunctionFromSassImplementation(implementation);

render(sassOptions, (error, result) => {
if (error) {
if (error.file) {
this.addDependency(path.normalize(error.file));
}
// `node-sass` returns POSIX paths
this.addDependency(path.normalize(error.file));

callback(new SassError(error, this.resourcePath));
callback(new SassError(error));

return;
}

if (result.map && result.map !== '{}') {
if (result.map) {
// eslint-disable-next-line no-param-reassign
result.map = JSON.parse(result.map);

Expand All @@ -69,33 +60,13 @@ function loader(content) {
// eslint-disable-next-line no-param-reassign
delete result.map.file;

// One of the sources is 'stdin' according to dart-sass/node-sass because we've used the data input.
// Now let's override that value with the correct relative path.
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in getSassOptions,
// we know that this path is relative to process.cwd(). This is how node-sass works.
// eslint-disable-next-line no-param-reassign
const stdinIndex = result.map.sources.findIndex((source) =>
source.includes('stdin')
);

if (stdinIndex !== -1) {
// eslint-disable-next-line no-param-reassign
result.map.sources[stdinIndex] = path.relative(
process.cwd(),
this.resourcePath
);
}

// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
// This fixes an error on windows where the source-map module cannot resolve the source maps.
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
// eslint-disable-next-line no-param-reassign
result.map.sourceRoot = path.normalize(result.map.sourceRoot);
// eslint-disable-next-line no-param-reassign
result.map.sources = result.map.sources.map(path.normalize);
} else {
// eslint-disable-next-line no-param-reassign
result.map = null;
}

result.stats.includedFiles.forEach((includedFile) => {
Expand Down
31 changes: 0 additions & 31 deletions src/proxyCustomImporters.js

This file was deleted.

9 changes: 1 addition & 8 deletions src/webpackImporter.js
Expand Up @@ -20,13 +20,6 @@ const matchCss = /\.css$/i;
*
*/
function webpackImporter(loaderContext, includePaths) {
function dirContextFrom(fileContext) {
return path.dirname(
// The first file is 'stdin' when we're using the data option
fileContext === 'stdin' ? loaderContext.resourcePath : fileContext
);
}

function startResolving(resolutionMap) {
if (resolutionMap.length === 0) {
return Promise.reject();
Expand Down Expand Up @@ -116,7 +109,7 @@ function webpackImporter(loaderContext, includePaths) {

resolutionMap = resolutionMap.concat({
resolve: webpackResolve,
context: isFileScheme ? '/' : dirContextFrom(prev),
context: isFileScheme ? '/' : path.dirname(prev),
possibleRequests: webpackPossibleRequests,
});

Expand Down
48 changes: 36 additions & 12 deletions test/__snapshots__/sassOptions-option.test.js.snap
Expand Up @@ -1732,29 +1732,53 @@ exports[`sassOptions option should work with the "functions" option (node-sass)

exports[`sassOptions option should work with the "functions" option (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (sass): css 1`] = `""`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (sass): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (sass): errors 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (sass): warnings 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (scss): css 1`] = `""`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (scss): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (scss): errors 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (dart-sass) (scss): warnings 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (node-sass) (sass): css 1`] = `""`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (sass): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" option (node-sass) (sass): errors 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (sass): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (node-sass) (sass): warnings 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (node-sass) (scss): css 1`] = `""`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (scss): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" option (node-sass) (scss): errors 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (scss): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" option (node-sass) (scss): warnings 1`] = `Array []`;
exports[`sassOptions option should work with the "importer" as a array of functions option (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (sass): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (sass): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (sass): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (scss): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (scss): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (dart-sass) (scss): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (sass): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (sass): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (sass): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (scss): css 1`] = `""`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (scss): errors 1`] = `Array []`;

exports[`sassOptions option should work with the "importer" as a single function option (node-sass) (scss): warnings 1`] = `Array []`;

exports[`sassOptions option should work with the "includePaths" option (dart-sass) (sass): css 1`] = `
".include-path-module {
Expand Down
11 changes: 9 additions & 2 deletions test/helpers/customImporter.js
@@ -1,8 +1,15 @@
function customImporter(path, prev) {
expect(path).toBe('import-with-custom-logic');
function customImporter(url, prev, done) {
expect(url).toBe('import-with-custom-logic');
expect(prev).toMatch(/(sass|scss)[/\\]custom-importer\.(scss|sass)/);
expect(this.options).toBeDefined();

if (done) {
done(customImporter.returnValue);

return;
}

// eslint-disable-next-line consistent-return
return customImporter.returnValue;
}

Expand Down
8 changes: 7 additions & 1 deletion test/helpers/getCodeFromSass.js
Expand Up @@ -723,7 +723,13 @@ function getCodeFromSass(testId, options) {
}

sassOptions.importer = sassOptions.importer
? [sassOptions.importer, testImporter]
? []
.concat(
Array.isArray(sassOptions.importer)
? [...sassOptions.importer]
: [sassOptions.importer]
)
.concat([testImporter])
: [testImporter];

const { css, map } = implementation.renderSync(sassOptions);
Expand Down
2 changes: 1 addition & 1 deletion test/helpers/getErrors.js
@@ -1,5 +1,5 @@
import normalizeErrors from './normalizeErrors';

export default (stats) => {
return normalizeErrors(stats.compilation.errors);
return normalizeErrors(stats.compilation.errors.sort());
};
2 changes: 1 addition & 1 deletion test/helpers/getWarnings.js
@@ -1,5 +1,5 @@
import normalizeErrors from './normalizeErrors';

export default (stats) => {
return normalizeErrors(stats.compilation.warnings);
return normalizeErrors(stats.compilation.warnings.sort());
};

0 comments on commit 006c02e

Please sign in to comment.