You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.9 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const bl = require("bl");
const through2 = require("through2");
const path = require("path");
const createFilePreprocessor = require("./postcss/preprocess");
const loaderShimPath = require("./loader-shim-path");
module.exports = function (state) {
const isCss = require("./is-css")(state);
return function createTransform(file, options) {
// TODO: Reuse instance?
let preprocessFile = createFilePreprocessor(options);
if (isCss({ file: file })) {
let buffer = new bl.BufferList();
function chunkHandler(chunk, encoding, callback) {
// NOTE: We check the `chunk` here, not the `encoding`, because in at least one instance a Buffer was passed in claiming to be a "utf8" string according to the `encoding` argument
if (Buffer.isBuffer(chunk)) {
buffer.append(chunk);
callback();
} else {
throw new Error(`Expected Buffer, got string instead (encoding = ${encoding})`);
}
}
function endHandler(callback) {
return Promise.try(() => {
return preprocessFile({ file: file, source: buffer.toString() });
}).then((result) => {
let imports = result.messages
.filter((message) => {
return (
message.pluginName === "postcss-icss-find-imports"
&& message.type === "import"
);
})
.map((message) => message.url);
imports.forEach((importUrl) => {
this.emit("dep", importUrl);
});
// This ensures that whenever *any* CSS file is processed, the global loader file gets included as well (which is the file that eventually inserts the concatenated CSS)
let relativeLoaderPath = path.relative(path.dirname(file), loaderShimPath);
this.emit("dep", relativeLoaderPath);
this.push(result.css);
callback();
}).catch((error) => {
callback(error);
});
}
return through2.obj(chunkHandler, endHandler);
} else {
return through2.obj();
}
};
};