PluginProbe
Ultimate Store Kit / 3.1.3
Ultimate Store Kit v3.1.3
3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 92 releases
ultimate-store-kit / webpack.config.js

webpack.config.js in Ultimate Store Kit 3.1.3, at webpack.config.js

169 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * External Dependencies
3 */
4 const fs = require('fs');
5 const { resolve, relative, extname, join } = require('path');
6 const webpack = require('webpack');
7 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
8 const CopyWebpackPlugin = require('copy-webpack-plugin');
9 const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
10 const defaultConfig = require('@wordpress/scripts/config/webpack.config');
11
12 const isProduction = process.env.NODE_ENV === 'production';
13
14 /**
15 * Recursively find files by extension, skipping SCSS partials (prefixed with _).
16 */
17 function findFiles(dir, ext) {
18 const results = [];
19 if (!fs.existsSync(dir)) return results;
20 const items = fs.readdirSync(dir, { withFileTypes: true });
21 for (const item of items) {
22 const fullPath = join(dir, item.name);
23 if (item.isDirectory()) {
24 // Skip src/scss/components folder
25 if (fullPath.includes('src/scss/components')) continue;
26 results.push(...findFiles(fullPath, ext));
27 } else if (item.name.endsWith(ext) && !item.name.startsWith('_')) {
28 results.push(fullPath);
29 }
30 }
31 return results;
32 }
33
34 // Build entry map: srcDir -> outDir (without extension)
35 function buildEntries(srcDir, ext, outDir) {
36 const entries = {};
37 findFiles(resolve(__dirname, srcDir), ext).forEach((file) => {
38 const rel = relative(resolve(__dirname, srcDir), file);
39 const name = rel.replace(extname(rel), '');
40 entries[`${outDir}/${name}`] = file;
41 });
42 return entries;
43 }
44
45 // src/js/**/*.js -> assets/js/**/*.js
46 const jsEntries = buildEntries('src/js', '.js', 'js');
47
48 // src/scss/**/*.scss -> assets/css/**/*.css (partials excluded)
49 const scssEntries = buildEntries('src/scss', '.scss', 'css');
50
51 // src/admin/dashboard.js -> assets/admin/admin.js (+ admin.css via style.scss import)
52 const adminEntries = {
53 'admin/admin': resolve(__dirname, 'src/admin/dashboard.js'),
54 };
55
56 // src/admin/others/**/*.js -> assets/admin/others/**/*.js
57 const adminOthersJsEntries = buildEntries('src/admin/others', '.js', 'admin/others');
58
59 // src/admin/others/scss/**/*.scss -> assets/admin/others/css/**/*.css
60 const adminOthersScssEntries = (() => {
61 const entries = {};
62 const base = resolve(__dirname, 'src/admin/others');
63 findFiles(base, '.scss').forEach((file) => {
64 const rel = relative(base, file);
65 const name = rel.replace(extname(rel), '').replace(/^scss([\\/])/, 'css$1');
66 entries[`admin/others/${name}`] = file;
67 });
68 return entries;
69 })();
70
71 // Keep default plugins except MiniCssExtractPlugin and CopyPlugin (we define our own)
72 const filteredPlugins = defaultConfig.plugins.filter(
73 (plugin) =>
74 !(plugin instanceof MiniCssExtractPlugin) &&
75 !(plugin.constructor && plugin.constructor.name === 'CopyPlugin')
76 );
77
78 // Remove the default SCSS rule — we supply our own with url resolution disabled
79 const defaultScssRule = (defaultConfig.module?.rules || []).find(
80 (rule) => rule && rule.test && rule.test.toString() === /\.(sc|sa)ss$/.toString()
81 );
82 const nonScssRules = (defaultConfig.module?.rules || []).filter((r) => r !== defaultScssRule);
83
84 // Clone the default SCSS rule but set url:false on css-loader
85 const scssRule = {
86 ...defaultScssRule,
87 use: defaultScssRule.use.map((u) => {
88 const loader = typeof u === 'string' ? u : u?.loader;
89 if (loader && /[\\/]css-loader[\\/]/.test(loader)) {
90 return {
91 ...(typeof u === 'string' ? { loader: u } : u),
92 options: { ...(typeof u === 'object' ? u.options : {}), url: false },
93 };
94 }
95 return u;
96 }),
97 };
98
99 const config = {
100 ...defaultConfig,
101
102 entry: {
103 ...jsEntries,
104 ...scssEntries,
105 ...adminEntries,
106 ...adminOthersJsEntries,
107 ...adminOthersScssEntries,
108 },
109
110 output: {
111 path: resolve(__dirname, 'assets'),
112 filename: '[name].js',
113 publicPath: 'auto',
114 chunkFilename: '[name].js',
115 },
116
117 module: {
118 ...defaultConfig.module,
119 rules: [...nonScssRules, scssRule],
120 },
121
122 plugins: [
123 new RemoveEmptyScriptsPlugin(),
124 new MiniCssExtractPlugin({ filename: '[name].css' }),
125 new CopyWebpackPlugin({
126 patterns: [
127 { from: 'src/fonts', to: 'fonts' },
128 { from: 'src/images', to: 'images' },
129 { from: 'src/vendor', to: 'vendor' },
130 ],
131 }),
132 new webpack.DefinePlugin({
133 'process.env.NODE_ENV': JSON.stringify(
134 isProduction ? 'production' : 'development'
135 ),
136 }),
137 ...filteredPlugins.filter(
138 (p) => p.constructor.name !== 'DependencyExtractionWebpackPlugin'
139 ),
140
141 /*
142 * Keep @wordpress/* externals but remove .asset.php files after build
143 */
144 new (require('@wordpress/dependency-extraction-webpack-plugin'))(),
145 {
146 apply(compiler) {
147 compiler.hooks.afterEmit.tapAsync('RemoveAssetPhp', (compilation, callback) => {
148 const outputPath = compilation.outputOptions.path;
149 findFiles(outputPath, '.asset.php').forEach((file) => {
150 try { fs.unlinkSync(file); } catch (e) { /* ignore */ }
151 });
152 callback();
153 });
154 },
155 },
156 ],
157
158 devtool: false,
159 stats: 'minimal',
160 };
161
162 if (!isProduction) {
163 config.devServer = {
164 ...config.devServer,
165 allowedHosts: 'all',
166 };
167 }
168
169 module.exports = config;