@oroinc/oro-webpack-config-builder 6.0.0-dev001 → 6.0.0-lts01
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.
|
@@ -28,7 +28,7 @@ class LayoutModulesConfigLoader extends ModulesConfigLoader {
|
|
|
28
28
|
* @param {string} fileExtName file extension
|
|
29
29
|
* @return {Object} Merged Configs loaded from all the bundles Yaml files matched by dirPath
|
|
30
30
|
*/
|
|
31
|
-
getFilesPaths(theme, dirPath = '/public', fileExtName = '.
|
|
31
|
+
getFilesPaths(theme, dirPath = '/public', fileExtName = '.svg') {
|
|
32
32
|
let iconsPaths = super.getFilesPaths(theme, dirPath, fileExtName);
|
|
33
33
|
|
|
34
34
|
// recursive process parent theme
|
|
@@ -40,9 +40,14 @@ class ModulesConfigLoader {
|
|
|
40
40
|
* @param {Array} bundles Array of ordered symfony bundle paths
|
|
41
41
|
* @param {string|Array} themesLocation Path inside the bundle, where to find the theme
|
|
42
42
|
* @param {string} themeInfoFileName Yaml File name with theme info
|
|
43
|
+
* @param {string} projectPublicPath Symfony public directory path related to application root folder
|
|
44
|
+
* @param {string} publicPath Symfony public directory path related to application root folder
|
|
43
45
|
*/
|
|
44
|
-
constructor(bundles, themesLocation, themeInfoFileName) {
|
|
46
|
+
constructor(bundles, themesLocation, themeInfoFileName, projectPublicPath, publicPath) {
|
|
45
47
|
this._bundles = bundles;
|
|
48
|
+
this._projectPublicPath = projectPublicPath;
|
|
49
|
+
this._publicPath = publicPath;
|
|
50
|
+
|
|
46
51
|
if (!Array.isArray(themesLocation)) {
|
|
47
52
|
themesLocation = [themesLocation];
|
|
48
53
|
}
|
|
@@ -126,25 +131,57 @@ class ModulesConfigLoader {
|
|
|
126
131
|
* @param {string} fileExtName file extension
|
|
127
132
|
* @return {Object} Merged Configs loaded from all the bundles Yaml files matched by dirPath
|
|
128
133
|
*/
|
|
129
|
-
getFilesPaths(theme, dirPath = '/public', fileExtName = '.
|
|
130
|
-
const result = [];
|
|
131
|
-
|
|
134
|
+
getFilesPaths(theme, dirPath = '/public', fileExtName = '.svg') {
|
|
132
135
|
this._processedFiles = [];
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
const iconsFolder = 'svg-icons';
|
|
137
|
+
const {resolve_extra_paths: resolveExtraPaths = []} = this.themes[theme];
|
|
138
|
+
const logProcessedFile = pathToFile => this._processedFiles.push(pathToFile);
|
|
139
|
+
const collectIcons = pathToFile => {
|
|
140
|
+
const icons = [];
|
|
141
|
+
const files = fs.readdirSync(pathToFile);
|
|
142
|
+
|
|
143
|
+
for (const file of files) {
|
|
144
|
+
const fileExt = path.extname(file);
|
|
145
|
+
|
|
146
|
+
if (fileExt === fileExtName) {
|
|
147
|
+
icons.push(`${pathToFile}/${file}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
135
150
|
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
return icons;
|
|
152
|
+
};
|
|
153
|
+
const result = [];
|
|
138
154
|
|
|
139
|
-
|
|
155
|
+
if (resolveExtraPaths.length) {
|
|
156
|
+
resolveExtraPaths.map(
|
|
157
|
+
extraPath => path.join(this._projectPublicPath, this._publicPath, extraPath)
|
|
158
|
+
).forEach(extraPath => {
|
|
159
|
+
const findIcons = extraPath => {
|
|
160
|
+
const files = fs.readdirSync(extraPath);
|
|
161
|
+
|
|
162
|
+
for (const file of files) {
|
|
163
|
+
const innerFolder = path.join(extraPath, file);
|
|
164
|
+
|
|
165
|
+
if (fs.statSync(innerFolder).isDirectory()) {
|
|
166
|
+
if (file === iconsFolder) {
|
|
167
|
+
logProcessedFile(innerFolder);
|
|
168
|
+
result.push(...collectIcons(innerFolder));
|
|
169
|
+
} else {
|
|
170
|
+
findIcons(innerFolder);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
findIcons(extraPath);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
140
178
|
|
|
141
|
-
|
|
142
|
-
|
|
179
|
+
this._bundles.forEach(bundle => {
|
|
180
|
+
const absolutePath = path.resolve(bundle, dirPath, `${theme}/${iconsFolder}`);
|
|
143
181
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
182
|
+
if (fs.existsSync(absolutePath)) {
|
|
183
|
+
logProcessedFile(absolutePath);
|
|
184
|
+
result.push(...collectIcons(absolutePath));
|
|
148
185
|
}
|
|
149
186
|
});
|
|
150
187
|
|
package/oro-webpack-config.js
CHANGED
|
@@ -28,6 +28,7 @@ const EventEmitter = require('events');
|
|
|
28
28
|
const ErrorHandler = require('./error-handler');
|
|
29
29
|
const SVGSprite = require('./svg-sprite');
|
|
30
30
|
require('resolve-url-loader');
|
|
31
|
+
require('lezer-loader');
|
|
31
32
|
|
|
32
33
|
class ConfigBuilder {
|
|
33
34
|
constructor() {
|
|
@@ -355,7 +356,7 @@ class ConfigBuilder {
|
|
|
355
356
|
},
|
|
356
357
|
{
|
|
357
358
|
test: /\.grammar$/,
|
|
358
|
-
use: 'lezer-loader'
|
|
359
|
+
use: 'lezer-loader'
|
|
359
360
|
}
|
|
360
361
|
]
|
|
361
362
|
},
|
|
@@ -566,7 +567,9 @@ class ConfigBuilder {
|
|
|
566
567
|
this._modulesConfigLoader = new ModulesConfigLoader(
|
|
567
568
|
this._appConfig.paths,
|
|
568
569
|
['/Resources/public/themes/', '/public/themes/admin/'],
|
|
569
|
-
'settings.yml'
|
|
570
|
+
'settings.yml',
|
|
571
|
+
this.resolvedProjectPath,
|
|
572
|
+
this._publicPath
|
|
570
573
|
);
|
|
571
574
|
this._adminThemes = this._modulesConfigLoader.themeNames.map(themeName => 'admin.' + themeName);
|
|
572
575
|
this._adminStyleLoader = new AdminStyleLoader(this._modulesConfigLoader, entryPointFileWriter);
|
|
@@ -580,7 +583,9 @@ class ConfigBuilder {
|
|
|
580
583
|
this._layoutModulesConfigLoader = new LayoutModulesConfigLoader(
|
|
581
584
|
this._appConfig.paths,
|
|
582
585
|
['/Resources/views/layouts/', '/templates/layouts/'],
|
|
583
|
-
'theme.yml'
|
|
586
|
+
'theme.yml',
|
|
587
|
+
this.resolvedProjectPath,
|
|
588
|
+
this._publicPath
|
|
584
589
|
);
|
|
585
590
|
this._layoutStyleLoader = new LayoutStyleLoader(this._layoutModulesConfigLoader, entryPointFileWriter);
|
|
586
591
|
this._layoutThemeConfigFactory = new ThemeConfigFactory(
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oroinc/oro-webpack-config-builder",
|
|
3
|
-
"version": "6.0.0-
|
|
3
|
+
"version": "6.0.0-lts01",
|
|
4
4
|
"author": "Oro, Inc (https://www.oroinc.com)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "An integration of OroPlatform based applications with the Webpack.",
|
|
7
7
|
"main": "oro-webpack-config.js",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@babel/core": "~7.
|
|
9
|
+
"@babel/core": "~7.23.3",
|
|
10
10
|
"@babel/plugin-transform-runtime": "~7.21.0",
|
|
11
11
|
"@babel/preset-env": "~7.21.2",
|
|
12
12
|
"autoprefixer": "~10.4.13",
|
|
13
13
|
"babel-loader": "~9.1.0",
|
|
14
14
|
"bindings": "~1.5.0",
|
|
15
|
-
"css-loader": "^6.
|
|
15
|
+
"css-loader": "^6.8.1",
|
|
16
16
|
"css-minimizer-webpack-plugin": "~5.0.0",
|
|
17
17
|
"deepmerge": "~4.3.1",
|
|
18
18
|
"exports-loader": "~4.0.0",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"minimist": "~1.2.7",
|
|
27
27
|
"nan": "~2.17.0",
|
|
28
28
|
"path": "0.12.7",
|
|
29
|
-
"postcss": "
|
|
30
|
-
"postcss-loader": "~7.
|
|
29
|
+
"postcss": "<8.4.33",
|
|
30
|
+
"postcss-loader": "~7.3.4",
|
|
31
31
|
"printf": "~0.6.0",
|
|
32
32
|
"resolve-url-loader": "^5.0.0",
|
|
33
33
|
"rtlcss-webpack-plugin": "~4.0.6",
|
package/svg-sprite/index.js
CHANGED
|
@@ -14,6 +14,7 @@ class SvgSprite {
|
|
|
14
14
|
*/
|
|
15
15
|
constructor(configLoader, theme, publicPath, buildPublicPath) {
|
|
16
16
|
this.SPRITE_NAME = 'theme-icons';
|
|
17
|
+
this.SPRITE_NAME_RTL = `${this.SPRITE_NAME}.rtl`;
|
|
17
18
|
this._configLoader = configLoader;
|
|
18
19
|
this._theme = theme;
|
|
19
20
|
this._publicPath = publicPath;
|
|
@@ -22,6 +23,18 @@ class SvgSprite {
|
|
|
22
23
|
this.optimize();
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Gets theme configuration's settings
|
|
28
|
+
* @returns {*}
|
|
29
|
+
*/
|
|
30
|
+
get themeConfig() {
|
|
31
|
+
if (!this._theme) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return this._configLoader._themes[this._theme];
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/**
|
|
26
39
|
* Starting optimization
|
|
27
40
|
*/
|
|
@@ -45,9 +58,10 @@ class SvgSprite {
|
|
|
45
58
|
svgPaths.forEach(icon => {
|
|
46
59
|
const svgName = path.parse(icon).name;
|
|
47
60
|
|
|
48
|
-
if (svgName === this.SPRITE_NAME) {
|
|
61
|
+
if (svgName === this.SPRITE_NAME || svgName === this.SPRITE_NAME_RTL) {
|
|
49
62
|
throw new Error(
|
|
50
|
-
`The "${this.SPRITE_NAME}"
|
|
63
|
+
`The "${this.SPRITE_NAME}" and "${this.SPRITE_NAME_RTL}" are a reserved words and
|
|
64
|
+
cannot be used as a svg name for building sprite.`
|
|
51
65
|
);
|
|
52
66
|
}
|
|
53
67
|
|
|
@@ -91,9 +105,71 @@ class SvgSprite {
|
|
|
91
105
|
await Promise.all(
|
|
92
106
|
files.map(file => this.optimizeFile(file, dirPath))
|
|
93
107
|
);
|
|
94
|
-
|
|
108
|
+
|
|
109
|
+
const {filesList, rtlFilesList} = this.createSpriteMap(fs.readdirSync(dirPath));
|
|
110
|
+
this.createSprite(filesList, dirPath, `${this.SPRITE_NAME}.svg`);
|
|
111
|
+
|
|
112
|
+
if (rtlFilesList) {
|
|
113
|
+
this.createSprite(rtlFilesList, dirPath, `${this.SPRITE_NAME_RTL}.svg`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.createMetadata(fs.readdirSync(dirPath), dirPath);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {Array} files
|
|
121
|
+
@returns {{ filesList: {}, rtlFilesList: {}|undefined }}
|
|
122
|
+
*/
|
|
123
|
+
createSpriteMap(files) {
|
|
124
|
+
const SVGFiles = files.filter(file => path.extname(file) === '.svg');
|
|
125
|
+
const {rtl_support: rtl} = this.themeConfig;
|
|
126
|
+
const result = {
|
|
127
|
+
filesList: SVGFiles.reduce((list, file) => {
|
|
128
|
+
list[file] = path.parse(file).name;
|
|
129
|
+
return list;
|
|
130
|
+
}, {})
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
if (!rtl) {
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const LTR_TO_RTL = [
|
|
138
|
+
['left', 'right'],
|
|
139
|
+
['right', 'left'],
|
|
140
|
+
['start', 'end'],
|
|
141
|
+
['end', 'start']
|
|
142
|
+
];
|
|
143
|
+
const rtlFiles = {...result.filesList};
|
|
144
|
+
const rtlRegexp = /-(?:left|right|start|end)\.svg$/;
|
|
145
|
+
const pairedFiles = Object.entries(rtlFiles).filter(([key])=> rtlRegexp.test(key));
|
|
146
|
+
const swappedFiles = pairedFiles.map(rtlFile => {
|
|
147
|
+
const file = rtlFile[1];
|
|
148
|
+
const pair = LTR_TO_RTL.find(pair => file.endsWith(pair[0]));
|
|
149
|
+
|
|
150
|
+
if (!pair) {
|
|
151
|
+
return rtlFile;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const RTLFileName = `${file.substring(0, file.length - pair[0].length)}${pair[1]}`;
|
|
155
|
+
const RTLPairFile = pairedFiles.find(rtlFile => rtlFile[1] === RTLFileName);
|
|
156
|
+
|
|
157
|
+
if (RTLPairFile) {
|
|
158
|
+
return [
|
|
159
|
+
rtlFile[0],
|
|
160
|
+
RTLPairFile[1]
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return rtlFile;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
result.rtlFilesList = Object.assign(rtlFiles, Object.fromEntries(swappedFiles));
|
|
168
|
+
|
|
169
|
+
return result;
|
|
95
170
|
}
|
|
96
171
|
|
|
172
|
+
|
|
97
173
|
/**
|
|
98
174
|
* Optimizing svg using svgo
|
|
99
175
|
* @param {Object} file
|
|
@@ -117,18 +193,34 @@ class SvgSprite {
|
|
|
117
193
|
|
|
118
194
|
/**
|
|
119
195
|
* Creating sprite
|
|
120
|
-
* @param {
|
|
196
|
+
* @param {Object} files
|
|
121
197
|
* @param {string} dirPath
|
|
198
|
+
* @param {string} spriteName
|
|
122
199
|
*/
|
|
123
|
-
createSprite(files, dirPath) {
|
|
200
|
+
createSprite(files, dirPath, spriteName) {
|
|
124
201
|
const sprites = svgstore(svgSpriteConfig);
|
|
202
|
+
for (const [fullFileName, file] of Object.entries(files)) {
|
|
203
|
+
sprites.add(file, fs.readFileSync(path.join(dirPath, fullFileName), 'utf8'));
|
|
204
|
+
}
|
|
205
|
+
fs.writeFileSync(path.join(dirPath, spriteName), sprites.toString(), 'utf8');
|
|
206
|
+
}
|
|
125
207
|
|
|
126
|
-
|
|
208
|
+
/**
|
|
209
|
+
* @param {Array<string>} files
|
|
210
|
+
* @param {string} dirPath
|
|
211
|
+
*/
|
|
212
|
+
createMetadata(files, dirPath) {
|
|
213
|
+
const SVGFiles = files.filter(file => path.extname(file) === '.svg');
|
|
214
|
+
const svgList = SVGFiles.reduce((acc, file) => {
|
|
127
215
|
const svgName = path.parse(file).name;
|
|
128
|
-
|
|
129
|
-
}
|
|
216
|
+
acc[svgName] = file;
|
|
130
217
|
|
|
131
|
-
|
|
218
|
+
return acc;
|
|
219
|
+
}, {});
|
|
220
|
+
|
|
221
|
+
fs.writeFileSync(
|
|
222
|
+
path.join(dirPath, 'icons-metadata.json'), JSON.stringify({icons: svgList}, null, null)
|
|
223
|
+
);
|
|
132
224
|
}
|
|
133
225
|
}
|
|
134
226
|
|