@pixolith/webpack-sw6-config 11.0.9 → 12.0.0
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/package.json +11 -11
- package/src/config.js +46 -6
- package/src/index.js +205 -7
- package/src/webpack.config.administration.js +92 -160
- package/src/webpack.config.dev.js +162 -167
- package/src/webpack.config.storefront.js +169 -154
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixolith/webpack-sw6-config",
|
|
3
3
|
"public": true,
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "12.0.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"scripts": {},
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"url": "https://github.com/pixolith/webpack-plugins/issues"
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/pixolith/webpack-plugins/tree/master/packages/webpack-hook-plugin/#readme",
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "5c29b0a4c1b2e0876f25a05f517100c83fc9a36c",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/cli": "7.25.9",
|
|
27
27
|
"@babel/core": "^7.26.0",
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"@babel/plugin-proposal-decorators": "7.25.9",
|
|
30
30
|
"@babel/preset-env": "7.26.0",
|
|
31
31
|
"@babel/preset-typescript": "7.26.0",
|
|
32
|
-
"@pixolith/eslint-config-sw6": "^
|
|
33
|
-
"@pixolith/external-svg-sprite-loader": "^
|
|
34
|
-
"@pixolith/stylelint-config-standard": "^
|
|
35
|
-
"@pixolith/webpack-assets-copy-plugin": "^
|
|
36
|
-
"@pixolith/webpack-filename-linter-plugin": "^
|
|
37
|
-
"@pixolith/webpack-hook-plugin": "^
|
|
38
|
-
"@pixolith/webpack-sw6-plugin-map-emitter": "^
|
|
39
|
-
"@pixolith/webpack-twig-assets-emitter-plugin": "^
|
|
40
|
-
"@pixolith/webpack-watcher": "^
|
|
32
|
+
"@pixolith/eslint-config-sw6": "^12.0.0",
|
|
33
|
+
"@pixolith/external-svg-sprite-loader": "^12.0.0",
|
|
34
|
+
"@pixolith/stylelint-config-standard": "^12.0.0",
|
|
35
|
+
"@pixolith/webpack-assets-copy-plugin": "^12.0.0",
|
|
36
|
+
"@pixolith/webpack-filename-linter-plugin": "^12.0.0",
|
|
37
|
+
"@pixolith/webpack-hook-plugin": "^12.0.0",
|
|
38
|
+
"@pixolith/webpack-sw6-plugin-map-emitter": "^12.0.0",
|
|
39
|
+
"@pixolith/webpack-twig-assets-emitter-plugin": "^12.0.0",
|
|
40
|
+
"@pixolith/webpack-watcher": "^12.0.0",
|
|
41
41
|
"@swc/core": "^1.9.3",
|
|
42
42
|
"autoprefixer": "^10.4.20",
|
|
43
43
|
"babel-loader": "^9.2.1",
|
package/src/config.js
CHANGED
|
@@ -6,11 +6,22 @@ const config = {
|
|
|
6
6
|
isProd: process.env.NODE_ENV === 'production',
|
|
7
7
|
isDebug: !!process.env.DEBUG || false,
|
|
8
8
|
shopwareMode: process.env.SHOPWARE_MODE,
|
|
9
|
-
shopwareVersion: process.env.SHOPWARE_VERSION || '6.6',
|
|
10
9
|
|
|
11
10
|
assetUrl: process.env.ASSET_URL || '/',
|
|
12
11
|
pluginPrefixes: process.env.PLUGIN_PREFIXES || 'Pxsw',
|
|
13
12
|
|
|
13
|
+
// Multi-theme build configuration (mandatory in v12+)
|
|
14
|
+
themeNames: process.env.THEME_NAMES
|
|
15
|
+
? process.env.THEME_NAMES.split(',')
|
|
16
|
+
.map((s) => s.trim())
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
: [],
|
|
19
|
+
skipPlugins: process.env.SKIP_PLUGINS
|
|
20
|
+
? process.env.SKIP_PLUGINS.split(',')
|
|
21
|
+
.map((s) => s.trim())
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
: [],
|
|
24
|
+
|
|
14
25
|
pxSharedPath: process.env.SHARED_SCSS_PATH || '../../shared',
|
|
15
26
|
scssFolder: process.env.SCSS_FOLDER || 'scss',
|
|
16
27
|
jsFolder: process.env.JS_FOLDER || 'js',
|
|
@@ -32,11 +43,35 @@ const config = {
|
|
|
32
43
|
shopwareVendorPath: Path.join(process.cwd(), 'vendor/shopware/storefront/Resources/app/storefront/vendor'),
|
|
33
44
|
shopwarePluginPath: Path.join(process.cwd(), 'vendor/shopware/storefront/Resources/app/storefront/src'),
|
|
34
45
|
|
|
35
|
-
allowedExtensions: ['.ts', '.js', '.scss', '.css', '.svg']
|
|
46
|
+
allowedExtensions: ['.ts', '.js', '.scss', '.css', '.svg'],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// PICKED_THEME: optional filter to build/watch a single theme from THEME_NAMES
|
|
50
|
+
let pickedTheme = process.env.PICKED_THEME
|
|
51
|
+
? process.env.PICKED_THEME.trim()
|
|
52
|
+
: '';
|
|
53
|
+
|
|
54
|
+
if (pickedTheme && config.themeNames.indexOf(pickedTheme) === -1) {
|
|
55
|
+
process.stderr.write(
|
|
56
|
+
`PICKED_THEME "${pickedTheme}" is not in THEME_NAMES [${config.themeNames.join(', ')}].\n`,
|
|
57
|
+
);
|
|
58
|
+
process.exit(1);
|
|
36
59
|
}
|
|
37
60
|
|
|
38
|
-
|
|
39
|
-
|
|
61
|
+
// buildThemes: the subset of themeNames that actually get compiled
|
|
62
|
+
// themeNames stays as the full list (used for _global_resources exclusion)
|
|
63
|
+
config.buildThemes = pickedTheme ? [pickedTheme] : config.themeNames;
|
|
64
|
+
|
|
65
|
+
const pxEntryPath =
|
|
66
|
+
process.env.PX_ENTRY_PATH ||
|
|
67
|
+
(process.env.SHOPWARE_MODE === 'storefront'
|
|
68
|
+
? 'src/Resources/app/storefront/private'
|
|
69
|
+
: 'src/Resources/app/administration/src');
|
|
70
|
+
const pxRouteSplitPath =
|
|
71
|
+
process.env.PX_ROUTE_SPLIT_PATH ||
|
|
72
|
+
(process.env.SHOPWARE_MODE === 'storefront'
|
|
73
|
+
? 'src/Resources/app/storefront/private/scss-route-split/*'
|
|
74
|
+
: '');
|
|
40
75
|
|
|
41
76
|
// Create a glob regex to match the plugin prefixes
|
|
42
77
|
let prefixes = config.pluginPrefixes.split(',').map(p => `${p}*`).join('|');
|
|
@@ -49,6 +84,7 @@ const routeSplitMatch = new RegExp(`/scss-route-split\/([\\w-]*)`);
|
|
|
49
84
|
|
|
50
85
|
module.exports = {
|
|
51
86
|
...config,
|
|
87
|
+
|
|
52
88
|
pluginSrcPath: Path.join(pluginSrcPath, pxEntryPath),
|
|
53
89
|
pluginScssPath: Path.join(pluginSrcPath, pxEntryPath, config.scssFolder),
|
|
54
90
|
pluginJsPath: Path.join(pluginSrcPath, pxEntryPath, config.jsFolder),
|
|
@@ -70,5 +106,9 @@ module.exports = {
|
|
|
70
106
|
pluginRouteSplitPath: Path.join(pluginSrcPath, pxRouteSplitPath),
|
|
71
107
|
vendorRouteSplitPath: Path.join(vendorSrcPath, pxRouteSplitPath),
|
|
72
108
|
|
|
73
|
-
|
|
74
|
-
|
|
109
|
+
// Raw glob base paths for multi-theme resource resolution
|
|
110
|
+
pluginGlobBase: pluginSrcPath,
|
|
111
|
+
vendorGlobBase: vendorSrcPath,
|
|
112
|
+
pxEntryPath: pxEntryPath,
|
|
113
|
+
resourcesPath: process.env.RESOURCES_PATHS,
|
|
114
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
const Fs = require('fs');
|
|
2
|
+
const Glob = require('glob');
|
|
1
3
|
const config = require('./config');
|
|
2
4
|
const production = require('./webpack.config.production');
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
5
|
+
const createStorefrontConfig = require('./webpack.config.storefront');
|
|
6
|
+
const createDevConfig = require('./webpack.config.dev');
|
|
7
|
+
const createAdministrationConfig = require('./webpack.config.administration');
|
|
6
8
|
const pkg = require('./../package.json');
|
|
7
9
|
const watcher = require('@pixolith/webpack-watcher');
|
|
8
10
|
const { merge } = require('webpack-merge');
|
|
11
|
+
const ChangeCase = require('change-case');
|
|
9
12
|
|
|
10
13
|
const setup = () => {
|
|
11
14
|
watcher.clean(config);
|
|
12
|
-
|
|
15
|
+
config.buildThemes.forEach((themeName) => {
|
|
16
|
+
watcher.compileTheme(themeName, config);
|
|
17
|
+
});
|
|
13
18
|
|
|
14
19
|
if (config.isDebug) {
|
|
15
20
|
console.table({
|
|
@@ -29,14 +34,207 @@ const setup = () => {
|
|
|
29
34
|
isProd: config.isProd,
|
|
30
35
|
shopwareMode: config.shopwareMode,
|
|
31
36
|
assetUrl: config.assetUrl,
|
|
37
|
+
themeNames: config.themeNames.join(', ') + (config.buildThemes.length < config.themeNames.length ? ' (building: ' + config.buildThemes.join(', ') + ')' : ''),
|
|
32
38
|
version: pkg.version,
|
|
33
39
|
});
|
|
34
40
|
}
|
|
35
41
|
};
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Build per-theme resource paths for sass-resources-loader.
|
|
45
|
+
*
|
|
46
|
+
* Each theme gets:
|
|
47
|
+
* 1. uses.scss (shared vendor utilities)
|
|
48
|
+
* 2. vendor global resources (vendor/pxsw/...)
|
|
49
|
+
* 3. all non-theme plugin _global_resources (custom/plugins + custom/static-plugins
|
|
50
|
+
* that are NOT in THEME_NAMES)
|
|
51
|
+
* 4. this theme's _global_resources (overrides everything)
|
|
52
|
+
*
|
|
53
|
+
* Other themes' global resources are excluded to prevent style bleeding.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} themeName - Theme name (e.g. 'PxswEbertTheme')
|
|
56
|
+
* @param {Object} options
|
|
57
|
+
* @param {string[]} options.uses - Paths to shared vendor uses.scss
|
|
58
|
+
* @param {string[]} options.sharedVendorResourcePaths - Paths to shared vendor _global_resources
|
|
59
|
+
* @returns {string[]} Array of SCSS resource paths
|
|
60
|
+
*/
|
|
61
|
+
const getResourcesPaths = (themeName, options) => {
|
|
62
|
+
let uses = options.uses || [];
|
|
63
|
+
let sharedVendorResourcePaths = options.sharedVendorResourcePaths || [];
|
|
64
|
+
let paths = [].concat(uses, sharedVendorResourcePaths);
|
|
65
|
+
let globalResourcesSuffix = '/src/Resources/app/_global_resources';
|
|
66
|
+
let scssGlob = '/**/*.scss';
|
|
67
|
+
|
|
68
|
+
// Collect base plugin global resources (plugins NOT in THEME_NAMES)
|
|
69
|
+
let pluginDirs = ['custom/plugins', 'custom/static-plugins'];
|
|
70
|
+
pluginDirs.forEach((dir) => {
|
|
71
|
+
if (!Fs.existsSync(dir)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let entries = Fs.readdirSync(dir).filter((name) => {
|
|
76
|
+
// Must match plugin prefix pattern
|
|
77
|
+
let prefixes = (config.pluginPrefixes || 'Pxsw').split(',');
|
|
78
|
+
let matchesPrefix = prefixes.some((p) =>
|
|
79
|
+
name.startsWith(p.trim()),
|
|
80
|
+
);
|
|
81
|
+
if (!matchesPrefix) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// Exclude ALL themes from base pool — prevents style bleeding
|
|
85
|
+
let isTheme = config.themeNames.some(
|
|
86
|
+
(t) => name.indexOf(t) !== -1,
|
|
87
|
+
);
|
|
88
|
+
return !isTheme;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
entries.forEach((name) => {
|
|
92
|
+
let glob = dir + '/' + name + globalResourcesSuffix + scssGlob;
|
|
93
|
+
if (Glob.sync(glob).length) {
|
|
94
|
+
paths.push(glob);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Add this theme's global resources LAST (overrides base)
|
|
100
|
+
pluginDirs.forEach((dir) => {
|
|
101
|
+
if (!Fs.existsSync(dir)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let themeGlob =
|
|
106
|
+
dir + '/*' + themeName + '*' + globalResourcesSuffix + scssGlob;
|
|
107
|
+
if (Glob.sync(themeGlob).length) {
|
|
108
|
+
paths.push(themeGlob);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return paths;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create an array of webpack configs, one per theme.
|
|
117
|
+
* Each theme gets its own dev config (with per-theme resourcesPaths for
|
|
118
|
+
* sass-resources-loader) and its own storefront config (with per-theme entry).
|
|
119
|
+
*
|
|
120
|
+
* @param {Object} options
|
|
121
|
+
* @param {string[]} options.uses - Paths to shared vendor uses.scss
|
|
122
|
+
* @param {string[]} options.sharedVendorResourcePaths - Paths to shared vendor _global_resources
|
|
123
|
+
* @returns {Object[]} Array of webpack config objects (one per theme)
|
|
124
|
+
*/
|
|
125
|
+
const createThemeConfigs = (options) => {
|
|
126
|
+
setup();
|
|
127
|
+
|
|
128
|
+
return config.buildThemes.map((themeName, index) => {
|
|
129
|
+
let resourcesPaths = getResourcesPaths(themeName, options);
|
|
130
|
+
let themeSlug = ChangeCase.kebabCase(themeName);
|
|
131
|
+
let themeOptions = {
|
|
132
|
+
themeName: themeName,
|
|
133
|
+
resourcesPaths: resourcesPaths,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
let devCfg = createDevConfig(themeOptions);
|
|
137
|
+
let storefrontCfg = createStorefrontConfig(themeOptions);
|
|
138
|
+
let merged = merge(
|
|
139
|
+
devCfg,
|
|
140
|
+
storefrontCfg,
|
|
141
|
+
config.isProd ? production : {},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Only the first compiler should have devServer (webpack multi-compiler limitation)
|
|
145
|
+
if (index > 0) {
|
|
146
|
+
delete merged.devServer;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Per-theme filesystem cache to avoid collisions between compilers
|
|
150
|
+
merged.cache = {
|
|
151
|
+
type: 'filesystem',
|
|
152
|
+
name: themeSlug,
|
|
153
|
+
buildDependencies: {
|
|
154
|
+
config: [__filename],
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return merged;
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const setupAdministration = () => {
|
|
163
|
+
watcher.clean(config);
|
|
164
|
+
config.buildThemes.forEach((themeName) => {
|
|
165
|
+
watcher.compileAdministration(themeName, config);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
if (config.isDebug) {
|
|
169
|
+
console.table({
|
|
170
|
+
...config,
|
|
171
|
+
|
|
172
|
+
version: pkg.version,
|
|
173
|
+
|
|
174
|
+
pluginMatch: config.pluginMatch.toString(),
|
|
175
|
+
vendorMatch: config.vendorMatch.toString(),
|
|
176
|
+
allowedExtensions: config.allowedExtensions.toString(),
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
console.table({
|
|
180
|
+
isProd: config.isProd,
|
|
181
|
+
shopwareMode: config.shopwareMode,
|
|
182
|
+
assetUrl: config.assetUrl,
|
|
183
|
+
themeNames: config.themeNames.join(', ') + (config.buildThemes.length < config.themeNames.length ? ' (building: ' + config.buildThemes.join(', ') + ')' : ''),
|
|
184
|
+
version: pkg.version,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Create an array of webpack configs for administration, one per theme.
|
|
191
|
+
* Each theme gets its own dev config (with per-theme resourcesPaths for
|
|
192
|
+
* sass-resources-loader) and its own administration config (with per-theme
|
|
193
|
+
* SCSS entries for theme-specific styling).
|
|
194
|
+
*
|
|
195
|
+
* @param {Object} options
|
|
196
|
+
* @param {string[]} options.uses - Paths to shared vendor uses.scss
|
|
197
|
+
* @param {string[]} options.sharedVendorResourcePaths - Paths to shared vendor _global_resources
|
|
198
|
+
* @returns {Object[]} Array of webpack config objects (one per theme)
|
|
199
|
+
*/
|
|
200
|
+
const createAdminConfigs = (options) => {
|
|
201
|
+
setupAdministration();
|
|
202
|
+
|
|
203
|
+
return config.buildThemes.map((themeName, index) => {
|
|
204
|
+
let resourcesPaths = getResourcesPaths(themeName, options);
|
|
205
|
+
let themeSlug = ChangeCase.kebabCase(themeName);
|
|
206
|
+
let themeOptions = {
|
|
207
|
+
themeName: themeName,
|
|
208
|
+
resourcesPaths: resourcesPaths,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
let devCfg = createDevConfig(themeOptions);
|
|
212
|
+
let adminCfg = createAdministrationConfig(themeOptions);
|
|
213
|
+
let merged = merge(
|
|
214
|
+
devCfg,
|
|
215
|
+
adminCfg,
|
|
216
|
+
config.isProd ? production : {},
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
// Only the first compiler should have devServer (webpack multi-compiler limitation)
|
|
220
|
+
if (index > 0) {
|
|
221
|
+
delete merged.devServer;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Per-theme filesystem cache to avoid collisions between compilers
|
|
225
|
+
merged.cache = {
|
|
226
|
+
type: 'filesystem',
|
|
227
|
+
name: themeSlug + '-admin',
|
|
228
|
+
buildDependencies: {
|
|
229
|
+
config: [__filename],
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return merged;
|
|
234
|
+
});
|
|
235
|
+
};
|
|
38
236
|
|
|
39
237
|
module.exports = {
|
|
40
|
-
|
|
41
|
-
|
|
238
|
+
createThemeConfigs: createThemeConfigs,
|
|
239
|
+
createAdminConfigs: createAdminConfigs,
|
|
42
240
|
};
|
|
@@ -5,178 +5,110 @@ const Path = require('path'),
|
|
|
5
5
|
Entry = require('webpack-glob-entry'),
|
|
6
6
|
ChangeCase = require('change-case'),
|
|
7
7
|
MiniCssExtractPlugin = require('mini-css-extract-plugin'),
|
|
8
|
-
Consola = require('consola')
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
Consola = require('consola');
|
|
9
|
+
|
|
10
|
+
module.exports = function createAdministrationConfig(themeOptions) {
|
|
11
|
+
let themeName = themeOptions && themeOptions.themeName;
|
|
12
|
+
let themeSlug = themeName
|
|
13
|
+
? ChangeCase.kebabCase(themeName)
|
|
14
|
+
: 'administration';
|
|
15
|
+
|
|
16
|
+
let outputConfig = {
|
|
13
17
|
path: config.outputPath,
|
|
14
|
-
publicPath: config.
|
|
15
|
-
filename: (chunkData) => {
|
|
16
|
-
let pluginName = chunkData.chunk.name.toLowerCase().replace('pxsw-pxsw-', 'pxsw-');
|
|
17
|
-
pluginName = config.shopwareVersion === '6.6' ? pluginName.replace('vendor-', '') : pluginName;
|
|
18
|
-
return config.shopwareVersion === '6.6' ?
|
|
19
|
-
`${pluginName.replace(/-/g, '',)}/administration/js/${pluginName}.js` :
|
|
20
|
-
`js/${chunkData.chunk.name.toLowerCase()}${
|
|
21
|
-
config.isProd ? '.admin.[contenthash]' : ''
|
|
22
|
-
}.js`;
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
miniCssChunksConfig = {
|
|
18
|
+
publicPath: config.assetUrl,
|
|
26
19
|
filename: (chunkData) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}.css`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
20
|
+
return `js/${chunkData.chunk.name.toLowerCase()}${
|
|
21
|
+
config.isProd ? '.admin.[contenthash]' : ''
|
|
22
|
+
}.js`;
|
|
23
|
+
},
|
|
24
|
+
uniqueName: themeSlug + '-admin',
|
|
25
|
+
};
|
|
36
26
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Path.join(config.pluginSrcPath, 'index.js'),
|
|
45
|
-
);
|
|
27
|
+
let miniCssChunksConfig = {
|
|
28
|
+
filename: (chunkData) => {
|
|
29
|
+
return `css/[name]${
|
|
30
|
+
config.isProd ? '.admin.[contenthash]' : ''
|
|
31
|
+
}.css`;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
46
34
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
return {
|
|
36
|
+
name: themeSlug + '-admin',
|
|
37
|
+
entry: () => {
|
|
38
|
+
let entriesPlugins = Entry(
|
|
39
|
+
(filePath) =>
|
|
40
|
+
ChangeCase.kebabCase(filePath.match(config.pluginMatch)[2]),
|
|
41
|
+
Path.join(config.pluginSrcPath, 'index.js'),
|
|
42
|
+
);
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
let entriesVendor = Entry(
|
|
45
|
+
(filePath) =>
|
|
46
|
+
ChangeCase.kebabCase(filePath.match(config.vendorMatch)[1]),
|
|
47
|
+
Path.resolve(config.vendorSrcPath, 'index.js'),
|
|
48
|
+
);
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
|
|
74
|
-
type: 'asset/resource',
|
|
75
|
-
generator: {
|
|
76
|
-
filename: config.shopwareVersion === '6.6' ? '../img/[name][ext]' : 'img/[name][ext]'
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
test: /\.(eot|ttf|woff2?)(\?v=\d+\.\d+\.\d+)?$/,
|
|
81
|
-
type: 'asset/resource',
|
|
82
|
-
generator: {
|
|
83
|
-
filename: config.shopwareVersion === '6.6' ? '../fonts/[name][ext]' : 'fonts/[name][ext]'
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
test: /\.svg$/,
|
|
88
|
-
use: [
|
|
89
|
-
{
|
|
90
|
-
loader: SvgStorePlugin.loader,
|
|
91
|
-
options: {
|
|
92
|
-
name: 'sprite/sprite.svg',
|
|
93
|
-
iconName: '[name]',
|
|
94
|
-
overrideOrder: config.spriteOrder,
|
|
95
|
-
ignoreIconsByName: config.ignoreIcons,
|
|
96
|
-
onlySymbols: true,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
loader: 'svgo-loader',
|
|
101
|
-
options: {
|
|
102
|
-
plugins: [
|
|
103
|
-
'cleanupAttrs',
|
|
104
|
-
'removeDoctype',
|
|
105
|
-
'removeXMLProcInst',
|
|
106
|
-
'cleanupEnableBackground',
|
|
107
|
-
'convertStyleToAttrs',
|
|
108
|
-
'convertPathData',
|
|
109
|
-
'cleanupIds',
|
|
110
|
-
'minifyStyles',
|
|
111
|
-
'removeUselessDefs',
|
|
112
|
-
'convertShapeToPath',
|
|
113
|
-
'removeUnusedNS',
|
|
114
|
-
'removeDimensions',
|
|
115
|
-
'convertTransform',
|
|
116
|
-
'collapseGroups',
|
|
117
|
-
'removeComments',
|
|
118
|
-
'removeEditorsNSData',
|
|
119
|
-
'removeUnknownsAndDefaults',
|
|
120
|
-
],
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
},
|
|
127
|
-
output: outputConfig,
|
|
128
|
-
plugins: [
|
|
129
|
-
new SvgStorePlugin(),
|
|
130
|
-
new MiniCssExtractPlugin(miniCssChunksConfig),
|
|
131
|
-
].concat(
|
|
132
|
-
config.isProd && config.shopwareVersion === '6.6' ?
|
|
133
|
-
new AssetsCopyPlugin({
|
|
134
|
-
includes: ['js', 'css'],
|
|
135
|
-
ignoreFiles: [/[-\w.]*.hot-update.js/],
|
|
136
|
-
files: [
|
|
137
|
-
{
|
|
138
|
-
from: config.outputPath,
|
|
139
|
-
to: '$pluginPath/$plugin/src/Resources/public',
|
|
140
|
-
replace: async (fromPath, toPath) => {
|
|
141
|
-
let composerPluginName = Path.basename(fromPath).replace(
|
|
142
|
-
Path.extname(fromPath),
|
|
143
|
-
'',
|
|
144
|
-
).replace('pxsw-', ''),
|
|
145
|
-
pluginName = 'Pxsw' + ChangeCase.pascalCase(composerPluginName);
|
|
50
|
+
// Discover the consolidated admin SCSS entry from .theme-entries/{theme-slug}/
|
|
51
|
+
let scssEntries = {};
|
|
52
|
+
let scssEntryDir = Path.join(
|
|
53
|
+
config.outputPath,
|
|
54
|
+
'.theme-entries',
|
|
55
|
+
themeSlug,
|
|
56
|
+
);
|
|
57
|
+
let scssEntryFile = Path.join(
|
|
58
|
+
scssEntryDir,
|
|
59
|
+
themeSlug + '-admin.scss',
|
|
60
|
+
);
|
|
146
61
|
|
|
147
|
-
|
|
148
|
-
|
|
62
|
+
if (Fs.existsSync(scssEntryFile)) {
|
|
63
|
+
scssEntries[themeSlug + '-admin-scss'] = scssEntryFile;
|
|
64
|
+
}
|
|
149
65
|
|
|
150
|
-
|
|
66
|
+
let allEntries = {
|
|
67
|
+
...entriesPlugins,
|
|
68
|
+
...entriesVendor,
|
|
69
|
+
...scssEntries,
|
|
70
|
+
};
|
|
151
71
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
72
|
+
if (config.isDebug) {
|
|
73
|
+
Consola.info(
|
|
74
|
+
`[${themeName || themeSlug}] Administration webpack entry points:`,
|
|
75
|
+
);
|
|
76
|
+
console.table(allEntries);
|
|
77
|
+
}
|
|
159
78
|
|
|
160
|
-
|
|
161
|
-
|
|
79
|
+
return allEntries;
|
|
80
|
+
},
|
|
81
|
+
module: {
|
|
82
|
+
rules: [
|
|
83
|
+
{
|
|
84
|
+
test: /\.js$/,
|
|
85
|
+
exclude: (file) => /node_modules/.test(file),
|
|
86
|
+
loader: 'babel-loader',
|
|
87
|
+
options: {
|
|
88
|
+
configFile: Path.resolve(__dirname, 'babel.config.js'),
|
|
162
89
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
|
|
93
|
+
type: 'asset/resource',
|
|
94
|
+
generator: {
|
|
95
|
+
filename: 'img/[name][ext]',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
test: /\.(eot|ttf|woff2?)(\?v=\d+\.\d+\.\d+)?$/,
|
|
100
|
+
type: 'asset/resource',
|
|
101
|
+
generator: {
|
|
102
|
+
filename: 'fonts/[name][ext]',
|
|
174
103
|
},
|
|
175
104
|
},
|
|
176
|
-
|
|
177
|
-
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
output: outputConfig,
|
|
108
|
+
plugins: [new MiniCssExtractPlugin(miniCssChunksConfig)],
|
|
178
109
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
110
|
+
optimization: {
|
|
111
|
+
splitChunks: false,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
182
114
|
};
|