В моем файле index.mjs есть функция, которая объединяет и минимизирует файлы утилит JS. У меня это настроено так:
import fs from "fs";
import { minify } from "terser";
function concatenateAndMinifyJsFiles() {
const jsDir = "./js/";
const mainJsFile = "./js/main.min.js";
// Concatenate and minify .js files
fs.readdir(jsDir, { withFileTypes: true }, (err, files) => {
if (err) {
console.error(`Error reading directory ${jsDir}: ${err}`);
return;
}
const jsFiles = files.filter((file) => file.isFile() && file.name.endsWith(".js"));
if (jsFiles.length === 0) {
console.info(`No .js files found in ${jsDir}`);
return;
}
const concatenatedJs = jsFiles.map((file) => fs.readFileSync(`${jsDir}${file.name}`, "utf8")).join("\n");
const minifiedJs = minify(concatenatedJs).code;
fs.writeFile(mainJsFile, minifiedJs, (err) => {
if (err) {
console.error(`Error writing file ${mainJsFile}: ${err}`);
} else {
console.info(`File ${mainJsFile} has been created`);
}
});
});
}
Я получаю следующее сообщение об ошибке TypeError:
node:internal/fs/utils:885
throw new ERR_INVALID_ARG_TYPE(
^
TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined
После закомментирования каждого раздела оказывается, что раздел, в котором используется команда writeFile:
fs.writeFile(mainJsFile, minifiedJs, (err) => {
if (err) {
console.error(`Error writing file ${mainJsFile}: ${err}`);
} else {
console.info(`File ${mainJsFile} has been created`);
}
});
Значение mainJsFile является строкой. Значение minifiedJs из функции минимизации Terser также является строкой (из переменной concatenatedJs).
Я использую Node версии 16.15.1. Я не вижу в своем коде ничего, что выглядело бы неуместно в документации Node. Есть мысли о том, почему выдается эта ошибка?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ошибка, которую вы видите в модуле fs, верна. Значение, которое вы передаете в качестве аргумента данных, не является одним из разрешенных типов.
Согласно документации Terser по адресу https://www.npmjs.com/package/terser функция minify является асинхронной, и поэтому вы должны добавить await перед ее вызовом. Вызов writeFile вызывает жалобу, потому что на самом деле тип данных undefined, а не string. Это связано с тем, что вы пытаетесь получить доступ к свойству code промиса, которого не существует (и, следовательно, JavaScript оценивает его как неопределенное).
Попробуйте использовать следующее:
const result = await minify(concatenatedJs);
const minifiedJs = result.code;
Обратите внимание, что я разделил это на две переменные (в основном для ясности), потому что вы не можете получить доступ к свойству code, пока не будет ожидан результат.
Редактировать:
Как упоминал @jfriend00 в ответах на ответ, вам также необходимо пометить функцию, содержащую это ключевое слово await, как async. В вашем случае вам нужно будет пометить функцию обратного вызова для fs.readdir как асинхронную. Если вы этого не сделаете, вы получите сообщение об ошибке, поскольку вы не можете ожидать выполнения других асинхронных функций в неасинхронной функции.
fs.readdir(jsDir, { withFileTypes: true }, async (err, files) => {
// your code here
});
Чтобы использовать await, содержащая функция также должна быть async.
@jfriend00 Спасибо за заметку. Я обновил свой ответ, включив это.
Является ли minifiedJs тем, что вы ожидаете?