@oroinc/oro-webpack-config-builder 6.0.0-lts03 → 6.0.0-lts05

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/LICENSE CHANGED
@@ -1,8 +1,6 @@
1
- oro-webpack-config-builder
2
-
3
1
  The MIT License (MIT)
4
2
 
5
- Copyright (c) 2013, Oro, Inc.
3
+ Copyright (c) 2024 Oro Inc.
6
4
 
7
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
6
  of this software and associated documentation files (the "Software"), to deal
@@ -9,6 +9,8 @@ const EntryPointFileWriter = require('./writer/scss-entry-point-file-writer');
9
9
  const LayoutModulesConfigLoader = require('./modules-config/layout-modules-config-loader');
10
10
  const LayoutStyleLoader = require('./style/layout-style-loader');
11
11
  const MapModulesPlugin = require('./plugin/map/map-modules-plugin');
12
+ const IntegrityFilePlugin = require('./plugin/integrity/integrity-file-plugin');
13
+ const {SubresourceIntegrityPlugin} = require('webpack-subresource-integrity');
12
14
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
13
15
  const ModulesConfigLoader = require('./modules-config/modules-config-loader');
14
16
  const DynamicImportsFileWriter = require('./writer/dynamic-imports-file-writer');
@@ -27,6 +29,7 @@ const validation = require('./validation');
27
29
  const EventEmitter = require('events');
28
30
  const ErrorHandler = require('./error-handler');
29
31
  const SVGSprite = require('./svg-sprite');
32
+ const TerserPlugin = require('terser-webpack-plugin');
30
33
  require('resolve-url-loader');
31
34
  require('lezer-loader');
32
35
 
@@ -280,7 +283,8 @@ class ConfigBuilder {
280
283
  output: {
281
284
  filename: '[name].js',
282
285
  // Because we use third party libraries 'chunkFilename' should include only [name]
283
- chunkFilename: this._getVersionedPath('chunk/[name].js', this.assetVersion)
286
+ chunkFilename: this._getVersionedPath('chunk/[name].js', this.assetVersion),
287
+ crossOriginLoading: "anonymous"
284
288
  },
285
289
  devtool: !env.skipSourcemap && 'inline-cheap-module-source-map',
286
290
  mode: 'development',
@@ -290,7 +294,20 @@ class ConfigBuilder {
290
294
  cacheGroups: {
291
295
  defaultVendors: false
292
296
  }
293
- }
297
+ },
298
+ minimize: this._isProduction,
299
+ minimizer: [new TerserPlugin({
300
+ parallel: true,
301
+ extractComments: false,
302
+ minify: TerserPlugin.swcMinify,
303
+ terserOptions: {
304
+ compress: true,
305
+ mangle: true,
306
+ format: {
307
+ comments: false
308
+ }
309
+ }
310
+ })]
294
311
  },
295
312
  resolveLoader: {
296
313
  modules: [
@@ -374,6 +391,10 @@ class ConfigBuilder {
374
391
  new webpack.optimize.MinChunkSizePlugin({
375
392
  minChunkSize: 30000 // Minimum number of characters
376
393
  }),
394
+ new SubresourceIntegrityPlugin(),
395
+ new IntegrityFilePlugin({
396
+ publicPath: this.resolvedPublicPath
397
+ }),
377
398
  new AfterWebpackLogsPlugin(
378
399
  stats => this.emitter.emit('build:complete', stats)
379
400
  )
@@ -423,7 +444,10 @@ class ConfigBuilder {
423
444
  // Additional setting for production mode
424
445
  if (this._isProduction) {
425
446
  webpackConfig.devtool = false;
426
- webpackConfig.plugins.push(new CssMinimizerPlugin());
447
+ webpackConfig.plugins.push(new CssMinimizerPlugin({
448
+ parallel: true,
449
+ minify: CssMinimizerPlugin.esbuildMinify
450
+ }));
427
451
  }
428
452
 
429
453
  return webpackConfig;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@oroinc/oro-webpack-config-builder",
3
- "version": "6.0.0-lts03",
4
- "author": "Oro, Inc (https://www.oroinc.com)",
3
+ "version": "6.0.0-lts05",
4
+ "author": "Oro, Inc. (https://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
+ "@swc/core": "^1.11.8",
9
10
  "@babel/core": "~7.23.3",
10
11
  "@babel/plugin-transform-runtime": "~7.21.0",
11
12
  "@babel/preset-env": "~7.21.2",
@@ -17,6 +18,7 @@
17
18
  "deepmerge": "~4.3.1",
18
19
  "exports-loader": "~4.0.0",
19
20
  "expose-loader": "~4.1.0",
21
+ "esbuild-loader": "^4.3.0",
20
22
  "file-loader": "~6.2.0",
21
23
  "html-webpack-plugin": "~5.5.0",
22
24
  "imports-loader": "~4.0.1",
@@ -38,6 +40,7 @@
38
40
  "svgo": "^3.0.2",
39
41
  "svgstore": "^3.0.1",
40
42
  "terser": "~5.17.1",
43
+ "terser-webpack-plugin": "^5.3.13",
41
44
  "text-loader": "0.0.1",
42
45
  "underscore": "1.13.*",
43
46
  "url-loader": "~4.1.1",
@@ -46,6 +49,7 @@
46
49
  "webpack-cli": "~5.0.0",
47
50
  "webpack-dev-server": "^4.11.1",
48
51
  "webpack-merge": "~5.8.0",
52
+ "webpack-subresource-integrity": "^5.2.0-rc.1",
49
53
  "wildcard": "~2.0.0"
50
54
  }
51
55
  }
@@ -0,0 +1,42 @@
1
+ const { createHash } = require('crypto');
2
+ const { Compilation, sources } = require('webpack');
3
+ const fs = require('fs').promises;
4
+ const path = require('path');
5
+
6
+ class IntegrityFilePlugin {
7
+ constructor({fileName = 'integrity.json', publicPath = '', algorithm = 'sha384'} = {}) {
8
+ this.fileName = fileName;
9
+ this.publicPath = publicPath;
10
+ this.algorithm = algorithm;
11
+ }
12
+
13
+ apply(compiler) {
14
+ compiler.hooks.thisCompilation.tap('IntegrityFilePlugin', (compilation) => {
15
+ compilation.hooks.processAssets.tapPromise(
16
+ { name: 'SubresourceIntegrityPlugin', stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER },
17
+ async () => {
18
+ const integrityData = Object.fromEntries(
19
+ Object.entries(compilation.assets)
20
+ .filter(([assetName]) => assetName.endsWith('.css') || assetName.endsWith('.js'))
21
+ .map(([assetName, asset]) => {
22
+ const hash = createHash(this.algorithm).update(asset.source()).digest('base64');
23
+ const assetNormalized = assetName.split('?')[0];
24
+
25
+ return [
26
+ path.join(compiler.options.output.publicPath || '', assetNormalized),
27
+ `${this.algorithm}-${hash}`
28
+ ];
29
+ })
30
+ );
31
+ const jsonData = JSON.stringify(integrityData, null, 2);
32
+ const outputPath = path.join(this.publicPath, compiler.options.output.publicPath, this.fileName);
33
+
34
+ await fs.writeFile(outputPath, jsonData, 'utf8');
35
+ compilation.emitAsset(outputPath, new sources.RawSource(jsonData));
36
+ }
37
+ );
38
+ });
39
+ }
40
+ }
41
+
42
+ module.exports = IntegrityFilePlugin;
@@ -118,8 +118,8 @@ class SvgSprite {
118
118
 
119
119
  /**
120
120
  * @param {Array} files
121
- @returns {{ filesList: {}, rtlFilesList: {}|undefined }}
122
- */
121
+ @returns {{ filesList: {}, rtlFilesList: {}|undefined }}
122
+ */
123
123
  createSpriteMap(files) {
124
124
  const SVGFiles = files.filter(file => path.extname(file) === '.svg');
125
125
  const {rtl_support: rtl} = this.themeConfig;