-
Notifications
You must be signed in to change notification settings - Fork 191
/
webpack.dspublisher.js
141 lines (112 loc) · 5.43 KB
/
webpack.dspublisher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import path from 'path';
import fs from 'fs';
import url from 'url';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const buildDirectory = path.resolve(__dirname, 'target');
const settingsPath = path.resolve(buildDirectory, 'vaadin-dev-server-settings.json');
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
const frontendFolder = path.resolve(__dirname, settings.frontendFolder);
// Folders in the project which can contain static assets.
const projectStaticAssetsFolders = [
path.resolve(__dirname, 'src', 'main', 'resources', 'META-INF', 'resources'),
path.resolve(__dirname, 'src', 'main', 'resources', 'static'),
frontendFolder,
];
const projectStaticAssetsOutputFolder = path.resolve(__dirname, settings.staticOutput);
// Folders in the project which can contain application themes
const themeProjectFolders = projectStaticAssetsFolders.map(folder =>
path.resolve(folder, settings.themeFolder)
);
const frontendGeneratedFolder = path.resolve(frontendFolder, settings.generatedFolder);
const jarResourcesFolder = path.resolve(__dirname, settings.jarResourcesFolder);
const themeResourceFolder = path.resolve(__dirname, settings.themeResourceFolder, settings.themeFolder);
const themeOptions = {
devMode: false,
// The following matches folder 'frontend/generated/jar-resources/themes/'
// (not 'frontend/themes') for theme in JAR that is copied there
themeResourceFolder,
themeProjectFolders,
projectStaticAssetsOutputFolder,
frontendGeneratedFolder,
};
// this matches css files in the theme
const themeCssRegex = /(\\|\/).*frontend(\\|\/).*themes\1[\s\S]*?\.css/;
const embeddedWcRegex = /(\\|\/).*frontend(\\|\/)generated(\\|\/)[\s\S]*-wc.js/;
const projectThemePath = path.resolve(__dirname, 'frontend/themes');
// List of all the directories under projectThemePath (frontend/themes)
const projectThemeNames = fs.readdirSync(projectThemePath);
// Content of the DemoExporter.java file (has the @Theme annotation)
const demoExporterContent = fs.readFileSync(
path.resolve(__dirname, 'src/main/java/com/vaadin/demo/DemoExporter.java'),
'utf-8'
);
// Check if one of the project themes (default = "docs") is in use
const themeLine = demoExporterContent.split('\n').find((line) => line.includes('@Theme'));
const usesProjectTheme = projectThemeNames.some((themeName) =>
themeLine.includes(`"${themeName}"`)
);
const themesPath = usesProjectTheme ? projectThemePath : themeResourceFolder;
const applyThemePath = path.resolve(frontendGeneratedFolder, 'theme.js');
export default async function (config) {
const { ApplicationThemePlugin, extractThemeName, findParentThemes } = await import(url.pathToFileURL(
buildDirectory + '/plugins/application-theme-plugin/application-theme-plugin.js').href
);
const allFlowImportsPath = path.resolve(__dirname, 'frontend/generated/flow/generated-flow-imports.js');
config.resolve.alias['all-flow-imports-or-empty'] =
process.env.DOCS_IMPORT_EXAMPLE_RESOURCES === 'true'
? allFlowImportsPath
: // false not supported in Webpack 4, let's use a resource that would get included anyway
applyThemePath;
// Create an alias for each parent theme (if any)
const themeName = extractThemeName(frontendGeneratedFolder);
const parentThemePaths = findParentThemes(themeName, themeOptions);
parentThemePaths.forEach((parentThemePath) => {
const parentThemeName = parentThemePath.split('/').pop();
config.resolve.alias[`themes/${parentThemeName}`] = parentThemePath;
});
config.resolve.alias['Frontend/generated/theme'] = applyThemePath;
config.resolve.alias.themes = themesPath;
const frontendFolder = path.resolve(__dirname, 'frontend');
config.resolve.alias['Frontend/generated/endpoints'] = path.resolve(
frontendFolder,
'demo',
'services',
'mocks.js'
);
config.resolve.alias['Frontend'] = frontendFolder;
config.plugins.push(new ApplicationThemePlugin(themeOptions));
config.resolve.alias['@vaadin/flow-frontend'] = jarResourcesFolder;
config.resolve.alias['@vaadin/hilla-react-signals'] = '@preact/signals-react';
// Temporary workaround for embedded web components, where due to a bug Flow currently generates
// theme imports from `/generated/theme`, rather than `Frontend/generated/theme.js`
config.resolve.alias['/generated/theme'] = applyThemePath;
// If there are pre-existing rules that affect CSS files,
// make them exclude files that match the themeCssRegex pattern...
config.module.rules
.filter(rule => rule.oneOf && rule.oneOf.some(r => r.test.test('style.css')))
.forEach(rule => (rule.exclude = themeCssRegex));
// ...and add a custom rule to handle the CSS files matching the themeCssRegex pattern
config.module.rules.push({
test: themeCssRegex,
use: ['raw-loader', 'extract-loader', 'css-loader']
});
// The docs-app bundle should never contain the embedded Vaadin examples
config.module.rules.push({
test: embeddedWcRegex,
use: ['null-loader']
});
// Avoid having the docs-app dev server recompile whenever the Java-sources or generated files change
config.devServer = {
watchOptions: {
ignored: [
path.resolve(__dirname, 'target'),
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'src', 'main', 'java'),
path.resolve(__dirname, 'frontend', 'generated')
]
}
};
config.resolve.extensionAlias = { '.js': ['.js', '.ts', '.tsx'] };
}