import { createRequire } from "module";
import path from "path";
import { promisify } from "util";
import resolve from "resolve";
import PQueue from "p-queue";
function loadModule(moduleId) {
try {
return require(moduleId);
} catch {
}
try {
return createRequire(path.resolve(process.cwd(), "noop.js"))(moduleId);
} catch {
}
}
const threadPoolSize = process.env.UV_THREADPOOL_SIZE || 4;
const workQueue = new PQueue({ concurrency: threadPoolSize - 1 });
const moduleRe = /^~([a-z\d]|@).+/i;
const getUrlOfPartial = (url) => {
const parsedUrl = path.parse(url);
return `${parsedUrl.dir}${path.sep}_${parsedUrl.base}`;
};
const resolvePromise = promisify(resolve);
const sassModuleIds = ["node-sass", "sass"];
export default {
name: "sass",
test: /\.(sass|scss)$/,
process({ code }) {
return new Promise((resolve, reject) => {
const sass = loadSassOrThrow();
const render = promisify(sass.render.bind(sass));
const data = this.options.data || "";
workQueue.add(() =>
render({
...this.options,
file: this.id,
data: data + code,
indentedSyntax: /\.sass$/.test(this.id),
sourceMap: this.sourceMap,
importer: [
(url, importer, done) => {
if (!moduleRe.test(url)) {
if (/^@styles/.test(url)) {
return done({
file: url.replace(
/^@styles/,
path.resolve(__dirname, "./src/styles"),
),
});
}
return done({ file: url });
}
const moduleUrl = url.slice(1);
const partialUrl = getUrlOfPartial(moduleUrl);
const options = {
basedir: path.dirname(importer),
extensions: [".scss", ".sass", ".css"],
};
const finishImport = (id) => {
done({
file: id.endsWith(".css") ? id.replace(/\.css$/, "") : id,
});
};
const next = () => {
done({ file: url });
};
resolvePromise(partialUrl, options)
.then(finishImport)
.catch((error) => {
if (
error.code === "MODULE_NOT_FOUND" ||
error.code === "ENOENT"
) {
resolvePromise(moduleUrl, options)
.then(finishImport)
.catch(next);
} else {
next();
}
});
},
].concat(this.options.importer || []),
})
.then((result) => {
for (const file of result.stats.includedFiles) {
this.dependencies.add(file);
}
resolve({
code: result.css.toString(),
map: result.map && result.map.toString(),
});
})
.catch(reject),
);
});
},
};