@meteorjs/rspack 0.0.18 → 0.0.20

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.
@@ -122,6 +122,57 @@ function splitOverlapRulesMerge(aRules, bRules) {
122
122
  return result;
123
123
  }
124
124
 
125
+ /**
126
+ * Creates a customizer function for unique plugins.
127
+ *
128
+ * @param {string} key - The key to check for uniqueness
129
+ * @param {string[]} pluginNames - Array of plugin constructor names to make unique
130
+ * @param {Function} getter - Function to get the identifier from the plugin
131
+ * @returns {Function} Customizer function
132
+ */
133
+ export function unique(key, pluginNames = [], getter = item => item.constructor && item.constructor.name) {
134
+ return (a, b, k) => {
135
+ if (k !== key) return undefined;
136
+
137
+ const aItems = Array.isArray(a) ? a : [];
138
+ const bItems = Array.isArray(b) ? b : [];
139
+
140
+ // If not dealing with plugins, return undefined to use default merging
141
+ if (key !== 'plugins') return undefined;
142
+
143
+ // Create a map to track plugins by their identifier
144
+ const uniquePlugins = new Map();
145
+
146
+ // Process all plugins from both arrays
147
+ [...aItems, ...bItems].forEach(plugin => {
148
+ const id = getter(plugin);
149
+
150
+ // If this is a plugin we want to make unique and we can identify it
151
+ if (id && pluginNames.includes(id)) {
152
+ uniquePlugins.set(id, plugin); // Keep only the last instance
153
+ }
154
+ });
155
+
156
+ // Create the result array with all non-unique plugins from a
157
+ const result = aItems.filter(plugin => {
158
+ const id = getter(plugin);
159
+ return !id || !pluginNames.includes(id) || uniquePlugins.get(id) === plugin;
160
+ });
161
+
162
+ // Add unique plugins from b that weren't already in the result
163
+ bItems.forEach(plugin => {
164
+ const id = getter(plugin);
165
+ if (!id || !pluginNames.includes(id)) {
166
+ result.push(plugin);
167
+ } else if (uniquePlugins.get(id) === plugin) {
168
+ result.push(plugin);
169
+ }
170
+ });
171
+
172
+ return result;
173
+ };
174
+ }
175
+
125
176
  /**
126
177
  * Merges webpack/rspack configs with smart handling of overlapping rules.
127
178
  *
@@ -136,6 +187,16 @@ export function mergeSplitOverlap(...configs) {
136
187
  const bRules = Array.isArray(b) ? b : [];
137
188
  return splitOverlapRulesMerge(aRules, bRules);
138
189
  }
190
+
191
+ // Handle plugins uniqueness
192
+ if (key === 'plugins') {
193
+ return unique(
194
+ 'plugins',
195
+ ['HtmlRspackPlugin'],
196
+ (plugin) => plugin.constructor && plugin.constructor.name
197
+ )(a, b, key);
198
+ }
199
+
139
200
  // fall through to default merging
140
201
  return undefined;
141
202
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meteorjs/rspack",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "Configuration logic for using Rspack in Meteor projects",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -17,7 +17,6 @@ export default class CleanBuildAssetsPlugin {
17
17
  constructor(options = {}) {
18
18
  const defaults = [
19
19
  'public/_build-assets',
20
- 'public/_build-bundles',
21
20
  'private/_build-assets',
22
21
  ];
23
22
 
package/rspack.config.js CHANGED
@@ -139,6 +139,7 @@ export default function (inMeteor = {}, argv = {}) {
139
139
  // Determine output points
140
140
  const outputPath = Meteor.outputPath;
141
141
  const outputDir = path.dirname(Meteor.outputPath || '');
142
+
142
143
  const outputFilename = Meteor.outputFilename;
143
144
 
144
145
  // Determine run point
@@ -156,6 +157,10 @@ export default function (inMeteor = {}, argv = {}) {
156
157
  const bundlesContext = Meteor.bundlesContext || 'bundles';
157
158
  const assetsContext = Meteor.assetsContext || 'assets';
158
159
 
160
+ // Determine build output and pass to Meteor
161
+ const buildOutputDir = path.resolve(process.cwd(), buildContext, outputDir);
162
+ Meteor.buildOutputDir = buildOutputDir;
163
+
159
164
  // Set watch options
160
165
  const watchOptions = {
161
166
  ...defaultWatchOptions,
@@ -243,6 +248,7 @@ export default function (inMeteor = {}, argv = {}) {
243
248
  cssChunkFilename: `${assetsContext}/[id]${
244
249
  isProd ? '.[contenthash]' : ''
245
250
  }.css`,
251
+ clean: isProd,
246
252
  },
247
253
  optimization: {
248
254
  usedExports: true,
@@ -302,7 +308,7 @@ export default function (inMeteor = {}, argv = {}) {
302
308
  </body>
303
309
  `,
304
310
  }),
305
- new RspackMeteorHtmlPlugin({}),
311
+ new RspackMeteorHtmlPlugin(),
306
312
  ],
307
313
  watchOptions,
308
314
  devtool: isDevEnvironment || isTest ? 'source-map' : 'hidden-source-map',