ts-transform-img
Version:
Allow `import * as img from 'foo.png'` in TS
66 lines (65 loc) • 2.83 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const ts = require("typescript");
const path_1 = require("path");
const fs_1 = require("fs");
const loader_utils_1 = require("loader-utils");
const DEFAULT_OPTS = {
threshold: 1e4,
onImgExtracted() { },
};
const IMG_EXTENSION_REGEX = /\.gif|\.png|\.jpg|\.jpeg['"]$/;
function visitor(ctx, sf, opts = DEFAULT_OPTS) {
opts = Object.assign({}, DEFAULT_OPTS, opts);
const { onImgExtracted, threshold, interpolateName: interpolateNameOrFn } = opts;
const visitor = (node) => {
let imgPath;
let namespaceImport;
if (!ts.isImportDeclaration(node) ||
!node.importClause ||
!node.importClause.namedBindings ||
!ts.isNamespaceImport((namespaceImport = node.importClause.namedBindings)) ||
!IMG_EXTENSION_REGEX.test((imgPath = node.moduleSpecifier.getText(sf)))) {
return ts.visitEachChild(node, visitor, ctx);
}
// Bc cssPath includes ' or "
imgPath = imgPath.replace(/["'"]/g, '');
if (imgPath.startsWith('.')) {
const sourcePath = sf.fileName;
imgPath = path_1.resolve(path_1.dirname(sourcePath), imgPath);
}
const contentStr = fs_1.readFileSync(imgPath);
const ext = path_1.extname(imgPath).substr(1);
let content;
// Embeds everything that's less than threshold
if (Buffer.byteLength(contentStr) > threshold) {
const imgAbsolutePath = path_1.resolve(path_1.basename(sf.fileName), imgPath);
switch (typeof interpolateNameOrFn) {
case 'string':
content = loader_utils_1.interpolateName({ resourcePath: imgAbsolutePath }, interpolateNameOrFn, {
content: contentStr.toString('base64'),
});
break;
case 'function':
content = interpolateNameOrFn(imgAbsolutePath, contentStr);
break;
default:
throw new Error('interpolateName has to be a string or a function');
}
onImgExtracted(content, imgAbsolutePath);
}
else {
content = `data:image/${ext};base64,${contentStr.toString('base64')}`;
}
// This is the "foo" from "import * as foo from 'foo.css'"
const importVar = namespaceImport.name.getText(sf);
return ts.createVariableStatement(undefined, ts.createVariableDeclarationList(ts.createNodeArray([ts.createVariableDeclaration(importVar, undefined, ts.createLiteral(content))])));
};
return visitor;
}
function default_1(opts) {
return (ctx) => {
return (sf) => ts.visitNode(sf, visitor(ctx, sf, opts));
};
}
exports.default = default_1;
;