vite-plugin-fenom 1.0.11 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/vite-plugin-fenom.cjs +60 -54
- package/vite-plugin-fenom.cjs.map +1 -1
- package/vite-plugin-fenom.mjs +61 -55
- package/vite-plugin-fenom.mjs.map +1 -1
package/package.json
CHANGED
package/vite-plugin-fenom.cjs
CHANGED
|
@@ -1981,93 +1981,99 @@ function fenomPlugin(options = {}) {
|
|
|
1981
1981
|
const searchPath = require$$0.resolve(config.root, pages);
|
|
1982
1982
|
const pattern = require$$0.join(searchPath, '**/*.tpl').replace(/\\/g, '/');
|
|
1983
1983
|
try {
|
|
1984
|
-
const
|
|
1984
|
+
const templateFiles = await fastGlob(pattern);
|
|
1985
1985
|
if (debug)
|
|
1986
|
-
console.log('
|
|
1987
|
-
// === Сбор
|
|
1988
|
-
const
|
|
1989
|
-
const
|
|
1986
|
+
console.log('[Fenom Plugin] Found templates:', templateFiles);
|
|
1987
|
+
// === Сбор всех выходных файлов ===
|
|
1988
|
+
const emittedJs = {}; // relative moduleId → /out.js
|
|
1989
|
+
const emittedCss = {}; // input basename → /out.css
|
|
1990
1990
|
for (const [fileName, file] of Object.entries(bundle)) {
|
|
1991
|
-
const
|
|
1991
|
+
const publicPath = `/${fileName}`;
|
|
1992
1992
|
if (file.type === 'chunk' && file.facadeModuleId) {
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
entryChunks[inputPath] = outFile;
|
|
1993
|
+
const moduleId = require$$0.relative(config.root, file.facadeModuleId).replace(/\\/g, '/');
|
|
1994
|
+
emittedJs[moduleId] = publicPath;
|
|
1996
1995
|
}
|
|
1997
1996
|
if (file.type === 'asset' && fileName.endsWith('.css')) {
|
|
1998
|
-
//
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
const baseName = require$$0.basename(file.name, '.css');
|
|
2003
|
-
// Пока просто запоминаем — уточним позже
|
|
2004
|
-
cssAssets[file.name] = outFile;
|
|
2005
|
-
}
|
|
1997
|
+
// Сохраняем по базовому имени (без хеша)
|
|
1998
|
+
const baseName = fileName.replace(/\.[^.]+\.css$/, '.css'); // main.hash.css → main.css
|
|
1999
|
+
const keyName = baseName === fileName ? require$$0.basename(fileName, '.css') : baseName.replace('.css', '');
|
|
2000
|
+
emittedCss[keyName] = publicPath;
|
|
2006
2001
|
}
|
|
2007
2002
|
}
|
|
2008
|
-
// ===
|
|
2003
|
+
// === Получаем все входы как массив строк ===
|
|
2009
2004
|
const inputEntries = config.build.rollupOptions.input;
|
|
2010
|
-
const
|
|
2005
|
+
const inputPaths = [];
|
|
2011
2006
|
if (Array.isArray(inputEntries)) {
|
|
2012
|
-
|
|
2007
|
+
inputPaths.push(...inputEntries);
|
|
2013
2008
|
}
|
|
2014
2009
|
else if (typeof inputEntries === 'object' && inputEntries !== null) {
|
|
2015
|
-
|
|
2010
|
+
inputPaths.push(...Object.values(inputEntries));
|
|
2016
2011
|
}
|
|
2017
2012
|
else if (typeof inputEntries === 'string') {
|
|
2018
|
-
|
|
2013
|
+
inputPaths.push(inputEntries);
|
|
2019
2014
|
}
|
|
2020
|
-
//
|
|
2015
|
+
// Нормализуем: приводим к абсолютному пути, затем к относительному от корня
|
|
2016
|
+
const normalizedInputs = inputPaths.map((input) => {
|
|
2017
|
+
// Если путь абсолютный (начинается с /), считаем его относительно корня
|
|
2018
|
+
const absolute = input.startsWith('/')
|
|
2019
|
+
? require$$0.resolve(config.root, '.' + input) // /src/main.ts → root/src/main.ts
|
|
2020
|
+
: require$$0.resolve(config.root, input); // src/main.ts → root/src/main.ts
|
|
2021
|
+
return require$$0.relative(config.root, absolute).replace(/\\/g, '/');
|
|
2022
|
+
});
|
|
2023
|
+
// === Карта замены: исходный путь (в шаблоне) → выходной ассет ===
|
|
2021
2024
|
const replacementMap = new Map();
|
|
2022
|
-
for (const input of
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
if (entryChunks[moduleId]) {
|
|
2030
|
-
replacementMap.set(relativeInput, entryChunks[moduleId]);
|
|
2025
|
+
for (const input of normalizedInputs) {
|
|
2026
|
+
const ext = require$$0.extname(input).toLowerCase();
|
|
2027
|
+
const baseInputName = require$$0.basename(input, ext);
|
|
2028
|
+
if (ext === '.ts' || ext === '.js') {
|
|
2029
|
+
if (emittedJs[input]) {
|
|
2030
|
+
// Прямое совпадение
|
|
2031
|
+
replacementMap.set(`/${input}`, { type: 'js', path: emittedJs[input] });
|
|
2031
2032
|
}
|
|
2032
2033
|
}
|
|
2033
|
-
if (
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2034
|
+
if (ext === '.scss' || ext === '.css') {
|
|
2035
|
+
// Ищем CSS-файл по базовому имени
|
|
2036
|
+
const matchedCss = Object.keys(emittedCss).find(key => key === baseInputName ||
|
|
2037
|
+
key === require$$0.basename(input) ||
|
|
2038
|
+
key.includes(baseInputName));
|
|
2037
2039
|
if (matchedCss) {
|
|
2038
|
-
replacementMap.set(
|
|
2040
|
+
replacementMap.set(`/${input}`, { type: 'css', path: emittedCss[matchedCss] });
|
|
2039
2041
|
}
|
|
2040
2042
|
}
|
|
2041
2043
|
}
|
|
2042
2044
|
// === Генерация HTML ===
|
|
2043
|
-
for (const file of
|
|
2044
|
-
const
|
|
2045
|
-
const outputFileName =
|
|
2045
|
+
for (const file of templateFiles) {
|
|
2046
|
+
const pageName = require$$0.basename(file, '.tpl');
|
|
2047
|
+
const outputFileName = pageName === 'index' ? 'index.html' : `${pageName}.html`;
|
|
2046
2048
|
const source = await fs__namespace.readFile(file, 'utf-8');
|
|
2047
2049
|
const context = {
|
|
2048
|
-
title: `${
|
|
2050
|
+
title: `${pageName.charAt(0).toUpperCase() + pageName.slice(1)} Page`,
|
|
2049
2051
|
debug: false,
|
|
2050
|
-
url: '/' + (
|
|
2052
|
+
url: '/' + (pageName === 'index' ? '' : pageName),
|
|
2051
2053
|
...globalData,
|
|
2052
2054
|
};
|
|
2053
2055
|
let html = await FenomJs(source, {
|
|
2054
|
-
context
|
|
2056
|
+
context,
|
|
2055
2057
|
loader: templateLoader,
|
|
2056
2058
|
minify: minifyHtml,
|
|
2057
2059
|
});
|
|
2058
|
-
// === Замена путей ===
|
|
2059
|
-
for (const [devPath,
|
|
2060
|
-
|
|
2061
|
-
const escaped =
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
html = html.replace(scriptRegex, `<script type="module" src="${
|
|
2060
|
+
// === Замена тегов: поддержка путей с / и без / ===
|
|
2061
|
+
for (const [devPath, { type, path }] of replacementMap) {
|
|
2062
|
+
// devPath уже с `/` в начале: `/src/main.ts`
|
|
2063
|
+
const escaped = devPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
2064
|
+
if (type === 'js') {
|
|
2065
|
+
const scriptRegex = new RegExp(`<script[^>]+src=["']${escaped}["'][^>]*/?>`, 'gi');
|
|
2066
|
+
html = html.replace(scriptRegex, `<script type="module" src="${path}"></script>`);
|
|
2065
2067
|
}
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
html = html.replace(linkRegex, `<link rel="stylesheet" href="${
|
|
2068
|
+
if (type === 'css') {
|
|
2069
|
+
const linkRegex = new RegExp(`<link[^>]+href=["']${escaped}["'][^>]*/?>`, 'gi');
|
|
2070
|
+
html = html.replace(linkRegex, `<link rel="stylesheet" href="${path}">`);
|
|
2069
2071
|
}
|
|
2070
2072
|
}
|
|
2073
|
+
// Минификация
|
|
2074
|
+
if (minifyHtml) {
|
|
2075
|
+
html = html.replace(/>\s+</g, '><').replace(/\s+/g, ' ').trim();
|
|
2076
|
+
}
|
|
2071
2077
|
this.emitFile({
|
|
2072
2078
|
type: 'asset',
|
|
2073
2079
|
fileName: outputFileName,
|
|
@@ -2078,7 +2084,7 @@ function fenomPlugin(options = {}) {
|
|
|
2078
2084
|
}
|
|
2079
2085
|
}
|
|
2080
2086
|
catch (err) {
|
|
2081
|
-
console.error('\x1b[31m[Fenom Plugin]\x1b[0m
|
|
2087
|
+
console.error('\x1b[31m[Fenom Plugin]\x1b[0m Build error:', err);
|
|
2082
2088
|
}
|
|
2083
2089
|
},
|
|
2084
2090
|
};
|