Skip to content

Commit 01b3812

Browse files
refactor: code (#104)
1 parent 4c39c22 commit 01b3812

File tree

2 files changed

+106
-97
lines changed

2 files changed

+106
-97
lines changed

src/index.js

+73-87
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
*/
55
import fs from 'fs';
66
import path from 'path';
7-
import urlUtils from 'url';
7+
8+
import { promisify } from 'util';
89

910
import validateOptions from 'schema-utils';
1011
import parseDataURL from 'data-urls';
1112

1213
import { SourceMapConsumer } from 'source-map';
14+
1315
import { labelToName, decode } from 'whatwg-encoding';
1416
import { getOptions, urlToRequest } from 'loader-utils';
1517

@@ -18,11 +20,11 @@ import {
1820
flattenSourceMap,
1921
readFile,
2022
getContentFromSourcesContent,
21-
isUrlRequest,
2223
getSourceMappingUrl,
24+
getRequestedUrl,
2325
} from './utils';
2426

25-
export default function loader(input, inputMap) {
27+
export default async function loader(input, inputMap) {
2628
const options = getOptions(this);
2729

2830
validateOptions(schema, options, {
@@ -40,99 +42,83 @@ export default function loader(input, inputMap) {
4042
return;
4143
}
4244

43-
const dataURL = parseDataURL(url);
44-
4545
const { context, resolve, addDependency, emitWarning } = this;
46+
const resolver = promisify(resolve);
4647

47-
if (dataURL) {
48-
let map;
48+
if (url.toLowerCase().startsWith('data:')) {
49+
const dataURL = parseDataURL(url);
4950

50-
try {
51-
dataURL.encodingName =
52-
labelToName(dataURL.mimeType.parameters.get('charset')) || 'UTF-8';
51+
if (dataURL) {
52+
let map;
5353

54-
map = decode(dataURL.body, dataURL.encodingName);
55-
map = JSON.parse(map.replace(/^\)\]\}'/, ''));
56-
} catch (error) {
57-
emitWarning(
58-
`Cannot parse inline SourceMap with Charset ${dataURL.encodingName}: ${error}`
59-
);
54+
try {
55+
dataURL.encodingName =
56+
labelToName(dataURL.mimeType.parameters.get('charset')) || 'UTF-8';
6057

61-
callback(null, input, inputMap);
58+
map = decode(dataURL.body, dataURL.encodingName);
59+
map = JSON.parse(map.replace(/^\)\]\}'/, ''));
60+
} catch (error) {
61+
emitWarning(
62+
`Cannot parse inline SourceMap with Charset ${dataURL.encodingName}: ${error}`
63+
);
6264

63-
return;
64-
}
65+
callback(null, input, inputMap);
6566

66-
processMap(map, context, callback);
67+
return;
68+
}
6769

68-
return;
69-
}
70+
processMap(map, context, callback);
71+
72+
return;
73+
}
7074

71-
if (url.toLowerCase().indexOf('data:') === 0) {
7275
emitWarning(`Cannot parse inline SourceMap: ${url}`);
7376

7477
callback(null, input, inputMap);
7578

7679
return;
7780
}
7881

79-
if (!isUrlRequest(url)) {
80-
const { protocol } = urlUtils.parse(url);
81-
82-
if (protocol !== 'file:') {
83-
emitWarning(`URL scheme not supported: ${protocol}`);
82+
try {
83+
url = getRequestedUrl(url);
84+
} catch (error) {
85+
emitWarning(error.message);
8486

85-
callback(null, input, inputMap);
86-
87-
return;
88-
}
89-
90-
try {
91-
url = urlUtils.fileURLToPath(url);
92-
} catch (error) {
93-
emitWarning(error);
94-
95-
callback(null, input, inputMap);
87+
callback(null, input, inputMap);
9688

97-
return;
98-
}
89+
return;
9990
}
10091

101-
resolve(context, urlToRequest(url, true), (resolveError, result) => {
102-
if (resolveError) {
103-
emitWarning(`Cannot find SourceMap '${url}': ${resolveError}`);
104-
105-
callback(null, input, inputMap);
106-
107-
return;
108-
}
92+
let urlResolved;
10993

110-
addDependency(result);
94+
try {
95+
urlResolved = await resolver(context, urlToRequest(url, true));
96+
} catch (resolveError) {
97+
emitWarning(`Cannot find SourceMap '${url}': ${resolveError}`);
11198

112-
fs.readFile(result, 'utf-8', (readFileError, content) => {
113-
if (readFileError) {
114-
emitWarning(`Cannot open SourceMap '${result}': ${readFileError}`);
99+
callback(null, input, inputMap);
115100

116-
callback(null, input, inputMap);
101+
return;
102+
}
117103

118-
return;
119-
}
104+
urlResolved = urlResolved.toString();
105+
addDependency(urlResolved);
120106

121-
let map;
107+
const reader = promisify(fs.readFile);
108+
const content = await reader(urlResolved);
109+
let map;
122110

123-
try {
124-
map = JSON.parse(content);
125-
} catch (e) {
126-
emitWarning(`Cannot parse SourceMap '${url}': ${e}`);
111+
try {
112+
map = JSON.parse(content.toString());
113+
} catch (parseError) {
114+
emitWarning(`Cannot parse SourceMap '${url}': ${parseError}`);
127115

128-
callback(null, input, inputMap);
116+
callback(null, input, inputMap);
129117

130-
return;
131-
}
118+
return;
119+
}
132120

133-
processMap(map, path.dirname(result), callback);
134-
});
135-
});
121+
processMap(map, path.dirname(urlResolved), callback);
136122

137123
// eslint-disable-next-line no-shadow
138124
async function processMap(map, context, callback) {
@@ -163,30 +149,30 @@ export default function loader(input, inputMap) {
163149
: readFile(fullPath, 'utf-8', emitWarning);
164150
}
165151

166-
return new Promise((promiseResolve) => {
167-
resolve(
152+
let fullPathResolved;
153+
154+
try {
155+
fullPathResolved = await resolver(
168156
context,
169-
urlToRequest(fullPath, true),
170-
(resolveError, result) => {
171-
if (resolveError) {
172-
emitWarning(
173-
`Cannot find source file '${source}': ${resolveError}`
174-
);
175-
176-
return originalData
177-
? promiseResolve({
178-
source: fullPath,
179-
content: originalData,
180-
})
181-
: promiseResolve({ source: fullPath, content: null });
157+
urlToRequest(fullPath, true)
158+
);
159+
} catch (resolveError) {
160+
emitWarning(`Cannot find source file '${source}': ${resolveError}`);
161+
162+
return originalData
163+
? {
164+
source: fullPath,
165+
content: originalData,
182166
}
167+
: { source: fullPath, content: null };
168+
}
183169

184-
return originalData
185-
? promiseResolve({ source: result, content: originalData })
186-
: promiseResolve(readFile(result, 'utf-8', emitWarning));
170+
return originalData
171+
? {
172+
source: fullPathResolved,
173+
content: originalData,
187174
}
188-
);
189-
});
175+
: readFile(fullPathResolved, 'utf-8', emitWarning);
190176
})
191177
);
192178
} catch (error) {

src/utils.js

+33-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import fs from 'fs';
22
import path from 'path';
33

4+
import { promisify } from 'util';
5+
6+
import urlUtils from 'url';
7+
48
import sourceMap from 'source-map';
59

610
// Matches only the last occurrence of sourceMappingURL
@@ -68,18 +72,18 @@ async function flattenSourceMap(map) {
6872
return generatedMap.toJSON();
6973
}
7074

71-
function readFile(fullPath, charset, emitWarning) {
72-
return new Promise((resolve) => {
73-
fs.readFile(fullPath, charset, (readFileError, content) => {
74-
if (readFileError) {
75-
emitWarning(`Cannot open source file '${fullPath}': ${readFileError}`);
75+
async function readFile(fullPath, charset, emitWarning) {
76+
const reader = promisify(fs.readFile);
77+
let content;
7678

77-
resolve({ source: null, content: null });
78-
}
79+
try {
80+
content = await reader(fullPath, charset);
81+
return { source: fullPath, content };
82+
} catch (readFileError) {
83+
emitWarning(`Cannot open source file '${fullPath}': ${readFileError}`);
7984

80-
resolve({ source: fullPath, content });
81-
});
82-
});
85+
return { source: null, content: null };
86+
}
8387
}
8488

8589
function getContentFromSourcesContent(consumer, source) {
@@ -119,10 +123,29 @@ function getSourceMappingUrl(code) {
119123
};
120124
}
121125

126+
function getRequestedUrl(url) {
127+
if (isUrlRequest(url)) {
128+
return url;
129+
}
130+
131+
const { protocol } = urlUtils.parse(url);
132+
133+
if (protocol !== 'file:') {
134+
throw new Error(`URL scheme not supported: ${protocol}`);
135+
}
136+
137+
try {
138+
return urlUtils.fileURLToPath(url);
139+
} catch (error) {
140+
throw new Error(error);
141+
}
142+
}
143+
122144
export {
123145
flattenSourceMap,
124146
readFile,
125147
getContentFromSourcesContent,
126148
isUrlRequest,
127149
getSourceMappingUrl,
150+
getRequestedUrl,
128151
};

0 commit comments

Comments
 (0)