@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.
@@ -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 WEBPACK_ALIAS_RE = /^~[^/]/;
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 : {}; // Resolve relative paths from config file
60
+ let configResult = configFile ? configFile.contents : {};
92
61
 
93
- if (configFile && configResult.includePaths) {
94
- configResult.includePaths = configResult.includePaths.map(p => _path().default.resolve(_path().default.dirname(configFile.filePath), p));
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
- if (configFile && _path().default.extname(configFile.filePath) === '.js') {
98
- config.shouldInvalidateOnStartup();
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
- } // Always emit sourcemap
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
- config.setResult(configResult);
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({ ...rawConfig,
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.addIncludedFile(included);
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
- filePath = _path().default.resolve(p, url);
208
-
209
- try {
210
- contents = await asset.fs.readFile(filePath, 'utf8');
211
- break;
212
- } catch (err) {
213
- asset.invalidateOnFileCreate({
214
- filePath
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
- if (filePath) {
227
- return {
228
- file: (0, _url().pathToFileURL)(filePath).toString(),
229
- contents
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
- let url = rawUrl.replace(/^file:\/\//, '');
236
-
237
- if (WEBPACK_ALIAS_RE.test(url)) {
238
- const correctPath = url.replace(/^~/, '');
239
- const error = new Error(`The @import path "${url}" is using webpack specific syntax, which isn't supported by Parcel.\n\nTo @import files from node_modules, use "${correctPath}"`);
240
- done(error);
241
- return;
242
- }
243
-
244
- resolvePath(url, prev).then(done, done);
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-beta.3",
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-beta.1"
20
+ "parcel": "^2.0.0-dev.1508+a9bb85adf"
21
21
  },
22
22
  "dependencies": {
23
- "@parcel/plugin": "2.0.0-beta.3",
24
- "@parcel/source-map": "2.0.0-rc.1.0",
25
- "sass": "^1.32.4"
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": "bf03f018093f8c7ca4c3a544524e15065a637b3b"
27
+ "gitHead": "a9bb85adf8f3b38631e178b3aacaa30c78696e36"
28
28
  }
@@ -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 WEBPACK_ALIAS_RE = /^~[^/]/;
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
- config.setResult(configResult);
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.addIncludedFile(included);
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(url, prev) {
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
- let filePath;
136
- let contents;
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
- filePath = path.resolve(p, url);
141
- try {
142
- contents = await asset.fs.readFile(filePath, 'utf8');
143
- break;
144
- } catch (err) {
145
- asset.invalidateOnFileCreate({filePath});
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
- if (!contents) {
152
- filePath = await resolve(prev, url);
153
- contents = await asset.fs.readFile(filePath, 'utf8');
154
- }
155
-
156
- if (filePath) {
157
- return {
158
- file: pathToFileURL(filePath).toString(),
159
- contents,
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
- let url = rawUrl.replace(/^file:\/\//, '');
166
-
167
- if (WEBPACK_ALIAS_RE.test(url)) {
168
- const correctPath = url.replace(/^~/, '');
169
- const error = new Error(
170
- `The @import path "${url}" is using webpack specific syntax, which isn't supported by Parcel.\n\nTo @import files from node_modules, use "${correctPath}"`,
171
- );
172
- done(error);
173
- return;
174
- }
175
-
176
- resolvePath(url, prev).then(done, done);
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
  }