paperclip-loader
Version:
This project was bootstrapped by [create-neon](https://www.npmjs.com/package/create-neon).
90 lines (78 loc) • 2.63 kB
text/typescript
const { startLoader, compileFile, getConfigContext } = require("./main.node");
import { ConfigContext } from "@paperclip-ui/config";
import * as path from "path";
import * as fs from "fs";
type Options = {
configFile: string;
resourceProtocol?: string;
globalScript: string;
};
const DEFAULT_CONFIG_FILE_NAME = "paperclip.config.json";
let _loader: any;
const getLoader = (directory: string, configFileName: string) => {
if (!_loader) {
_loader = startLoader(directory, configFileName);
}
return _loader;
};
module.exports = function (source: string) {
this.cacheable();
const callback = this.async();
const options: Options = { ...this.getOptions() };
if (options.globalScript) {
return callback(null, includeGlobalScript(options.globalScript));
}
const { configFile = DEFAULT_CONFIG_FILE_NAME } = options;
const loader = getLoader(process.cwd(), configFile);
const compiledFiles = compileFile(loader, this.resourcePath);
let mainContent: string;
for (const compiledFilePath in compiledFiles) {
if (/\.js$/.test(compiledFilePath)) {
mainContent = compiledFiles[compiledFilePath];
}
}
const configContext: ConfigContext = getConfigContext(loader);
// inspiration: https://github.com/sveltejs/svelte-loader/blob/master/index.js
if (configContext.config.globalScripts) {
for (const relPath of configContext.config.globalScripts) {
const scriptPath = relPath.includes("://")
? relPath
: path.join(configContext.directory, relPath);
mainContent =
`import "${encodeURIComponent(
scriptPath
)}.js!=!paperclip-loader?globalScript=${scriptPath}!${path.join(
configContext.directory,
configContext.fileName
)}";\n` + mainContent;
}
}
callback(null, mainContent);
};
const includeGlobalScript = (script: string) => {
if (script.includes("://")) {
if (/\.css$/.test(script)) {
return `
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "${script}";
document.head.appendChild(link);
`;
}
} else {
const content = fs.readFileSync(script, "utf8");
if (/\.css$/.test(script)) {
return `
const style = document.createElement("style");
style.textContent = ${JSON.stringify(content)};
document.head.appendChild(style);
`;
} else if (/\.js/.test(script)) {
return `
const script = document.createElement("script");
script.textContent = ${JSON.stringify(content)};
document.head.appendChild(script);
`;
}
}
};