@meteorjs/rspack 0.0.49 → 0.0.51

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/lib/ignore.js ADDED
@@ -0,0 +1,117 @@
1
+ var fs = require('fs');
2
+ var path = require('path');
3
+
4
+ // Cleans an entry from wildcard patterns (*/**)
5
+ function cleanWildcardEntry(entry) {
6
+ // If it's an extension pattern like *.ext, skip it
7
+ if (entry.match(/\*\.[^\/]+$/)) {
8
+ return null;
9
+ }
10
+
11
+ // Handle patterns like my-folder/**/* by extracting the folder part
12
+ if (entry.includes('/**/')) {
13
+ const folderContext = entry.split('/**/')[0].replace(/\/+$/, '');
14
+ if (folderContext) {
15
+ return folderContext;
16
+ }
17
+ }
18
+
19
+ // Otherwise, extract the folder context by removing the wildcard part
20
+ if (entry.includes('*')) {
21
+ const folderContext = entry.split('*')[0].replace(/\/+$/, '');
22
+ if (folderContext) {
23
+ return folderContext;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ return entry;
29
+ }
30
+
31
+ /**
32
+ * Reads the .meteorignore file from the given project directory and returns
33
+ * the parsed entries.
34
+ *
35
+ * @param {string} projectDir - The project directory path
36
+ * @param {Object} options - Options for processing ignore entries
37
+ * @param {boolean} options.foldersOnly - If true, returns only folder entries
38
+ * @returns {Array<string>} - Array of ignore entries
39
+ */
40
+ const getMeteorIgnoreEntries = function (projectDir, options) {
41
+ options = options || {};
42
+ const foldersOnly = !!options.foldersOnly;
43
+
44
+ const meteorIgnorePath = path.join(projectDir, '.meteorignore');
45
+
46
+ // Check if .meteorignore file exists
47
+ let entries = [];
48
+ try {
49
+ const fileContent = fs.readFileSync(meteorIgnorePath, 'utf8');
50
+
51
+ // Process each line in the file
52
+ entries = fileContent.split(/\r?\n/).filter(line => {
53
+ // Skip empty lines and comments
54
+ return line.trim() !== '' && !line.trim().startsWith('#');
55
+ });
56
+
57
+ // Clean all entries from wildcard patterns (*/** parts)
58
+ entries = entries.map(entry => {
59
+ return cleanWildcardEntry(entry);
60
+ }).filter(entry => entry !== null);
61
+
62
+ if (foldersOnly) {
63
+ // Filter to include only entries that are likely to be folders
64
+ entries = entries.filter(entry => {
65
+ // Entries ending with / are definitely folders
66
+ if (entry.endsWith('/')) {
67
+ return true;
68
+ }
69
+
70
+ // Try to determine if it's a folder by checking if it exists
71
+ // and is a directory
72
+ try {
73
+ const fullPath = path.join(projectDir, entry);
74
+ return fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory();
75
+ } catch (e) {
76
+ // If we can't determine, assume it's not a folder
77
+ return false;
78
+ }
79
+ });
80
+ }
81
+
82
+ return entries;
83
+ } catch (e) {
84
+ // If the file doesn't exist or can't be read, return an empty array
85
+ return [];
86
+ }
87
+ };
88
+
89
+ /**
90
+ * Creates a regex pattern to ignore specified folders.
91
+ * The pattern will match paths where the specified folders appear as complete path segments.
92
+ * Special regex characters in folder names are automatically escaped.
93
+ * @param {string[]} folders - Array of folder names to ignore
94
+ * @returns {RegExp} - Regex pattern to ignore the specified folders
95
+ */
96
+ function createIgnoreFoldersRegex(folders) {
97
+ if (!Array.isArray(folders) || folders.length === 0) {
98
+ throw new Error('folders must be a non-empty array');
99
+ }
100
+
101
+ // Escape special regex characters in folder names
102
+ const escapedFolders = folders.map(folder =>
103
+ folder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
104
+ );
105
+
106
+ // Join folder names with | for the regex pattern
107
+ const foldersPattern = escapedFolders.join('|');
108
+
109
+ // Create a regex that matches paths where the specified folders appear as complete path segments
110
+ // Format: /(^|\/)(folder1|folder2|folder3)(\/|$)/
111
+ return new RegExp(`(^|\\/)(${foldersPattern})(\\/|$)`);
112
+ }
113
+
114
+ module.exports = {
115
+ createIgnoreFoldersRegex,
116
+ getMeteorIgnoreEntries,
117
+ };
package/lib/test.js ADDED
@@ -0,0 +1,50 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { createIgnoreFoldersRegex, getMeteorIgnoreEntries } = require("./ignore.js");
4
+
5
+ /**
6
+ * Generates eager test files dynamically
7
+ * @param {Object} options - Options for generating the test file
8
+ * @param {boolean} options.isAppTest - Whether this is an app test
9
+ * @param {string} options.projectDir - The project directory
10
+ * @returns {string} The path to the generated file
11
+ */
12
+ const generateEagerTestFile = ({ isAppTest, projectDir }) => {
13
+ const distDir = path.resolve(projectDir, ".meteor/local/test");
14
+ if (!fs.existsSync(distDir)) {
15
+ fs.mkdirSync(distDir, { recursive: true });
16
+ }
17
+
18
+ const ignoredFolders = getMeteorIgnoreEntries(projectDir, {
19
+ foldersOnly: true,
20
+ });
21
+ const excludeFoldersRegex = createIgnoreFoldersRegex([
22
+ "node_modules",
23
+ ".meteor",
24
+ "_build",
25
+ ...ignoredFolders,
26
+ ]);
27
+
28
+ const filename = isAppTest ? "eager-app-tests.mjs" : "eager-tests.mjs";
29
+ const filePath = path.resolve(distDir, filename);
30
+ const regExp = isAppTest
31
+ ? "/\\.app-(?:test|spec)s?\\.[^.]+$/"
32
+ : "/\\.(?:test|spec)s?\\.[^.]+$/";
33
+
34
+ const content = `{
35
+ const ctx = import.meta.webpackContext('/', {
36
+ recursive: true,
37
+ regExp: ${regExp},
38
+ exclude: ${excludeFoldersRegex.toString()},
39
+ mode: 'eager',
40
+ });
41
+ ctx.keys().forEach(ctx);
42
+ }`;
43
+
44
+ fs.writeFileSync(filePath, content);
45
+ return filePath;
46
+ };
47
+
48
+ module.exports = {
49
+ generateEagerTestFile,
50
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meteorjs/rspack",
3
- "version": "0.0.49",
3
+ "version": "0.0.51",
4
4
  "description": "Configuration logic for using Rspack in Meteor projects",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/rspack.config.js CHANGED
@@ -8,6 +8,8 @@ const { cleanOmittedPaths, mergeSplitOverlap } = require("./lib/mergeRulesSplitO
8
8
  const { getMeteorAppSwcConfig } = require('./lib/swc.js');
9
9
  const HtmlRspackPlugin = require('./plugins/HtmlRspackPlugin.js');
10
10
  const { RequireExternalsPlugin } = require('./plugins/RequireExtenalsPlugin.js');
11
+ const { createIgnoreFoldersRegex, getMeteorIgnoreEntries } = require("./lib/ignore.js");
12
+ const { generateEagerTestFile } = require("./lib/test.js");
11
13
 
12
14
  // Safe require that doesn't throw if the module isn't found
13
15
  function safeRequire(moduleName) {
@@ -52,7 +54,7 @@ function createSwcConfig({
52
54
  const defaultConfig = {
53
55
  jsc: {
54
56
  baseUrl: process.cwd(),
55
- paths: { '/*': ['*'] },
57
+ paths: { '/*': ['*', '/*'] },
56
58
  parser: {
57
59
  syntax: isTypescriptEnabled ? 'typescript' : 'ecmascript',
58
60
  ...(isTsxEnabled && { tsx: true }),
@@ -137,7 +139,8 @@ module.exports = async function (inMeteor = {}, argv = {}) {
137
139
  const swcExternalHelpers = !!Meteor.swcExternalHelpers;
138
140
  const isNative = !!Meteor.isNative;
139
141
  const mode = isProd ? 'production' : 'development';
140
- const projectConfigPath = Meteor.projectConfigPath || path.resolve(process.cwd(), 'rspack.config.js');
142
+ const projectDir = process.cwd();
143
+ const projectConfigPath = Meteor.projectConfigPath || path.resolve(projectDir, 'rspack.config.js');
141
144
 
142
145
  const isTypescriptEnabled = Meteor.isTypescriptEnabled || false;
143
146
  const isJsxEnabled =
@@ -368,11 +371,12 @@ module.exports = async function (inMeteor = {}, argv = {}) {
368
371
  experiments: { css: true },
369
372
  };
370
373
 
374
+
371
375
  const serverEntry =
372
376
  isTest && isTestEager && isTestFullApp
373
- ? path.resolve(process.cwd(), 'node_modules/@meteorjs/rspack/entries/eager-app-tests.mjs')
377
+ ? generateEagerTestFile({ isAppTest: true, projectDir })
374
378
  : isTest && isTestEager
375
- ? path.resolve(process.cwd(), 'node_modules/@meteorjs/rspack/entries/eager-tests.mjs')
379
+ ? generateEagerTestFile({ isAppTest: false, projectDir })
376
380
  : path.resolve(process.cwd(), buildContext, entryPath);
377
381
  const serverNameConfig = `[${(isTest && 'test-') || ''}${
378
382
  (isTestModule && 'module') || 'server'
@@ -1,9 +0,0 @@
1
- {
2
- const ctx = import.meta.webpackContext('/', {
3
- recursive: true,
4
- regExp: /\.app-(?:test|spec)s?\.[^.]+$/,
5
- exclude: /(^|\/)(node_modules|\.meteor|_build)(\/|$)/,
6
- mode: 'eager',
7
- });
8
- ctx.keys().forEach(ctx);
9
- }
@@ -1,9 +0,0 @@
1
- {
2
- const ctx = import.meta.webpackContext('/', {
3
- recursive: true,
4
- regExp: /\.(?:test|spec)s?\.[^.]+$/,
5
- exclude: /(^|\/)(node_modules|\.meteor|_build)(\/|$)/,
6
- mode: 'eager',
7
- });
8
- ctx.keys().forEach(ctx);
9
- }