Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: make Vite work with custom frontend directory
Fixes Vite configuration to work with a custom frontend directory. Also rewrite theme css to resolve urls for assets defined in theme.json Fixes #14046 Fixes #14102
- Loading branch information
1 parent
abb1dae
commit 60c64bf
Showing
11 changed files
with
594 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
flow-server/src/main/resources/plugins/theme-loader/theme-loader-utils.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
// Collect groups [url(] ['|"]optional './|../', file part and end of url | ||
const urlMatcher = /(url\(\s*)(\'|\")?(\.\/|\.\.\/)(\S*)(\2\s*\))/g; | ||
|
||
|
||
function assetsContains(fileUrl, themeFolder, logger) { | ||
const themeProperties = getThemeProperties(themeFolder); | ||
if (!themeProperties) { | ||
logger.debug('No theme properties found.'); | ||
logger.log('No theme properties found.'); | ||
return false; | ||
} | ||
const assets = themeProperties['assets']; | ||
if (!assets) { | ||
logger.debug('No defined assets in theme properties'); | ||
logger.log('No defined assets in theme properties'); | ||
return false; | ||
} | ||
// Go through each asset module | ||
for (let module of Object.keys(assets)) { | ||
const copyRules = assets[module]; | ||
logger.log('asset ' + module); | ||
// Go through each copy rule | ||
for (let copyRule of Object.keys(copyRules)) { | ||
logger.log('rule ' + copyRules[copyRule] + " ---> file " + fileUrl); | ||
// if file starts with copyRule target check if file with path after copy target can be found | ||
if (fileUrl.startsWith(copyRules[copyRule])) { | ||
const targetFile = fileUrl.replace(copyRules[copyRule], ''); | ||
const files = require('glob').sync(path.resolve('node_modules/', module, copyRule), { nodir: true }); | ||
|
||
logger.log('targetFile ' + targetFile); | ||
for (let file of files) { | ||
if (file.endsWith(targetFile)) return true; | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
function getThemeProperties(themeFolder) { | ||
const themePropertyFile = path.resolve(themeFolder, 'theme.json'); | ||
if (!fs.existsSync(themePropertyFile)) { | ||
return {}; | ||
} | ||
const themePropertyFileAsString = fs.readFileSync(themePropertyFile); | ||
if (themePropertyFileAsString.length === 0) { | ||
return {}; | ||
} | ||
return JSON.parse(themePropertyFileAsString); | ||
} | ||
|
||
|
||
function rewriteCssUrls(source, handledResourceFolder, themeFolder, logger, options) { | ||
source = source.replace(urlMatcher, function (match, url, quoteMark, replace, fileUrl, endString) { | ||
let absolutePath = path.resolve(handledResourceFolder, replace, fileUrl); | ||
const existingThemeResource = absolutePath.startsWith(themeFolder) && fs.existsSync(absolutePath); | ||
if ( | ||
existingThemeResource || assetsContains(fileUrl, themeFolder, logger) | ||
) { | ||
// Adding ./ will skip css-loader, which should be done for asset files | ||
const skipLoader = existingThemeResource ? '' : './'; | ||
const frontendThemeFolder = skipLoader + 'themes/' + path.basename(themeFolder); | ||
logger.debug( | ||
'Updating url for file', | ||
"'" + replace + fileUrl + "'", | ||
'to use', | ||
"'" + frontendThemeFolder + '/' + fileUrl + "'" | ||
); | ||
const pathResolved = absolutePath.substring(themeFolder.length).replace(/\\/g, '/'); | ||
|
||
// keep the url the same except replace the ./ or ../ to themes/[themeFolder] | ||
return url + (quoteMark??'') + frontendThemeFolder + pathResolved + endString; | ||
} else if (options.devMode) { | ||
logger.log("No rewrite for '", match, "' as the file was not found."); | ||
} | ||
return match; | ||
}); | ||
return source; | ||
} | ||
|
||
module.exports = { rewriteCssUrls }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
flow-tests/test-custom-frontend-directory/test-themes-custom-frontend-directory/pom-vite.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>test-custom-frontend-directory</artifactId> | ||
<version>23.2-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>flow-test-themes-custom-frontend-directory-vite</artifactId> | ||
<name>Flow themes tests in Vite with custom frontend directory</name> | ||
<packaging>war</packaging> | ||
<properties> | ||
<maven.deploy.skip>true</maven.deploy.skip> | ||
<vaadin.devmode.liveReload.enabled>true</vaadin.devmode.liveReload.enabled> | ||
<vaadin.pnpm.enable>false</vaadin.pnpm.enable> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>flow-test-common</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>flow-html-components-testbench</artifactId> | ||
<version>${project.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>vaadin-dev-server</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>flow-test-lumo</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<resources> | ||
<resource> | ||
<directory>${project.basedir}/src/main/vite-resources</directory> | ||
</resource> | ||
</resources> | ||
<testSourceDirectory>${project.basedir}/src/test-vite/java</testSourceDirectory> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.eclipse.jetty</groupId> | ||
<artifactId>jetty-maven-plugin</artifactId> | ||
</plugin> | ||
<plugin> | ||
<groupId>com.vaadin</groupId> | ||
<artifactId>flow-maven-plugin</artifactId> | ||
<configuration> | ||
<frontendDirectory>${project.basedir}/side-src/main/frontend</frontendDirectory> | ||
<productionMode>false</productionMode> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>ensure-fronted-deleted</id> | ||
<goals> | ||
<goal>clean-frontend</goal> | ||
</goals> | ||
<phase>initialize</phase> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-clean-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>ensure-fronted-deleted</id> | ||
<goals> | ||
<goal>clean</goal> | ||
</goals> | ||
<phase>initialize</phase> | ||
<configuration> | ||
<directory>${project.basedir}/frontend</directory> | ||
<failOnError>false</failOnError> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
1 change: 1 addition & 0 deletions
1
...t-themes-custom-frontend-directory/src/main/vite-resources/vaadin-featureflags.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
com.vaadin.experimental.viteForFrontendBuild=true |
Oops, something went wrong.