1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.exec = exec;
|
7 | exports.findPackageJSONDir = findPackageJSONDir;
|
8 | exports.getPostcssImplementation = getPostcssImplementation;
|
9 | exports.getPostcssOptions = getPostcssOptions;
|
10 | exports.loadConfig = loadConfig;
|
11 | exports.normalizeSourceMap = normalizeSourceMap;
|
12 | exports.normalizeSourceMapAfterPostcss = normalizeSourceMapAfterPostcss;
|
13 | exports.reportError = reportError;
|
14 | exports.warningFactory = warningFactory;
|
15 | var _path = _interopRequireDefault(require("path"));
|
16 | var _url = _interopRequireDefault(require("url"));
|
17 | var _module = _interopRequireDefault(require("module"));
|
18 | var _cosmiconfig = require("cosmiconfig");
|
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
20 | const parentModule = module;
|
21 | const stat = (inputFileSystem, filePath) => new Promise((resolve, reject) => {
|
22 | inputFileSystem.stat(filePath, (err, stats) => {
|
23 | if (err) {
|
24 | reject(err);
|
25 | }
|
26 | resolve(stats);
|
27 | });
|
28 | });
|
29 | function exec(code, loaderContext) {
|
30 | const {
|
31 | resource,
|
32 | context
|
33 | } = loaderContext;
|
34 | const module = new _module.default(resource, parentModule);
|
35 |
|
36 |
|
37 | module.paths = _module.default._nodeModulePaths(context);
|
38 | module.filename = resource;
|
39 |
|
40 |
|
41 | module._compile(code, resource);
|
42 | return module.exports;
|
43 | }
|
44 | let tsLoader;
|
45 | async function loadConfig(loaderContext, config, postcssOptions) {
|
46 | const searchPath = typeof config === "string" ? _path.default.resolve(config) : _path.default.dirname(loaderContext.resourcePath);
|
47 | let stats;
|
48 | try {
|
49 | stats = await stat(loaderContext.fs, searchPath);
|
50 | } catch (errorIgnore) {
|
51 | throw new Error(`No PostCSS config found in: ${searchPath}`);
|
52 | }
|
53 | const moduleName = "postcss";
|
54 | const searchPlaces = [
|
55 |
|
56 | "package.json", `${moduleName}.config.js`, `${moduleName}.config.mjs`, `${moduleName}.config.cjs`, `${moduleName}.config.ts`, `${moduleName}.config.mts`, `${moduleName}.config.cts`, `.${moduleName}rc`, `.${moduleName}rc.json`, `.${moduleName}rc.js`, `.${moduleName}rc.mjs`, `.${moduleName}rc.cjs`, `.${moduleName}rc.ts`, `.${moduleName}rc.mts`, `.${moduleName}rc.cts`, `.${moduleName}rc.yaml`, `.${moduleName}rc.yml`, `.config/${moduleName}rc`, `.config/${moduleName}rc.json`, `.config/${moduleName}rc.yaml`, `.config/${moduleName}rc.yml`, `.config/${moduleName}rc.js`, `.config/${moduleName}rc.mjs`, `.config/${moduleName}rc.cjs`, `.config/${moduleName}rc.ts`, `.config/${moduleName}rc.mts`, `.config/${moduleName}rc.cts`];
|
57 | const loaders = {
|
58 | ".js": async (...args) => {
|
59 | let result;
|
60 | try {
|
61 | result = _cosmiconfig.defaultLoadersSync[".js"](...args);
|
62 | } catch (error) {
|
63 | let importESM;
|
64 | try {
|
65 |
|
66 | importESM = new Function("id", "return import(id);");
|
67 | } catch (e) {
|
68 | importESM = null;
|
69 | }
|
70 | if (error.code === "ERR_REQUIRE_ESM" && _url.default.pathToFileURL && importESM) {
|
71 | const urlForConfig = _url.default.pathToFileURL(args[0]);
|
72 | result = await importESM(urlForConfig);
|
73 | } else {
|
74 | throw error;
|
75 | }
|
76 | }
|
77 | if (result.default) {
|
78 | return result.default;
|
79 | }
|
80 | return result;
|
81 | },
|
82 | ".cjs": _cosmiconfig.defaultLoadersSync[".cjs"],
|
83 | ".mjs": async (...args) => {
|
84 | let result;
|
85 | let importESM;
|
86 | try {
|
87 |
|
88 | importESM = new Function("id", "return import(id);");
|
89 | } catch (e) {
|
90 | importESM = null;
|
91 | }
|
92 | if (_url.default.pathToFileURL && importESM) {
|
93 | const urlForConfig = _url.default.pathToFileURL(args[0]);
|
94 | result = await importESM(urlForConfig);
|
95 | } else {
|
96 | throw new Error("ESM is not supported");
|
97 | }
|
98 | if (result.default) {
|
99 | return result.default;
|
100 | }
|
101 | return result;
|
102 | }
|
103 | };
|
104 | if (!tsLoader) {
|
105 | const opts = {
|
106 | interopDefault: true
|
107 | };
|
108 |
|
109 | const jiti = require("jiti")(__filename, opts);
|
110 | tsLoader = filepath => jiti(filepath);
|
111 | }
|
112 | loaders[".cts"] = tsLoader;
|
113 | loaders[".mts"] = tsLoader;
|
114 | loaders[".ts"] = tsLoader;
|
115 | const explorer = (0, _cosmiconfig.cosmiconfig)(moduleName, {
|
116 | searchStrategy: "global",
|
117 | searchPlaces,
|
118 | loaders
|
119 | });
|
120 | let result;
|
121 | try {
|
122 | if (stats.isFile()) {
|
123 | result = await explorer.load(searchPath);
|
124 | } else {
|
125 | result = await explorer.search(searchPath);
|
126 | }
|
127 | } catch (error) {
|
128 | throw error;
|
129 | }
|
130 | if (!result) {
|
131 | return {};
|
132 | }
|
133 | loaderContext.addBuildDependency(result.filepath);
|
134 | loaderContext.addDependency(result.filepath);
|
135 | if (result.isEmpty) {
|
136 | return result;
|
137 | }
|
138 | if (typeof result.config === "function") {
|
139 | const api = {
|
140 | mode: loaderContext.mode,
|
141 | file: loaderContext.resourcePath,
|
142 |
|
143 | webpackLoaderContext: loaderContext,
|
144 |
|
145 | env: loaderContext.mode,
|
146 | options: postcssOptions || {}
|
147 | };
|
148 | return {
|
149 | ...result,
|
150 | config: result.config(api)
|
151 | };
|
152 | }
|
153 | return result;
|
154 | }
|
155 | function loadPlugin(plugin, options, file) {
|
156 | try {
|
157 |
|
158 | let loadedPlugin = require(plugin);
|
159 | if (loadedPlugin.default) {
|
160 | loadedPlugin = loadedPlugin.default;
|
161 | }
|
162 | if (!options || Object.keys(options).length === 0) {
|
163 | return loadedPlugin;
|
164 | }
|
165 | return loadedPlugin(options);
|
166 | } catch (error) {
|
167 | throw new Error(`Loading PostCSS "${plugin}" plugin failed: ${error.message}\n\n(@${file})`);
|
168 | }
|
169 | }
|
170 | function pluginFactory() {
|
171 | const listOfPlugins = new Map();
|
172 | return plugins => {
|
173 | if (typeof plugins === "undefined") {
|
174 | return listOfPlugins;
|
175 | }
|
176 | if (Array.isArray(plugins)) {
|
177 | for (const plugin of plugins) {
|
178 | if (Array.isArray(plugin)) {
|
179 | const [name, options] = plugin;
|
180 | listOfPlugins.set(name, options);
|
181 | } else if (plugin && typeof plugin === "function") {
|
182 | listOfPlugins.set(plugin);
|
183 | } else if (plugin && Object.keys(plugin).length === 1 && (typeof plugin[Object.keys(plugin)[0]] === "object" || typeof plugin[Object.keys(plugin)[0]] === "boolean") && plugin[Object.keys(plugin)[0]] !== null) {
|
184 | const [name] = Object.keys(plugin);
|
185 | const options = plugin[name];
|
186 | if (options === false) {
|
187 | listOfPlugins.delete(name);
|
188 | } else {
|
189 | listOfPlugins.set(name, options);
|
190 | }
|
191 | } else if (plugin) {
|
192 | listOfPlugins.set(plugin);
|
193 | }
|
194 | }
|
195 | } else {
|
196 | const objectPlugins = Object.entries(plugins);
|
197 | for (const [name, options] of objectPlugins) {
|
198 | if (options === false) {
|
199 | listOfPlugins.delete(name);
|
200 | } else {
|
201 | listOfPlugins.set(name, options);
|
202 | }
|
203 | }
|
204 | }
|
205 | return listOfPlugins;
|
206 | };
|
207 | }
|
208 | async function tryRequireThenImport(module) {
|
209 | let exports;
|
210 | try {
|
211 |
|
212 | exports = require(module);
|
213 | return exports;
|
214 | } catch (requireError) {
|
215 | let importESM;
|
216 | try {
|
217 |
|
218 | importESM = new Function("id", "return import(id);");
|
219 | } catch (e) {
|
220 | importESM = null;
|
221 | }
|
222 | if (requireError.code === "ERR_REQUIRE_ESM" && importESM) {
|
223 | exports = await importESM(module);
|
224 | return exports.default;
|
225 | }
|
226 | throw requireError;
|
227 | }
|
228 | }
|
229 | async function getPostcssOptions(loaderContext, loadedConfig = {}, postcssOptions = {}) {
|
230 | const file = loaderContext.resourcePath;
|
231 | let normalizedPostcssOptions = postcssOptions;
|
232 | if (typeof normalizedPostcssOptions === "function") {
|
233 | normalizedPostcssOptions = normalizedPostcssOptions(loaderContext);
|
234 | }
|
235 | let plugins = [];
|
236 | try {
|
237 | const factory = pluginFactory();
|
238 | if (loadedConfig.config && loadedConfig.config.plugins) {
|
239 | factory(loadedConfig.config.plugins);
|
240 | }
|
241 | factory(normalizedPostcssOptions.plugins);
|
242 | plugins = [...factory()].map(item => {
|
243 | const [plugin, options] = item;
|
244 | if (typeof plugin === "string") {
|
245 | return loadPlugin(plugin, options, file);
|
246 | }
|
247 | return plugin;
|
248 | });
|
249 | } catch (error) {
|
250 | loaderContext.emitError(error);
|
251 | }
|
252 | const processOptionsFromConfig = {
|
253 | ...loadedConfig.config
|
254 | } || {};
|
255 | if (processOptionsFromConfig.from) {
|
256 | processOptionsFromConfig.from = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.from);
|
257 | }
|
258 | if (processOptionsFromConfig.to) {
|
259 | processOptionsFromConfig.to = _path.default.resolve(_path.default.dirname(loadedConfig.filepath), processOptionsFromConfig.to);
|
260 | }
|
261 | const processOptionsFromOptions = {
|
262 | ...normalizedPostcssOptions
|
263 | };
|
264 | if (processOptionsFromOptions.from) {
|
265 | processOptionsFromOptions.from = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.from);
|
266 | }
|
267 | if (processOptionsFromOptions.to) {
|
268 | processOptionsFromOptions.to = _path.default.resolve(loaderContext.rootContext, processOptionsFromOptions.to);
|
269 | }
|
270 |
|
271 |
|
272 | const {
|
273 | plugins: __plugins,
|
274 | ...optionsFromConfig
|
275 | } = processOptionsFromConfig;
|
276 | const {
|
277 | config: _config,
|
278 | plugins: _plugins,
|
279 | ...optionsFromOptions
|
280 | } = processOptionsFromOptions;
|
281 | const processOptions = {
|
282 | from: file,
|
283 | to: file,
|
284 | map: false,
|
285 | ...optionsFromConfig,
|
286 | ...optionsFromOptions
|
287 | };
|
288 | if (typeof processOptions.parser === "string") {
|
289 | try {
|
290 | processOptions.parser = await tryRequireThenImport(processOptions.parser);
|
291 | } catch (error) {
|
292 | loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.parser}" parser failed: ${error.message}\n\n(@${file})`));
|
293 | }
|
294 | }
|
295 | if (typeof processOptions.stringifier === "string") {
|
296 | try {
|
297 | processOptions.stringifier = await tryRequireThenImport(processOptions.stringifier);
|
298 | } catch (error) {
|
299 | loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.stringifier}" stringifier failed: ${error.message}\n\n(@${file})`));
|
300 | }
|
301 | }
|
302 | if (typeof processOptions.syntax === "string") {
|
303 | try {
|
304 | processOptions.syntax = await tryRequireThenImport(processOptions.syntax);
|
305 | } catch (error) {
|
306 | loaderContext.emitError(new Error(`Loading PostCSS "${processOptions.syntax}" syntax failed: ${error.message}\n\n(@${file})`));
|
307 | }
|
308 | }
|
309 | if (processOptions.map === true) {
|
310 |
|
311 | processOptions.map = {
|
312 | inline: true
|
313 | };
|
314 | }
|
315 | return {
|
316 | plugins,
|
317 | processOptions
|
318 | };
|
319 | }
|
320 | const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
|
321 | const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;
|
322 | function getURLType(source) {
|
323 | if (source[0] === "/") {
|
324 | if (source[1] === "/") {
|
325 | return "scheme-relative";
|
326 | }
|
327 | return "path-absolute";
|
328 | }
|
329 | if (IS_NATIVE_WIN32_PATH.test(source)) {
|
330 | return "path-absolute";
|
331 | }
|
332 | return ABSOLUTE_SCHEME.test(source) ? "absolute" : "path-relative";
|
333 | }
|
334 | function normalizeSourceMap(map, resourceContext) {
|
335 | let newMap = map;
|
336 |
|
337 |
|
338 |
|
339 | if (typeof newMap === "string") {
|
340 | newMap = JSON.parse(newMap);
|
341 | }
|
342 | delete newMap.file;
|
343 | const {
|
344 | sourceRoot
|
345 | } = newMap;
|
346 | delete newMap.sourceRoot;
|
347 | if (newMap.sources) {
|
348 | newMap.sources = newMap.sources.map(source => {
|
349 | const sourceType = getURLType(source);
|
350 |
|
351 |
|
352 | if (sourceType === "path-relative" || sourceType === "path-absolute") {
|
353 | const absoluteSource = sourceType === "path-relative" && sourceRoot ? _path.default.resolve(sourceRoot, _path.default.normalize(source)) : _path.default.normalize(source);
|
354 | return _path.default.relative(resourceContext, absoluteSource);
|
355 | }
|
356 | return source;
|
357 | });
|
358 | }
|
359 | return newMap;
|
360 | }
|
361 | function normalizeSourceMapAfterPostcss(map, resourceContext) {
|
362 | const newMap = map;
|
363 |
|
364 |
|
365 |
|
366 |
|
367 | delete newMap.file;
|
368 |
|
369 |
|
370 | newMap.sourceRoot = "";
|
371 |
|
372 |
|
373 | newMap.sources = newMap.sources.map(source => {
|
374 | if (source.indexOf("<") === 0) {
|
375 | return source;
|
376 | }
|
377 | const sourceType = getURLType(source);
|
378 |
|
379 |
|
380 | if (sourceType === "path-relative") {
|
381 | return _path.default.resolve(resourceContext, source);
|
382 | }
|
383 | return source;
|
384 | });
|
385 | return newMap;
|
386 | }
|
387 | function findPackageJSONDir(cwd, statSync) {
|
388 | let dir = cwd;
|
389 | for (;;) {
|
390 | try {
|
391 | if (statSync(_path.default.join(dir, "package.json")).isFile()) {
|
392 | break;
|
393 | }
|
394 | } catch (error) {
|
395 |
|
396 | }
|
397 | const parent = _path.default.dirname(dir);
|
398 | if (dir === parent) {
|
399 | dir = null;
|
400 | break;
|
401 | }
|
402 | dir = parent;
|
403 | }
|
404 | return dir;
|
405 | }
|
406 | function getPostcssImplementation(loaderContext, implementation) {
|
407 | let resolvedImplementation = implementation;
|
408 | if (!implementation || typeof implementation === "string") {
|
409 | const postcssImplPkg = implementation || "postcss";
|
410 |
|
411 |
|
412 | resolvedImplementation = require(postcssImplPkg);
|
413 | }
|
414 |
|
415 |
|
416 | return resolvedImplementation;
|
417 | }
|
418 | function reportError(loaderContext, callback, error) {
|
419 | if (error.file) {
|
420 | loaderContext.addDependency(error.file);
|
421 | }
|
422 | if (error.name === "CssSyntaxError") {
|
423 | callback(syntaxErrorFactory(error));
|
424 | } else {
|
425 | callback(error);
|
426 | }
|
427 | }
|
428 | function warningFactory(warning) {
|
429 | let message = "";
|
430 | if (typeof warning.line !== "undefined") {
|
431 | message += `(${warning.line}:${warning.column}) `;
|
432 | }
|
433 | if (typeof warning.plugin !== "undefined") {
|
434 | message += `from "${warning.plugin}" plugin: `;
|
435 | }
|
436 | message += warning.text;
|
437 | if (warning.node) {
|
438 | message += `\n\nCode:\n ${warning.node.toString()}\n`;
|
439 | }
|
440 | const obj = new Error(message, {
|
441 | cause: warning
|
442 | });
|
443 | obj.stack = null;
|
444 | return obj;
|
445 | }
|
446 | function syntaxErrorFactory(error) {
|
447 | let message = "\nSyntaxError\n\n";
|
448 | if (typeof error.line !== "undefined") {
|
449 | message += `(${error.line}:${error.column}) `;
|
450 | }
|
451 | if (typeof error.plugin !== "undefined") {
|
452 | message += `from "${error.plugin}" plugin: `;
|
453 | }
|
454 | message += error.file ? `${error.file} ` : "<css input> ";
|
455 | message += `${error.reason}`;
|
456 | const code = error.showSourceCode();
|
457 | if (code) {
|
458 | message += `\n\n${code}\n`;
|
459 | }
|
460 | const obj = new Error(message, {
|
461 | cause: error
|
462 | });
|
463 | obj.stack = null;
|
464 | return obj;
|
465 | } |
\ | No newline at end of file |