Skip to content

Commit 230c4a1

Browse files
authored
De-duplicate hoisted imports and avoid rewriting imports of built-ins (#142)
* De-duplicate hoisted imports and avoid rewriting imports of built-ins * Add changelog entry and bump version number
1 parent a29438b commit 230c4a1

File tree

8 files changed

+75
-6
lines changed

8 files changed

+75
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Change Log
2-
## [Unreleased]
2+
## [2.2.2] - Unreleased
3+
* De-duplicate hoisted imports and avoid rewriting imports of built-ins. [#142](https://github.com/shakacode/sass-resources-loader/pull/142) by [Jan Amann](https://github.com/amannn).
34

45
## [2.2.1] - 2021-04-14
56
* Support multi-line imports with @use syntax. Fixes: [#135](https://github.com/shakacode/sass-resources-loader/issues/135). [#140](https://github.com/shakacode/sass-resources-loader/pull/140) by [Toms Burgmanis](https://github.com/tomburgs).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sass-resources-loader",
3-
"version": "2.2.1",
3+
"version": "2.2.2",
44
"description": "SASS resources loader for Webpack",
55
"main": "lib/loader.js",
66
"files": [

src/utils/processResources.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,23 @@ const useRegexTest = new RegExp(useRegex, 'm');
99
// Makes sure that only the last instance of `useRegex` variable is found
1010
const useRegexReplace = new RegExp(`${useRegex}(?![\\s\\S]*${useRegex})`, 'gm');
1111

12-
const getOutput = (source, resources, { hoistUseStatements }) => {
12+
export const getOutput = (source, resources, { hoistUseStatements }) => {
1313
if (hoistUseStatements && useRegexTest.test(source)) {
14-
return source.replace(
14+
const output = source.replace(
1515
useRegexReplace,
16-
useStatements => `${useStatements}\n${resources}`,
16+
(useStatements) => `${useStatements}\n${resources}`,
1717
);
18+
19+
// De-duplicate identical imports
20+
const importedResources = {};
21+
return output.replace(new RegExp(useRegex, 'mg'), (importedResource) => {
22+
if (importedResources[importedResource]) {
23+
return '';
24+
}
25+
26+
importedResources[importedResource] = true;
27+
return importedResource;
28+
});
1829
}
1930

2031
return `${resources}\n${source}`;

src/utils/rewritePaths.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ export default function rewritePaths(error, file, contents, moduleContext, callb
2222
return callback(null, contents);
2323
}
2424

25-
2625
const rewritten = contents.replace(useRegexp, (entire, importer, single, double, unquoted) => {
26+
// Don't rewrite imports from built-ins
27+
if (single.indexOf('sass:') === 0) {
28+
return entire;
29+
}
30+
2731
const oldUsePath = single || double || unquoted;
2832

2933
const absoluteUsePath = path.join(path.dirname(file), oldUsePath);

test/__snapshots__/index.test.js.snap

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ div {
9898
"
9999
`;
100100

101+
exports[`sass-resources-loader imports should not rewrite the path for built-ins with @use 1`] = `
102+
"// Should be de-duplicated
103+
@use 'sass:math';
104+
105+
106+
$padding: #{math.div(4 / 2)}px;
107+
108+
div {
109+
padding: $padding;
110+
margin: #{math.div(4 / 2)}px;;
111+
}
112+
"
113+
`;
114+
101115
exports[`sass-resources-loader imports should preserve import method 1`] = `
102116
"@use 'shared/index' as secret;
103117
@import 'shared/variables';
@@ -126,6 +140,10 @@ exports[`sass-resources-loader resources should parse array resources 1`] = `
126140
127141
@forward \\"variables\\";
128142
143+
@use 'sass:math';
144+
145+
$padding: #{math.div(4 / 2)}px;
146+
129147
$text-color: $ccc;
130148
131149
@mixin my-mixin {

test/index.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const path = require('path');
22
const webpack = require('webpack');
33
const { merge } = require('webpack-merge');
4+
const { getOutput } = require('../src/utils/processResources');
45

56
const pathToLoader = require.resolve('../lib/loader.js');
67

@@ -240,5 +241,29 @@ describe('sass-resources-loader', () => {
240241
const output = require('./output/imports2').default;
241242
expect(output).toMatchSnapshot();
242243
}));
244+
245+
it('should not rewrite the path for built-ins with @use', () => execTest('use-builtin', {
246+
hoistUseStatements: true,
247+
resources: [
248+
path.resolve(__dirname, './scss/shared/_math.scss'),
249+
],
250+
}).then(() => {
251+
// eslint-disable-next-line global-require
252+
const output = require('./output/use-builtin').default;
253+
expect(output).toMatchSnapshot();
254+
}));
255+
});
256+
257+
describe('getOutput', () => {
258+
it('de-duplicates imports from the source when they\'re present in a resource and `hoiseUseStatements` is enabled', () => {
259+
const result = getOutput(
260+
"@use 'sass:math';\n@use 'sass:list';\n@use 'sass:map';\ndiv { padding: $padding; }",
261+
"@use 'sass:math';\n$padding: 10px;",
262+
{ hoistUseStatements: true },
263+
);
264+
expect(result).toBe(
265+
"@use 'sass:math';\n@use 'sass:list';\n@use 'sass:map';\n\n$padding: 10px;\ndiv { padding: $padding; }",
266+
);
267+
});
243268
});
244269
});

test/scss/shared/_math.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@use 'sass:math';
2+
3+
$padding: #{math.div(4 / 2)}px;

test/scss/use-builtin.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Should be de-duplicated
2+
@use 'sass:math';
3+
4+
div {
5+
padding: $padding;
6+
margin: #{math.div(4 / 2)}px;;
7+
}

0 commit comments

Comments
 (0)