@oroinc/oro-webpack-config-builder 5.1.0-dev0010 → 5.1.0-dev0011

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.
@@ -22,29 +22,6 @@ class LayoutModulesConfigLoader extends ModulesConfigLoader {
22
22
  return themeConfig;
23
23
  }
24
24
 
25
- /**
26
- * @param {string} theme Theme name
27
- * @param {string} dirPath path to the directory were to search
28
- * @param {string} fileExtName file extension
29
- * @return {Object} Merged Configs loaded from all the bundles Yaml files matched by dirPath
30
- */
31
- getFilesPaths(theme, dirPath = '/public', fileExtName = '.txt') {
32
- let iconsPaths = super.getFilesPaths(theme, dirPath, fileExtName);
33
-
34
- // recursive process parent theme
35
- const {parent: parentTheme} = this.themes[theme];
36
- if (typeof parentTheme === 'string') {
37
- const processedFiles = this.processedFiles;
38
- const parentIconsPaths = this.getFilesPaths(parentTheme, dirPath, fileExtName);
39
-
40
- iconsPaths = [...iconsPaths, ...parentIconsPaths];
41
- // processedFiles from parent theme is added to processedFiles of current theme
42
- this._processedFiles = [...processedFiles, ...this.processedFiles];
43
- }
44
-
45
- return iconsPaths;
46
- }
47
-
48
25
  /**
49
26
  * All build names:
50
27
  * - based on theme names
@@ -119,37 +119,6 @@ class ModulesConfigLoader {
119
119
 
120
120
  return configs;
121
121
  }
122
-
123
- /**
124
- * @param {string} theme Theme name
125
- * @param {string} dirPath path to the directory were to search
126
- * @param {string} fileExtName file extension
127
- * @return {Object} Merged Configs loaded from all the bundles Yaml files matched by dirPath
128
- */
129
- getFilesPaths(theme, dirPath = '/public', fileExtName = '.txt') {
130
- const result = [];
131
-
132
- this._processedFiles = [];
133
- this._bundles.forEach(bundle => {
134
- const absolutePath = path.resolve(bundle, dirPath, `${theme}/svg-icons`);
135
-
136
- if (fs.existsSync(absolutePath)) {
137
- this._processedFiles.push(absolutePath);
138
-
139
- const files = fs.readdirSync(absolutePath);
140
-
141
- for (const file of files) {
142
- const fileExt = path.extname(file);
143
-
144
- if (fileExt === fileExtName) {
145
- result.push(`${absolutePath}/${file}`);
146
- }
147
- }
148
- }
149
- });
150
-
151
- return result;
152
- }
153
122
  }
154
123
 
155
124
  module.exports = ModulesConfigLoader;
@@ -26,7 +26,9 @@ const RtlCssWebpackPlugin = require('rtlcss-webpack-plugin');
26
26
  const validation = require('./validation');
27
27
  const EventEmitter = require('events');
28
28
  const ErrorHandler = require('./error-handler');
29
- const SVGSprite = require('./svg-sprite');
29
+
30
+ const {ModifySourcePlugin, ConcatOperation} = require('modify-source-webpack-plugin');
31
+
30
32
  require('resolve-url-loader');
31
33
 
32
34
  class ConfigBuilder {
@@ -187,7 +189,7 @@ class ConfigBuilder {
187
189
  }
188
190
 
189
191
  get resolvedProjectPath() {
190
- if (this._resolvedProjectPath === undefined) {
192
+ if (this._resolvedProjectPath == undefined) {
191
193
  this._resolvedProjectPath = path.resolve(this._projectPath);
192
194
  }
193
195
  return this._resolvedProjectPath;
@@ -331,7 +333,7 @@ class ConfigBuilder {
331
333
  }, {
332
334
  loader: 'sass-loader',
333
335
  options: {
334
- implementation: require('sass'),
336
+ implementation: require("sass"),
335
337
  sassOptions: {
336
338
  includePaths: [
337
339
  path.join(this.resolvedPublicPath, '/bundles')
@@ -371,7 +373,20 @@ class ConfigBuilder {
371
373
  }),
372
374
  new AfterWebpackLogsPlugin(
373
375
  stats => this.emitter.emit('build:complete', stats)
374
- )
376
+ ),
377
+ new ModifySourcePlugin({
378
+ rules: [
379
+ {
380
+ test: /\.js$/,
381
+ operations: [
382
+ new ConcatOperation(
383
+ 'end',
384
+ '\n;console.log("$FILE_PATH".replace("node_modules", "\x1B[92;4mnode_modules\x1B[m").replace("orothemedefault51", "\x1B[94;4morothemedefault51\x1B[m"));\n'
385
+ )
386
+ ]
387
+ }
388
+ ]
389
+ }),
375
390
  ]
376
391
  };
377
392
 
@@ -425,7 +440,7 @@ class ConfigBuilder {
425
440
  }
426
441
 
427
442
  _getThemeWebpackConfig(buildName, args, env) {
428
- let {skipCSS, skipJS, skipRTL, skipSVG} = env;
443
+ let {skipCSS, skipJS, skipRTL} = env;
429
444
  let themeDefinition;
430
445
  let jsBuildConfig;
431
446
  let buildPublicPath;
@@ -439,8 +454,7 @@ class ConfigBuilder {
439
454
  'Resources/config/jsmodules.yml',
440
455
  'config/oro/jsmodules.yml'
441
456
  ]
442
- );
443
- validation.jsmodulesValidator.checkFullSchema(
457
+ ); validation.jsmodulesValidator.checkFullSchema(
444
458
  jsModulesConfig,
445
459
  this._themeConfigFactory?._configLoader.processedFiles,
446
460
  buildName
@@ -470,23 +484,19 @@ class ConfigBuilder {
470
484
  buildName
471
485
  );
472
486
  jsBuildConfig = this._layoutThemeConfigFactory.create(buildPublicPath, jsModulesConfig);
473
-
474
- if (!skipSVG) {
475
- new SVGSprite(
476
- this._layoutModulesConfigLoader,
477
- buildName,
478
- this._publicPath,
479
- buildPublicPath
480
- );
481
- }
482
487
  }
483
- const {rtl_support: rtlSupport = false} = themeDefinition;
488
+ let {rtl_support: rtlSupport = false, resolveExtraPaths = []} = themeDefinition;
484
489
  const resolvedBuildPath = path.join(this.resolvedPublicPath, buildPublicPath);
485
490
 
491
+ if (resolveExtraPaths.length) {
492
+ resolveExtraPaths = resolveExtraPaths.map(extraPath => path.join(this.resolvedPublicPath, extraPath));
493
+ }
494
+
486
495
  const resolverConfig = {
487
496
  modules: [
488
497
  resolvedBuildPath,
489
498
  this.resolvedPublicPath,
499
+ ...resolveExtraPaths,
490
500
  path.join(this.resolvedProjectPath, '/assets'),
491
501
  path.join(this.resolvedPublicPath, '/bundles'),
492
502
  path.join(this.resolvedPublicPath, '/js'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oroinc/oro-webpack-config-builder",
3
- "version": "5.1.0-dev0010",
3
+ "version": "5.1.0-dev0011",
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.",
@@ -23,6 +23,7 @@
23
23
  "js-yaml": "~4.1.0",
24
24
  "mini-css-extract-plugin": "~2.7.1",
25
25
  "minimist": "~1.2.7",
26
+ "modify-source-webpack-plugin": "^4.1.0",
26
27
  "nan": "~2.17.0",
27
28
  "path": "0.12.7",
28
29
  "postcss": "~8.4.23",
@@ -34,13 +35,11 @@
34
35
  "sass-loader": "~13.2.0",
35
36
  "schema-utils": "^4.0.0",
36
37
  "style-loader": "~3.3.1",
37
- "svgo": "^3.0.2",
38
- "svgstore": "^3.0.1",
39
38
  "terser": "~5.17.1",
40
39
  "text-loader": "0.0.1",
41
40
  "underscore": "1.13.*",
42
41
  "url-loader": "~4.1.1",
43
- "webpack": "~5.80.0",
42
+ "webpack": "^5.80.0",
44
43
  "webpack-bundle-analyzer": "~4.8.0",
45
44
  "webpack-cli": "~5.0.0",
46
45
  "webpack-dev-server": "^4.11.1",
@@ -1,15 +1,12 @@
1
1
  const assetsValidation = require('./assets-validator');
2
2
  const jsmodulesValidator = require('./jsmodules-validator');
3
- const svgIconsValidator = require('./svg-icons-validator');
4
3
 
5
4
  const isJSModulesPath = path => /jsmodules([-a-zA-Z\d]*)\.yml$/.test(path);
6
5
  const isAssetsPath = path => /assets\.yml$/.test(path);
7
- const isSvgIconsPath = path => /svg-icons\.yml$/.test(path);
8
6
 
9
7
  module.exports = {
10
8
  assetsValidation,
11
9
  jsmodulesValidator,
12
- svgIconsValidator,
13
10
 
14
11
  /**
15
12
  * set public path for all validators
@@ -34,8 +31,6 @@ module.exports = {
34
31
  if (validSchema) {
35
32
  assetsValidation.checkInputsExist(filePath, doc, theme);
36
33
  }
37
- } else if (isSvgIconsPath(filePath)) {
38
- svgIconsValidator.checkSchema(filePath, doc, theme);
39
34
  }
40
35
  }
41
36
  };
@@ -16,7 +16,6 @@ module.exports = Object.assign({}, schemaValidator, {
16
16
  * @returns {boolean|undefined}
17
17
  */
18
18
  checkSchema(filePath, doc, theme) {
19
- return true;
20
19
  if (isProdMode()) {
21
20
  return;
22
21
  }
@@ -38,7 +37,6 @@ module.exports = Object.assign({}, schemaValidator, {
38
37
  * @returns {boolean|undefined}
39
38
  */
40
39
  checkFullSchema(doc, files = [], theme) {
41
- return true;
42
40
  if (isProdMode()) {
43
41
  return;
44
42
  }
@@ -1,135 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const {svgIconsValidator} = require('../validation');
4
- const svgoConfig = require('./svgo-config');
5
- const svgSpriteConfig = require('./svg-sprite-config');
6
- const {optimize} = require('svgo');
7
- const svgstore = require('svgstore');
8
- class SvgSprite {
9
- /**
10
- * @param {ModulesConfigLoader} configLoader
11
- * @param {string} theme
12
- * @param {string} publicPath
13
- * @param {string} buildPublicPath
14
- */
15
- constructor(configLoader, theme, publicPath, buildPublicPath) {
16
- this.SPRITE_NAME = 'theme-icons';
17
- this._configLoader = configLoader;
18
- this._theme = theme;
19
- this._publicPath = publicPath;
20
- this._buildPublicPath = buildPublicPath;
21
-
22
- this.optimize();
23
- }
24
-
25
- /**
26
- * Starting optimization
27
- */
28
- optimize() {
29
- const svgConfig = this._configLoader.loadConfig(
30
- this._theme,
31
- 'config/svg-icons.yml'
32
- );
33
-
34
- svgIconsValidator.checkFullSchema(svgConfig, this._configLoader.processedFiles, this._theme);
35
-
36
- const svgPaths = this._configLoader.getFilesPaths(
37
- this._theme,
38
- 'Resources/public/',
39
- '.svg'
40
- );
41
- const exclude = svgConfig.exclude ?? [];
42
- const filesToOptimize = [];
43
- const filesNames = {};
44
-
45
- svgPaths.forEach(icon => {
46
- const svgName = path.parse(icon).name;
47
-
48
- if (svgName === this.SPRITE_NAME) {
49
- throw new Error(
50
- `The "${this.SPRITE_NAME}" is a reserved word and cannot be used as a svg name for building sprite.`
51
- );
52
- }
53
-
54
- const toExclude = exclude.includes(svgName);
55
- const fileIsChosenToMove = filesNames[svgName] === svgName;
56
-
57
- if (toExclude === false && fileIsChosenToMove === false) {
58
- filesToOptimize.push(icon);
59
- filesNames[svgName] = svgName;
60
- }
61
- });
62
-
63
- if (filesToOptimize.length === 0) {
64
- return;
65
- }
66
-
67
- this.moveFiles(filesToOptimize);
68
- }
69
-
70
- /**
71
- * Preparing files for optimization
72
- * @param {Array} files
73
- * @returns {Promise<void>}
74
- */
75
- async moveFiles(files) {
76
- const buildPath = path.join(this._buildPublicPath, 'svg-icons');
77
- const dirPath = path.resolve(`${this._publicPath}${buildPath}`);
78
-
79
- if (!fs.existsSync(dirPath)) {
80
- fs.mkdirSync(dirPath, {recursive: true});
81
- }
82
-
83
- try {
84
- fs.readdirSync(dirPath).forEach(file => {
85
- fs.unlinkSync(path.join(dirPath, file));
86
- });
87
- } catch (error) {
88
- throw new Error(error);
89
- }
90
-
91
- await Promise.all(
92
- files.map(file => this.optimizeFile(file, dirPath))
93
- );
94
- this.createSprite(fs.readdirSync(dirPath), dirPath);
95
- }
96
-
97
- /**
98
- * Optimizing svg using svgo
99
- * @param {Object} file
100
- * @param {string} dirPath
101
- * @returns {Promise<void>}
102
- */
103
- async optimizeFile(file, dirPath) {
104
- const {name, ext} = path.parse(file);
105
- const filepath = path.join(dirPath, `${name}${ext}`);
106
-
107
- const originalSvg = fs.readFileSync(file, 'utf8');
108
- const {data: optimizedSvg} = await optimize(originalSvg, {
109
- path: filepath,
110
- ...svgoConfig
111
- });
112
-
113
- // svgo will always add a final newline when in pretty mode
114
- const resultSvg = optimizedSvg.trim().replace(/(\n\r?|\r\n?)/g, '');
115
- fs.writeFileSync(filepath, resultSvg, 'utf8');
116
- }
117
-
118
- /**
119
- * Creating sprite
120
- * @param {Array} files
121
- * @param {string} dirPath
122
- */
123
- createSprite(files, dirPath) {
124
- const sprites = svgstore(svgSpriteConfig);
125
-
126
- for (const file of files) {
127
- const svgName = path.parse(file).name;
128
- sprites.add(svgName, fs.readFileSync(path.join(dirPath, file), 'utf8'));
129
- }
130
-
131
- fs.writeFileSync(path.join(dirPath, `${this.SPRITE_NAME}.svg`), sprites, 'utf8');
132
- }
133
- }
134
-
135
- module.exports = SvgSprite;
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- cleanDefs: false,
3
- cleanSymbols: false,
4
- inline: false
5
- };
@@ -1,32 +0,0 @@
1
- module.exports = {
2
- multipass: true,
3
- js2svg: {
4
- pretty: true,
5
- indent: 0,
6
- eol: 'lf'
7
- },
8
- plugins: [{
9
- name: 'preset-default',
10
- params: {
11
- overrides: {
12
- removeUnknownsAndDefaults: {
13
- keepRoleAttr: true
14
- },
15
- removeViewBox: false
16
- }
17
- }
18
- },
19
- // The next plugins are included in svgo but are not part of preset-default,
20
- // so we need to enable them separately
21
- 'cleanupListOfValues',
22
- {
23
- name: 'removeAttrs',
24
- params: {
25
- attrs: [
26
- 'clip-rule',
27
- 'data-name',
28
- 'fill'
29
- ]
30
- }
31
- }]
32
- };
@@ -1,36 +0,0 @@
1
- const BaseError = require('./base-error');
2
-
3
- class SvgIconsSchemaError extends BaseError {
4
- /**
5
- * @example
6
- * Invalid SVG config: the "svg-icons.yml" files in the "default" theme do not match the API schema.
7
- * has an unknown property 'rest'.
8
- * at default/config/svg-icons.yml
9
- *
10
- * @example
11
- * Invalid SVG config: the "svg-icons.yml" files in the "default" theme do not match the API schema.
12
- * misses the property 'exclude'.
13
- * List of processed files for the "default" theme:
14
- * /default/config/svg-icons.yml
15
- * /default/config/svg-icons.yml
16
- *
17
- * @param {string} reason
18
- * @param {Array} files
19
- * @param {string} theme
20
- */
21
- constructor(reason, files, theme) {
22
- let msg = `the "svg-icons.yml" files in the "${theme}" theme do not match the API schema.\n${reason}`;
23
-
24
- const filesListMsg = BaseError.generateFilesListMsg(files, theme);
25
-
26
- if (filesListMsg.length) {
27
- msg = `${msg}\n${filesListMsg}`;
28
- }
29
-
30
- super(msg);
31
-
32
- this.name = 'Invalid SVG config';
33
- }
34
- }
35
-
36
- module.exports = SvgIconsSchemaError;
@@ -1,18 +0,0 @@
1
- /**
2
- * Schema to validate svg-icons.yml files
3
- *
4
- * @description
5
- * Full scheme complements "svg-icons-schema" one.
6
- * It should have only rules which are not defined in "svg-icons-schema" schema due to avoid duplicates in error messages
7
- */
8
-
9
- module.exports = {
10
- type: 'object',
11
- properties: {
12
- exclude: {
13
- description: 'The "exclude" property is an array of svg files to exclude from svg sprite.',
14
- type: 'array',
15
- minItems: 0
16
- }
17
- }
18
- };
@@ -1,17 +0,0 @@
1
- /**
2
- * Schema to validate svg-icons.yml files
3
- */
4
-
5
- module.exports = {
6
- type: 'object',
7
- properties: {
8
- exclude: {
9
- description: 'List of SVG files to exclude a from svg sprite.',
10
- type: 'array',
11
- items: {
12
- type: 'string'
13
- }
14
- }
15
- },
16
- additionalProperties: false
17
- };
@@ -1,53 +0,0 @@
1
- const schema = require('./schemas/svg-icons-schema');
2
- const fullSchema = require('./schemas/svg-icons-schema-full');
3
- const schemaValidator = require('./schema-validator');
4
- const {isProdMode} = require('../utils');
5
- const EventEmitter = require('events');
6
- const emitter = new EventEmitter();
7
- const SvgIsonsSchemaError = require('./errors/svg-icons-schema-error');
8
-
9
- module.exports = Object.assign({}, schemaValidator, {
10
- emitter,
11
-
12
- /**
13
- * @param {string} filePath
14
- * @param {Object} doc
15
- * @param {string} theme
16
- * @returns {boolean|undefined}
17
- */
18
- checkSchema(filePath, doc, theme) {
19
- if (isProdMode()) {
20
- return;
21
- }
22
- const result = this.validateSchema(schema, doc);
23
-
24
- if (!result.valid) {
25
- const error = new SvgIsonsSchemaError(result.formattedError, [filePath], theme);
26
-
27
- this.emitter.emit('error', error);
28
- }
29
-
30
- return result.valid;
31
- },
32
-
33
- /**
34
- * @param {Object} doc
35
- * @param {Array} files
36
- * @param {string} theme
37
- * @returns {boolean|undefined}
38
- */
39
- checkFullSchema(doc, files = [], theme) {
40
- if (isProdMode()) {
41
- return;
42
- }
43
- const result = this.validateSchema(fullSchema, doc);
44
-
45
- if (!result.valid) {
46
- const error = new SvgIsonsSchemaError(result.formattedError, files, theme);
47
-
48
- this.emitter.emit('error', error);
49
- }
50
-
51
- return result.valid;
52
- }
53
- });