function buildComplex()

in resources/todomvc/big-dom-generator/utils/buildComplex.js [24:120]


function buildComplex(options) {
    const {
        callerDirectory,
        sourceDirectory,
        title,
        filesToMove,
        cssFilePath,
        cssFolder = "", // sometimes the css file we are looking for may be nested in another folder.
        cssFileNamePattern, // This is mandatory if cssFilePath is provided.
        extraCssToLink = [],
        scriptsToLink = [],
        targetDirectory = "./dist",
        complexDomHtmlFile = "index.html",
        todoHtmlFile = "index.html",
        cssFilesToAddLinksFor = ["big-dom.css"],
    } = options;

    prepareComplex(options);

    // npm ci in big-dom-generator needs to run before we import JSDOM
    let JSDOM;
    try {
        JSDOM = require("jsdom").JSDOM;
    } catch (e) {
        console.error("Error: jsdom is not installed.");
        process.exit(1);
    }

    // Remove dist directory if it exists
    fs.rmSync(path.resolve(targetDirectory), { recursive: true, force: true });

    // Re-create the directory
    fs.mkdirSync(path.resolve(targetDirectory));

    // Copy dist folder from javascript-es6-webpack
    fs.cpSync(path.join(callerDirectory, sourceDirectory), path.resolve(targetDirectory), { recursive: true });

    // Copy files to move
    for (let i = 0; i < filesToMove.length; i++) {
        // Rename app.css to big-dom.css so it's unique
        const sourcePath = path.resolve(callerDirectory, "..", filesToMove[i]);
        const fileName = path.basename(filesToMove[i]);
        const targetPath = path.join(targetDirectory, fileName);
        fs.copyFileSync(sourcePath, targetPath);
    }

    if (cssFilePath) {
        // Get the name of the CSS file that's in the dist, we do this because the name of the CSS file may change
        const cssFolderDirectory = path.join(callerDirectory, sourceDirectory, cssFolder);
        const cssFile = fs.readdirSync(cssFolderDirectory, { withFileTypes: true }).find((dirent) => dirent.isFile() && cssFileNamePattern.test(dirent.name))?.name;
        // Overwrite the CSS file in the dist directory with the one from the big-dom-generator module
        // but keep the existing name so we don't need to add a new link
        fs.copyFileSync(cssFilePath, path.resolve(targetDirectory, cssFolder, cssFile));
    }

    // Read todo.html file
    let html = fs.readFileSync(path.resolve(callerDirectory, path.join("..", "dist", todoHtmlFile)), "utf8");

    const dom = new JSDOM(html);
    const doc = dom.window.document;
    const head = doc.querySelector("head");

    doc.documentElement.setAttribute("class", "spectrum spectrum--medium spectrum--light");

    const body = doc.querySelector("body");
    const htmlToInjectInTodoHolder = body.innerHTML;
    body.innerHTML = getHtmlBodySync("node_modules/big-dom-generator/dist/index.html");

    const titleElement = head.querySelector("title");
    titleElement.innerHTML = title;

    const todoHolder = doc.createElement("div");
    todoHolder.className = "todoholder";
    todoHolder.innerHTML = htmlToInjectInTodoHolder;

    const todoArea = doc.querySelector(".todo-area");
    todoArea.appendChild(todoHolder);

    const cssFilesToAddLinksForFinal = [...cssFilesToAddLinksFor, ...extraCssToLink];
    for (const cssFile of cssFilesToAddLinksForFinal) {
        const cssLink = doc.createElement("link");
        cssLink.rel = "stylesheet";
        cssLink.href = cssFile;
        head.appendChild(cssLink);
    }

    for (const script of scriptsToLink) {
        const scriptLink = doc.createElement("script");
        scriptLink.src = script;
        head.appendChild(scriptLink);
    }

    const destinationFilePath = path.join(targetDirectory, complexDomHtmlFile);
    fs.writeFileSync(destinationFilePath, dom.serialize());

    console.log(`The complex code for ${sourceDirectory} has been written to ${destinationFilePath}.`);
}