@parcel/transformer-sass 2.0.0-beta.3 → 2.0.0-dev.1510
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/SassTransformer.js +70 -95
- package/package.json +6 -6
- package/src/SassTransformer.js +61 -42
package/lib/SassTransformer.js
CHANGED
|
@@ -4,115 +4,86 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
function _plugin() {
|
|
9
8
|
const data = require("@parcel/plugin");
|
|
10
|
-
|
|
11
9
|
_plugin = function () {
|
|
12
10
|
return data;
|
|
13
11
|
};
|
|
14
|
-
|
|
15
12
|
return data;
|
|
16
13
|
}
|
|
17
|
-
|
|
18
14
|
function _path() {
|
|
19
15
|
const data = _interopRequireDefault(require("path"));
|
|
20
|
-
|
|
21
16
|
_path = function () {
|
|
22
17
|
return data;
|
|
23
18
|
};
|
|
24
|
-
|
|
25
19
|
return data;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
21
|
function _os() {
|
|
29
22
|
const data = require("os");
|
|
30
|
-
|
|
31
23
|
_os = function () {
|
|
32
24
|
return data;
|
|
33
25
|
};
|
|
34
|
-
|
|
35
26
|
return data;
|
|
36
27
|
}
|
|
37
|
-
|
|
38
28
|
function _sourceMap() {
|
|
39
29
|
const data = _interopRequireDefault(require("@parcel/source-map"));
|
|
40
|
-
|
|
41
30
|
_sourceMap = function () {
|
|
42
31
|
return data;
|
|
43
32
|
};
|
|
44
|
-
|
|
45
33
|
return data;
|
|
46
34
|
}
|
|
47
|
-
|
|
48
35
|
function _sass() {
|
|
49
36
|
const data = _interopRequireDefault(require("sass"));
|
|
50
|
-
|
|
51
37
|
_sass = function () {
|
|
52
38
|
return data;
|
|
53
39
|
};
|
|
54
|
-
|
|
55
|
-
return data;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function _url() {
|
|
59
|
-
const data = require("url");
|
|
60
|
-
|
|
61
|
-
_url = function () {
|
|
62
|
-
return data;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
40
|
return data;
|
|
66
41
|
}
|
|
67
|
-
|
|
68
42
|
function _util() {
|
|
69
43
|
const data = require("util");
|
|
70
|
-
|
|
71
44
|
_util = function () {
|
|
72
45
|
return data;
|
|
73
46
|
};
|
|
74
|
-
|
|
75
47
|
return data;
|
|
76
48
|
}
|
|
77
|
-
|
|
78
49
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
79
|
-
|
|
80
50
|
// E.g: ~library/file.sass
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
var _default = new (_plugin().Transformer)({
|
|
51
|
+
const NODE_MODULE_ALIAS_RE = /^~[^/\\]/;
|
|
52
|
+
var _default = exports.default = new (_plugin().Transformer)({
|
|
84
53
|
async loadConfig({
|
|
85
54
|
config,
|
|
86
55
|
options
|
|
87
56
|
}) {
|
|
88
|
-
let configFile = await config.getConfig(['.sassrc', '.sassrc.json', '.sassrc.js'], {
|
|
57
|
+
let configFile = await config.getConfig(['.sassrc', '.sassrc.json', '.sassrc.js', '.sassrc.cjs', '.sassrc.mjs'], {
|
|
89
58
|
packageKey: 'sass'
|
|
90
59
|
});
|
|
91
|
-
let configResult = configFile ? configFile.contents : {};
|
|
60
|
+
let configResult = configFile ? configFile.contents : {};
|
|
92
61
|
|
|
93
|
-
|
|
94
|
-
|
|
62
|
+
// Some packages in the wild declare a field `sass` in the package.json that
|
|
63
|
+
// is a relative path to the sass entrypoint. In those cases we simply
|
|
64
|
+
// initialize the config to an empty object.
|
|
65
|
+
if (typeof configResult === 'string') {
|
|
66
|
+
configResult = {};
|
|
95
67
|
}
|
|
96
68
|
|
|
97
|
-
|
|
98
|
-
|
|
69
|
+
// Resolve relative paths from config file
|
|
70
|
+
if (configFile && configResult.includePaths) {
|
|
71
|
+
configResult.includePaths = configResult.includePaths.map(p => _path().default.resolve(_path().default.dirname(configFile.filePath), p));
|
|
99
72
|
}
|
|
100
|
-
|
|
101
73
|
if (configResult.importer === undefined) {
|
|
102
74
|
configResult.importer = [];
|
|
103
75
|
} else if (!Array.isArray(configResult.importer)) {
|
|
104
76
|
configResult.importer = [configResult.importer];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
configResult.sourceMap = true; // sources are created relative to the directory of outFile
|
|
77
|
+
}
|
|
109
78
|
|
|
79
|
+
// Always emit sourcemap
|
|
80
|
+
configResult.sourceMap = true;
|
|
81
|
+
// sources are created relative to the directory of outFile
|
|
110
82
|
configResult.outFile = _path().default.join(options.projectRoot, 'style.css.map');
|
|
111
83
|
configResult.omitSourceMapUrl = true;
|
|
112
84
|
configResult.sourceMapContents = false;
|
|
113
|
-
|
|
85
|
+
return configResult;
|
|
114
86
|
},
|
|
115
|
-
|
|
116
87
|
async transform({
|
|
117
88
|
asset,
|
|
118
89
|
options,
|
|
@@ -122,10 +93,10 @@ var _default = new (_plugin().Transformer)({
|
|
|
122
93
|
let rawConfig = config !== null && config !== void 0 ? config : {};
|
|
123
94
|
let sassRender = (0, _util().promisify)(_sass().default.render.bind(_sass().default));
|
|
124
95
|
let css;
|
|
125
|
-
|
|
126
96
|
try {
|
|
127
97
|
let code = await asset.getCode();
|
|
128
|
-
let result = await sassRender({
|
|
98
|
+
let result = await sassRender({
|
|
99
|
+
...rawConfig,
|
|
129
100
|
file: asset.filePath,
|
|
130
101
|
data: rawConfig.data ? rawConfig.data + _os().EOL + code : code,
|
|
131
102
|
importer: [...rawConfig.importer, resolvePathImporter({
|
|
@@ -137,13 +108,11 @@ var _default = new (_plugin().Transformer)({
|
|
|
137
108
|
indentedSyntax: typeof rawConfig.indentedSyntax === 'boolean' ? rawConfig.indentedSyntax : asset.type === 'sass'
|
|
138
109
|
});
|
|
139
110
|
css = result.css;
|
|
140
|
-
|
|
141
111
|
for (let included of result.stats.includedFiles) {
|
|
142
112
|
if (included !== asset.filePath) {
|
|
143
|
-
asset.
|
|
113
|
+
asset.invalidateOnFileChange(included);
|
|
144
114
|
}
|
|
145
115
|
}
|
|
146
|
-
|
|
147
116
|
if (result.map != null) {
|
|
148
117
|
let map = new (_sourceMap().default)(options.projectRoot);
|
|
149
118
|
map.addVLQMap(JSON.parse(result.map));
|
|
@@ -158,16 +127,11 @@ var _default = new (_plugin().Transformer)({
|
|
|
158
127
|
};
|
|
159
128
|
throw err;
|
|
160
129
|
}
|
|
161
|
-
|
|
162
130
|
asset.type = 'css';
|
|
163
131
|
asset.setCode(css);
|
|
164
132
|
return [asset];
|
|
165
133
|
}
|
|
166
|
-
|
|
167
134
|
});
|
|
168
|
-
|
|
169
|
-
exports.default = _default;
|
|
170
|
-
|
|
171
135
|
function resolvePathImporter({
|
|
172
136
|
asset,
|
|
173
137
|
resolve,
|
|
@@ -187,60 +151,71 @@ function resolvePathImporter({
|
|
|
187
151
|
See: https://sass-lang.com/documentation/js-api#importer
|
|
188
152
|
See also: https://github.com/sass/dart-sass/blob/006e6aa62f2417b5267ad5cdb5ba050226fab511/lib/src/importer/node/implementation.dart
|
|
189
153
|
*/
|
|
190
|
-
let paths = [_path().default.dirname(prev)];
|
|
191
154
|
|
|
155
|
+
let paths = [_path().default.dirname(prev)];
|
|
192
156
|
if (includePaths) {
|
|
193
157
|
paths.push(...includePaths);
|
|
194
158
|
}
|
|
195
|
-
|
|
196
159
|
asset.invalidateOnEnvChange('SASS_PATH');
|
|
197
|
-
|
|
198
160
|
if (options.env.SASS_PATH) {
|
|
199
|
-
paths.push(...options.env.SASS_PATH.split(process.platform === 'win32' ? ';' : ':'));
|
|
161
|
+
paths.push(...options.env.SASS_PATH.split(process.platform === 'win32' ? ';' : ':').map(p => _path().default.resolve(options.projectRoot, p)));
|
|
162
|
+
}
|
|
163
|
+
const urls = [url];
|
|
164
|
+
const urlFileName = _path().default.basename(url);
|
|
165
|
+
if (urlFileName[0] !== '_') {
|
|
166
|
+
urls.push(_path().default.join(_path().default.dirname(url), `_${urlFileName}`));
|
|
200
167
|
}
|
|
201
|
-
|
|
202
|
-
let filePath;
|
|
203
|
-
let contents;
|
|
204
|
-
|
|
205
168
|
if (url[0] !== '~') {
|
|
206
169
|
for (let p of paths) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
})
|
|
170
|
+
for (let u of urls) {
|
|
171
|
+
const filePath = _path().default.resolve(p, u);
|
|
172
|
+
try {
|
|
173
|
+
const contents = await asset.fs.readFile(filePath, 'utf8');
|
|
174
|
+
return {
|
|
175
|
+
filePath,
|
|
176
|
+
contents
|
|
177
|
+
};
|
|
178
|
+
} catch (err) {
|
|
179
|
+
asset.invalidateOnFileCreate({
|
|
180
|
+
filePath
|
|
181
|
+
});
|
|
182
|
+
}
|
|
216
183
|
}
|
|
217
184
|
}
|
|
218
|
-
} // If none of the default sass rules apply, try Parcel's resolver.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (!contents) {
|
|
222
|
-
filePath = await resolve(prev, url);
|
|
223
|
-
contents = await asset.fs.readFile(filePath, 'utf8');
|
|
224
185
|
}
|
|
225
186
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
187
|
+
// If none of the default sass rules apply, try Parcel's resolver.
|
|
188
|
+
for (let u of urls) {
|
|
189
|
+
if (NODE_MODULE_ALIAS_RE.test(u)) {
|
|
190
|
+
u = u.slice(1);
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
const filePath = await resolve(prev, u, {
|
|
194
|
+
packageConditions: ['sass', 'style']
|
|
195
|
+
});
|
|
196
|
+
if (filePath) {
|
|
197
|
+
const contents = await asset.fs.readFile(filePath, 'utf8');
|
|
198
|
+
return {
|
|
199
|
+
filePath,
|
|
200
|
+
contents
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
} catch (err) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
231
206
|
}
|
|
232
207
|
}
|
|
233
|
-
|
|
234
208
|
return function (rawUrl, prev, done) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
209
|
+
const url = rawUrl.replace(/^file:\/\//, '');
|
|
210
|
+
resolvePath(url, prev).then(resolved => {
|
|
211
|
+
if (resolved) {
|
|
212
|
+
done({
|
|
213
|
+
file: resolved.filePath,
|
|
214
|
+
contents: resolved.contents
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
done();
|
|
218
|
+
}
|
|
219
|
+
}).catch(done);
|
|
245
220
|
};
|
|
246
221
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/transformer-sass",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-dev.1510+a9bb85adf",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"source": "src/SassTransformer.js",
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">= 12.0.0",
|
|
20
|
-
"parcel": "^2.0.0-
|
|
20
|
+
"parcel": "^2.0.0-dev.1508+a9bb85adf"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@parcel/plugin": "2.0.0-
|
|
24
|
-
"@parcel/source-map": "2.
|
|
25
|
-
"sass": "^1.
|
|
23
|
+
"@parcel/plugin": "2.0.0-dev.1510+a9bb85adf",
|
|
24
|
+
"@parcel/source-map": "^2.1.1",
|
|
25
|
+
"sass": "^1.38.0"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "a9bb85adf8f3b38631e178b3aacaa30c78696e36"
|
|
28
28
|
}
|
package/src/SassTransformer.js
CHANGED
|
@@ -4,16 +4,15 @@ import path from 'path';
|
|
|
4
4
|
import {EOL} from 'os';
|
|
5
5
|
import SourceMap from '@parcel/source-map';
|
|
6
6
|
import sass from 'sass';
|
|
7
|
-
import {pathToFileURL} from 'url';
|
|
8
7
|
import {promisify} from 'util';
|
|
9
8
|
|
|
10
9
|
// E.g: ~library/file.sass
|
|
11
|
-
const
|
|
10
|
+
const NODE_MODULE_ALIAS_RE = /^~[^/\\]/;
|
|
12
11
|
|
|
13
12
|
export default (new Transformer({
|
|
14
13
|
async loadConfig({config, options}) {
|
|
15
14
|
let configFile = await config.getConfig(
|
|
16
|
-
['.sassrc', '.sassrc.json', '.sassrc.js'],
|
|
15
|
+
['.sassrc', '.sassrc.json', '.sassrc.js', '.sassrc.cjs', '.sassrc.mjs'],
|
|
17
16
|
{
|
|
18
17
|
packageKey: 'sass',
|
|
19
18
|
},
|
|
@@ -21,6 +20,13 @@ export default (new Transformer({
|
|
|
21
20
|
|
|
22
21
|
let configResult = configFile ? configFile.contents : {};
|
|
23
22
|
|
|
23
|
+
// Some packages in the wild declare a field `sass` in the package.json that
|
|
24
|
+
// is a relative path to the sass entrypoint. In those cases we simply
|
|
25
|
+
// initialize the config to an empty object.
|
|
26
|
+
if (typeof configResult === 'string') {
|
|
27
|
+
configResult = {};
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
// Resolve relative paths from config file
|
|
25
31
|
if (configFile && configResult.includePaths) {
|
|
26
32
|
configResult.includePaths = configResult.includePaths.map(p =>
|
|
@@ -28,10 +34,6 @@ export default (new Transformer({
|
|
|
28
34
|
);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
if (configFile && path.extname(configFile.filePath) === '.js') {
|
|
32
|
-
config.shouldInvalidateOnStartup();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
37
|
if (configResult.importer === undefined) {
|
|
36
38
|
configResult.importer = [];
|
|
37
39
|
} else if (!Array.isArray(configResult.importer)) {
|
|
@@ -45,7 +47,7 @@ export default (new Transformer({
|
|
|
45
47
|
configResult.omitSourceMapUrl = true;
|
|
46
48
|
configResult.sourceMapContents = false;
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
return configResult;
|
|
49
51
|
},
|
|
50
52
|
|
|
51
53
|
async transform({asset, options, config, resolve}) {
|
|
@@ -76,7 +78,7 @@ export default (new Transformer({
|
|
|
76
78
|
css = result.css;
|
|
77
79
|
for (let included of result.stats.includedFiles) {
|
|
78
80
|
if (included !== asset.filePath) {
|
|
79
|
-
asset.
|
|
81
|
+
asset.invalidateOnFileChange(included);
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
|
|
@@ -105,7 +107,10 @@ export default (new Transformer({
|
|
|
105
107
|
function resolvePathImporter({asset, resolve, includePaths, options}) {
|
|
106
108
|
// This is a reimplementation of the Sass resolution algorithm that uses Parcel's
|
|
107
109
|
// FS and tracks all tried files so they are watched for creation.
|
|
108
|
-
async function resolvePath(
|
|
110
|
+
async function resolvePath(
|
|
111
|
+
url,
|
|
112
|
+
prev,
|
|
113
|
+
): Promise<{filePath: string, contents: string, ...} | void> {
|
|
109
114
|
/*
|
|
110
115
|
Imports are resolved by trying, in order:
|
|
111
116
|
* Loading a file relative to the file in which the `@import` appeared.
|
|
@@ -128,51 +133,65 @@ function resolvePathImporter({asset, resolve, includePaths, options}) {
|
|
|
128
133
|
paths.push(
|
|
129
134
|
...options.env.SASS_PATH.split(
|
|
130
135
|
process.platform === 'win32' ? ';' : ':',
|
|
131
|
-
),
|
|
136
|
+
).map(p => path.resolve(options.projectRoot, p)),
|
|
132
137
|
);
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
|
|
136
|
-
|
|
140
|
+
const urls = [url];
|
|
141
|
+
const urlFileName = path.basename(url);
|
|
142
|
+
if (urlFileName[0] !== '_') {
|
|
143
|
+
urls.push(path.join(path.dirname(url), `_${urlFileName}`));
|
|
144
|
+
}
|
|
137
145
|
|
|
138
146
|
if (url[0] !== '~') {
|
|
139
147
|
for (let p of paths) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
for (let u of urls) {
|
|
149
|
+
const filePath = path.resolve(p, u);
|
|
150
|
+
try {
|
|
151
|
+
const contents = await asset.fs.readFile(filePath, 'utf8');
|
|
152
|
+
return {
|
|
153
|
+
filePath,
|
|
154
|
+
contents,
|
|
155
|
+
};
|
|
156
|
+
} catch (err) {
|
|
157
|
+
asset.invalidateOnFileCreate({filePath});
|
|
158
|
+
}
|
|
146
159
|
}
|
|
147
160
|
}
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
// If none of the default sass rules apply, try Parcel's resolver.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
for (let u of urls) {
|
|
165
|
+
if (NODE_MODULE_ALIAS_RE.test(u)) {
|
|
166
|
+
u = u.slice(1);
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
const filePath = await resolve(prev, u, {
|
|
170
|
+
packageConditions: ['sass', 'style'],
|
|
171
|
+
});
|
|
172
|
+
if (filePath) {
|
|
173
|
+
const contents = await asset.fs.readFile(filePath, 'utf8');
|
|
174
|
+
return {filePath, contents};
|
|
175
|
+
}
|
|
176
|
+
} catch (err) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
161
179
|
}
|
|
162
180
|
}
|
|
163
181
|
|
|
164
|
-
return function(rawUrl, prev, done) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
return function (rawUrl, prev, done) {
|
|
183
|
+
const url = rawUrl.replace(/^file:\/\//, '');
|
|
184
|
+
resolvePath(url, prev)
|
|
185
|
+
.then(resolved => {
|
|
186
|
+
if (resolved) {
|
|
187
|
+
done({
|
|
188
|
+
file: resolved.filePath,
|
|
189
|
+
contents: resolved.contents,
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
done();
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
.catch(done);
|
|
177
196
|
};
|
|
178
197
|
}
|