UNPKG

4.66 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
6
7const Asset = require('../Asset');
8
9const localRequire = require('../utils/localRequire');
10
11const _require = require('@parcel/utils'),
12 promisify = _require.promisify;
13
14const path = require('path');
15
16const os = require('os');
17
18const Resolver = require('../Resolver');
19
20const parseCSSImport = require('../utils/parseCSSImport');
21
22class SASSAsset extends Asset {
23 constructor(name, options) {
24 super(name, options);
25 this.type = 'css';
26 }
27
28 parse(code) {
29 var _this = this;
30
31 return (0, _asyncToGenerator2.default)(function* () {
32 // node-sass or dart-sass should be installed locally in the module that's being required
33 let sass = yield getSassRuntime(_this.name);
34 let render = promisify(sass.render.bind(sass));
35 const resolver = new Resolver({
36 extensions: ['.scss', '.sass'],
37 rootDir: _this.options.rootDir
38 });
39 let opts = (yield _this.getConfig(['.sassrc', '.sassrc.js'], {
40 packageKey: 'sass'
41 })) || {};
42 opts.includePaths = (opts.includePaths ? opts.includePaths.map(includePath => path.resolve(includePath)) : []).concat(path.dirname(_this.name));
43 opts.data = opts.data ? opts.data + os.EOL + code : code;
44 let type = _this.options.rendition ? _this.options.rendition.type : path.extname(_this.name).toLowerCase().replace('.', '');
45 opts.indentedSyntax = typeof opts.indentedSyntax === 'boolean' ? opts.indentedSyntax : type === 'sass';
46 opts.importer = opts.importer || [];
47 opts.importer = Array.isArray(opts.importer) ? opts.importer : [opts.importer];
48 opts.importer.push((url, prev, done) => {
49 url = url.replace(/^file:\/\//, '');
50 url = parseCSSImport(url);
51 resolver.resolve(url, prev === 'stdin' ? _this.name : prev).then(resolved => resolved.path).catch(() => url).then(file => done({
52 file
53 })).catch(err => done(normalizeError(err)));
54 });
55
56 if (_this.options.sourceMaps) {
57 opts.sourceMap = true;
58 opts.file = _this.name;
59 opts.outFile = _this.name;
60 opts.omitSourceMapUrl = true;
61 opts.sourceMapContents = true;
62 }
63
64 try {
65 return yield render(opts);
66 } catch (err) {
67 // Format the error so it can be handled by parcel's prettyError
68 if (err.formatted) {
69 throw sassToCodeFrame(err);
70 } // Throw original error if there is no codeFrame
71
72
73 throw err;
74 }
75 })();
76 }
77
78 collectDependencies() {
79 var _iteratorNormalCompletion = true;
80 var _didIteratorError = false;
81 var _iteratorError = undefined;
82
83 try {
84 for (var _iterator = this.ast.stats.includedFiles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
85 let dep = _step.value;
86 this.addDependency(dep, {
87 includedInParent: true
88 });
89 }
90 } catch (err) {
91 _didIteratorError = true;
92 _iteratorError = err;
93 } finally {
94 try {
95 if (!_iteratorNormalCompletion && _iterator.return != null) {
96 _iterator.return();
97 }
98 } finally {
99 if (_didIteratorError) {
100 throw _iteratorError;
101 }
102 }
103 }
104 }
105
106 generate() {
107 return [{
108 type: 'css',
109 value: this.ast ? this.ast.css.toString() : '',
110 map: this.ast && this.ast.map ? JSON.parse(this.ast.map.toString()) : undefined
111 }];
112 }
113
114}
115
116module.exports = SASSAsset;
117
118function getSassRuntime(_x) {
119 return _getSassRuntime.apply(this, arguments);
120}
121
122function _getSassRuntime() {
123 _getSassRuntime = (0, _asyncToGenerator2.default)(function* (searchPath) {
124 try {
125 return yield localRequire('node-sass', searchPath, true);
126 } catch (e) {
127 // If node-sass is not used locally, install dart-sass, as this causes no freezing issues
128 return localRequire('sass', searchPath);
129 }
130 });
131 return _getSassRuntime.apply(this, arguments);
132}
133
134function sassToCodeFrame(err) {
135 let error = new Error(err.message);
136 error.codeFrame = err.formatted;
137 error.stack = err.stack;
138 error.fileName = err.file;
139 error.loc = {
140 line: err.line,
141 column: err.column
142 };
143 return error;
144} // Ensures an error inherits from Error
145
146
147function normalizeError(err) {
148 let message = 'Unknown error';
149
150 if (err) {
151 if (err instanceof Error) {
152 return err;
153 }
154
155 message = err.stack || err.message || err;
156 }
157
158 return new Error(message);
159}
\No newline at end of file