diff --git a/README.md b/README.md
index df7666ee..c5e0dae5 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
Babel Loader
-This package allows transpiling JavaScript files using [Babel](https://github.com/babel/babel) and [webpack](https://github.com/webpack/webpack).
+This package allows transpiling JavaScript files using [Babel](https://github.com/babel/babel) together with [webpack](https://github.com/webpack/webpack) or [Rspack](https://github.com/web-infra-dev/rspack).
**Note**: Issues with the output should be reported on the Babel [Issues](https://github.com/babel/babel/issues) tracker.
diff --git a/package.json b/package.json
index 59cd6ab7..f0bc6093 100644
--- a/package.json
+++ b/package.json
@@ -14,13 +14,23 @@
},
"peerDependencies": {
"@babel/core": "^7.12.0 || ^8.0.0-beta.1",
+ "@rspack/core": "^1.0.0 || ^2.0.0-0",
"webpack": ">=5.61.0"
},
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ },
"devDependencies": {
"@babel/cli": "^8.0.0-beta.1",
"@babel/core": "^8.0.0-beta.1",
"@babel/eslint-parser": "^8.0.0-beta.1",
"@babel/preset-env": "^8.0.0-beta.1",
+ "@rspack/core": "^1.7.5",
"c8": "^10.1.2",
"eslint": "^9.6.0",
"eslint-config-prettier": "^9.1.0",
diff --git a/test/cache.test.js b/test/cache.test.js
index eb7b4efe..3a265bc8 100644
--- a/test/cache.test.js
+++ b/test/cache.test.js
@@ -2,7 +2,7 @@ import test from "node:test";
import fs from "node:fs";
import path from "node:path";
import assert from "node:assert/strict";
-import { webpackAsync } from "./helpers/webpackAsync.js";
+import { bundlers } from "./helpers/bundlers.js";
import createTestDirectory from "./helpers/createTestDirectory.js";
import { fileURLToPath } from "node:url";
@@ -13,7 +13,6 @@ const defaultCacheDir = path.join(
"../node_modules/.cache/babel-loader",
);
const cacheDir = path.join(__dirname, "output/cache/cachefiles");
-const outputDir = path.join(__dirname, "output/cache");
const babelLoader = path.join(__dirname, "../lib");
const globalConfig = {
@@ -30,204 +29,94 @@ const globalConfig = {
},
};
-// Cache filename is either SHA256 or MD5 hash
-const UNCOMPRESSED_CACHE_FILE_REGEX = /^[0-9a-f]{32}(?:[0-9a-f]{32})?\.json$/;
-const CACHE_FILE_REGEX = /^[0-9a-f]{32}(?:[0-9a-f]{32})?\.json\.gz$/;
+// Cache filename is a hex hash. webpack and rspack may use different lengths.
+const UNCOMPRESSED_CACHE_FILE_REGEX = /^[0-9a-f]{16,64}\.json$/;
+const CACHE_FILE_REGEX = /^[0-9a-f]{16,64}\.json\.gz$/;
-// Create a separate directory for each test so that the tests
-// can run in parallel
+function defineCacheTests(bundler) {
+ const outputDir = path.join(__dirname, "output/cache", bundler.name);
-const context = { directory: undefined, cacheDirectory: undefined };
+ // Create a separate directory for each test so that the tests
+ // can run in parallel
-test.beforeEach(async t => {
- const directory = await createTestDirectory(outputDir, t.name);
- context.directory = directory;
- const cacheDirectory = await createTestDirectory(cacheDir, t.name);
- context.cacheDirectory = cacheDirectory;
-});
-test.beforeEach(() =>
- fs.rmSync(defaultCacheDir, { recursive: true, force: true }),
-);
-test.afterEach(() => {
- fs.rmSync(context.directory, { recursive: true, force: true });
- fs.rmSync(context.cacheDirectory, { recursive: true, force: true });
-});
-
-test("should output files to cache directory", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: context.cacheDirectory,
- presets: ["@babel/preset-env"],
- },
- },
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ const context = { directory: undefined, cacheDirectory: undefined };
- const files = fs.readdirSync(context.cacheDirectory);
- assert.ok(files.length > 0);
-});
-
-test("should output json.gz files to standard cache dir by default", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: true,
- presets: ["@babel/preset-env"],
- },
- },
- ],
- },
+ test.beforeEach(async t => {
+ const directory = await createTestDirectory(outputDir, t.name);
+ context.directory = directory;
+ const cacheDirectory = await createTestDirectory(cacheDir, t.name);
+ context.cacheDirectory = cacheDirectory;
});
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- let files = fs.readdirSync(defaultCacheDir);
- files = files.filter(file => CACHE_FILE_REGEX.test(file));
- assert.ok(files.length > 0);
-});
-
-test("should output non-compressed files to standard cache dir when cacheCompression is set to false", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: true,
- cacheCompression: false,
- presets: ["@babel/preset-env"],
- },
- },
- ],
- },
+ test.beforeEach(() =>
+ fs.rmSync(defaultCacheDir, { recursive: true, force: true }),
+ );
+ test.afterEach(() => {
+ fs.rmSync(context.directory, { recursive: true, force: true });
+ fs.rmSync(context.cacheDirectory, { recursive: true, force: true });
});
+ // This test validates strict cache-hit behavior, which currently matches
+ // webpack. Rspack's cache behavior differs for this plugin scenario.
+ const strictCacheHitTest = bundler.name === "webpack" ? test : test.skip;
- await webpackAsync(config);
- let files = fs.readdirSync(defaultCacheDir);
- files = files.filter(file => UNCOMPRESSED_CACHE_FILE_REGEX.test(file));
- assert.ok(files.length > 0);
-});
-
-test("should output files to standard cache dir if set to true in query", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: true,
- presets: ["@babel/preset-env"],
+ test("should output files to cache directory", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: context.cacheDirectory,
+ presets: ["@babel/preset-env"],
+ },
},
- },
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ ],
+ },
+ });
- let files = fs.readdirSync(defaultCacheDir);
- files = files.filter(file => CACHE_FILE_REGEX.test(file));
- assert.ok(files.length > 0);
-});
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
-test("should read from cache directory if cached file exists", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: context.cacheDirectory,
- presets: ["@babel/preset-env"],
- },
- },
- ],
- },
+ const files = fs.readdirSync(context.cacheDirectory);
+ assert.ok(files.length > 0);
});
- // @TODO Find a way to know if the file as correctly read without relying on
- // Istanbul for coverage.
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- await webpackAsync(config);
- const files = fs.readdirSync(context.cacheDirectory);
- assert.ok(files.length > 0);
-});
-
-test("should have one file per module", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: context.cacheDirectory,
- presets: ["@babel/preset-env"],
+ test("should output json.gz files to standard cache dir by default", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: true,
+ presets: ["@babel/preset-env"],
+ },
},
- },
- ],
- },
- });
+ ],
+ },
+ });
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
- const files = fs.readdirSync(context.cacheDirectory);
- assert.strictEqual(files.length, 3);
-});
+ let files = fs.readdirSync(defaultCacheDir);
+ files = files.filter(file => CACHE_FILE_REGEX.test(file));
+ assert.ok(files.length > 0);
+ });
-test("should generate a new file if the identifier changes", async () => {
- const configs = [
- Object.assign({}, globalConfig, {
+ test("should output non-compressed files to standard cache dir when cacheCompression is set to false", async () => {
+ const config = Object.assign({}, globalConfig, {
output: {
path: context.directory,
},
@@ -238,15 +127,23 @@ test("should generate a new file if the identifier changes", async () => {
loader: babelLoader,
exclude: /node_modules/,
options: {
- cacheDirectory: context.cacheDirectory,
- cacheIdentifier: "a",
+ cacheDirectory: true,
+ cacheCompression: false,
presets: ["@babel/preset-env"],
},
},
],
},
- }),
- Object.assign({}, globalConfig, {
+ });
+
+ await bundler.compileAsync(config);
+ let files = fs.readdirSync(defaultCacheDir);
+ files = files.filter(file => UNCOMPRESSED_CACHE_FILE_REGEX.test(file));
+ assert.ok(files.length > 0);
+ });
+
+ test("should output files to standard cache dir if set to true in query", async () => {
+ const config = Object.assign({}, globalConfig, {
output: {
path: context.directory,
},
@@ -257,32 +154,25 @@ test("should generate a new file if the identifier changes", async () => {
loader: babelLoader,
exclude: /node_modules/,
options: {
- cacheDirectory: context.cacheDirectory,
- cacheIdentifier: "b",
+ cacheDirectory: true,
presets: ["@babel/preset-env"],
},
},
],
},
- }),
- ];
-
- await Promise.allSettled(
- configs.map(async config => {
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
- }),
- );
+ });
- const files = fs.readdirSync(context.cacheDirectory);
- assert.strictEqual(files.length, 6);
-});
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ let files = fs.readdirSync(defaultCacheDir);
+ files = files.filter(file => CACHE_FILE_REGEX.test(file));
+ assert.ok(files.length > 0);
+ });
-test("should allow to specify the .babelrc file", async () => {
- const config = [
- Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/constant.js"),
+ test("should read from cache directory if cached file exists", async () => {
+ const config = Object.assign({}, globalConfig, {
output: {
path: context.directory,
},
@@ -294,16 +184,26 @@ test("should allow to specify the .babelrc file", async () => {
exclude: /node_modules/,
options: {
cacheDirectory: context.cacheDirectory,
- extends: path.join(__dirname, "fixtures/babelrc"),
- babelrc: false,
presets: ["@babel/preset-env"],
},
},
],
},
- }),
- Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/constant.js"),
+ });
+
+ // @TODO Find a way to know if the file as correctly read without relying on
+ // Istanbul for coverage.
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ await bundler.compileAsync(config);
+ const files = fs.readdirSync(context.cacheDirectory);
+ assert.ok(files.length > 0);
+ });
+
+ test("should have one file per module", async () => {
+ const config = Object.assign({}, globalConfig, {
output: {
path: context.directory,
},
@@ -320,114 +220,230 @@ test("should allow to specify the .babelrc file", async () => {
},
],
},
- }),
- ];
- const multiStats = await webpackAsync(config);
- assert.deepEqual(multiStats.stats[0].compilation.errors, []);
- assert.deepEqual(multiStats.stats[0].compilation.warnings, []);
- assert.deepEqual(multiStats.stats[1].compilation.errors, []);
- assert.deepEqual(multiStats.stats[1].compilation.warnings, []);
-
- const files = fs.readdirSync(context.cacheDirectory);
- // The two configs resolved to same Babel config because "fixtures/babelrc"
- // is { "presets": ["@babel/preset-env"] }
- assert.strictEqual(files.length, 1);
-});
-
-test("should cache result when there are external dependencies", async () => {
- const dep = path.join(cacheDir, "externalDependency.txt");
-
- fs.writeFileSync(dep, "first update");
-
- let counter = 0;
-
- const config = Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/constant.js"),
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: babelLoader,
- options: {
- babelrc: false,
- configFile: false,
- cacheDirectory: context.cacheDirectory,
- plugins: [
- api => {
- api.cache.never();
- api.addExternalDependency(dep);
- return {
- visitor: {
- BooleanLiteral(path) {
- counter++;
- path.replaceWith(
- api.types.stringLiteral(fs.readFileSync(dep, "utf8")),
- );
- path.stop();
- },
- },
- };
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.cacheDirectory);
+ assert.strictEqual(files.length, 3);
+ });
+
+ test("should generate a new file if the identifier changes", async () => {
+ const configs = [
+ Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: context.cacheDirectory,
+ cacheIdentifier: "a",
+ presets: ["@babel/preset-env"],
},
- ],
- },
+ },
+ ],
},
- ],
- },
+ }),
+ Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: context.cacheDirectory,
+ cacheIdentifier: "b",
+ presets: ["@babel/preset-env"],
+ },
+ },
+ ],
+ },
+ }),
+ ];
+
+ await Promise.allSettled(
+ configs.map(async config => {
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+ }),
+ );
+
+ const files = fs.readdirSync(context.cacheDirectory);
+ assert.strictEqual(files.length, 6);
+ });
+
+ test("should allow to specify the .babelrc file", async () => {
+ const config = [
+ Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/constant.js"),
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: context.cacheDirectory,
+ extends: path.join(__dirname, "fixtures/babelrc"),
+ babelrc: false,
+ presets: ["@babel/preset-env"],
+ },
+ },
+ ],
+ },
+ }),
+ Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/constant.js"),
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: context.cacheDirectory,
+ presets: ["@babel/preset-env"],
+ },
+ },
+ ],
+ },
+ }),
+ ];
+ const multiStats = await bundler.compileAsync(config);
+ assert.equal(multiStats.stats[0].compilation.errors.length, 0);
+ assert.equal(multiStats.stats[0].compilation.warnings.length, 0);
+ assert.equal(multiStats.stats[1].compilation.errors.length, 0);
+ assert.equal(multiStats.stats[1].compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.cacheDirectory);
+ // The two configs resolved to same Babel config because "fixtures/babelrc"
+ // is { "presets": ["@babel/preset-env"] }
+ assert.strictEqual(files.length, 1);
});
- let stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.warnings, []);
- assert.deepEqual(stats.compilation.errors, []);
+ strictCacheHitTest(
+ "should cache result when there are external dependencies",
+ async () => {
+ const dep = path.join(cacheDir, "externalDependency.txt");
- assert.ok(stats.compilation.fileDependencies.has(dep));
- assert.strictEqual(counter, 1);
+ fs.writeFileSync(dep, "first update");
- stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.warnings, []);
- assert.deepEqual(stats.compilation.errors, []);
+ let counter = 0;
- assert.ok(stats.compilation.fileDependencies.has(dep));
- assert.strictEqual(counter, 1);
+ const config = Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/constant.js"),
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ loader: babelLoader,
+ options: {
+ babelrc: false,
+ configFile: false,
+ cacheDirectory: context.cacheDirectory,
+ plugins: [
+ api => {
+ api.cache.never();
+ api.addExternalDependency(dep);
+ return {
+ visitor: {
+ BooleanLiteral(path) {
+ counter++;
+ path.replaceWith(
+ api.types.stringLiteral(
+ fs.readFileSync(dep, "utf8"),
+ ),
+ );
+ path.stop();
+ },
+ },
+ };
+ },
+ ],
+ },
+ },
+ ],
+ },
+ });
+
+ let stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.warnings.length, 0);
+ assert.equal(stats.compilation.errors.length, 0);
+
+ assert.ok(stats.compilation.fileDependencies.has(dep));
+ assert.strictEqual(counter, 1);
+
+ stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.warnings.length, 0);
+ assert.equal(stats.compilation.errors.length, 0);
+
+ assert.ok(stats.compilation.fileDependencies.has(dep));
+ assert.strictEqual(counter, 1);
- fs.writeFileSync(dep, "second update");
- stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.warnings, []);
- assert.deepEqual(stats.compilation.errors, []);
+ fs.writeFileSync(dep, "second update");
- assert.ok(stats.compilation.fileDependencies.has(dep));
- assert.strictEqual(counter, 2);
-});
+ stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.warnings.length, 0);
+ assert.equal(stats.compilation.errors.length, 0);
-test("should output debug logs when stats.loggingDebug includes babel-loader", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
+ assert.ok(stats.compilation.fileDependencies.has(dep));
+ assert.strictEqual(counter, 2);
},
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- cacheDirectory: true,
- presets: ["@babel/preset-env"],
+ );
+
+ test("should output debug logs when stats.loggingDebug includes babel-loader", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ cacheDirectory: true,
+ presets: ["@babel/preset-env"],
+ },
},
- },
- ],
- },
- stats: {
- loggingDebug: ["babel-loader"],
- },
- });
+ ],
+ },
+ stats: {
+ loggingDebug: ["babel-loader"],
+ },
+ });
- const stats = await webpackAsync(config);
+ const stats = await bundler.compileAsync(config);
- assert.match(
- stats.toString(config.stats),
- /normalizing loader options\n\s+resolving Babel configs\n\s+cache is enabled\n\s+reading cache file.+\n\s+discarded cache as it can not be read\n\s+creating cache folder.+\n\s+applying Babel transform\n\s+writing result to cache file.+\n\s+added '.+babel.config.json' to webpack dependencies/,
- );
-});
+ assert.match(
+ stats.toString(config.stats),
+ /normalizing loader options\n\s+resolving Babel configs\n\s+cache is enabled\n\s+reading cache file.+\n\s+discarded cache as it can not be read\n\s+creating cache folder.+\n\s+applying Babel transform\n\s+writing result to cache file.+\n\s+added '.+babel.config.json' to webpack dependencies/,
+ );
+ });
+}
+
+for (const bundler of bundlers) {
+ test.describe(bundler.name, () => defineCacheTests(bundler));
+}
diff --git a/test/helpers/bundlers.js b/test/helpers/bundlers.js
new file mode 100644
index 00000000..b77ae94e
--- /dev/null
+++ b/test/helpers/bundlers.js
@@ -0,0 +1,14 @@
+import webpack from "webpack";
+import { rspack } from "@rspack/core";
+import { promisify } from "node:util";
+
+export const bundlers = [
+ {
+ name: "webpack",
+ compileAsync: promisify(webpack),
+ },
+ {
+ name: "rspack",
+ compileAsync: promisify(rspack),
+ },
+];
diff --git a/test/helpers/webpackAsync.js b/test/helpers/webpackAsync.js
deleted file mode 100644
index 247d41b9..00000000
--- a/test/helpers/webpackAsync.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import webpack from "webpack";
-import { promisify } from "node:util";
-export const webpackAsync = promisify(webpack);
diff --git a/test/loader.test.js b/test/loader.test.js
index 6dfc9a69..481dcc0c 100644
--- a/test/loader.test.js
+++ b/test/loader.test.js
@@ -4,12 +4,11 @@ import fs from "node:fs";
import path from "node:path";
import { satisfies } from "semver";
import createTestDirectory from "./helpers/createTestDirectory.js";
-import { webpackAsync } from "./helpers/webpackAsync.js";
+import { bundlers } from "./helpers/bundlers.js";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
-const outputDir = path.join(__dirname, "output/loader");
const babelLoader = path.join(__dirname, "../lib");
const globalConfig = {
mode: "development",
@@ -51,188 +50,196 @@ const globalConfig = {
},
};
-// Create a separate directory for each test so that the tests
-// can run in parallel
-const context = { directory: undefined };
-test.beforeEach(async t => {
- const directory = await createTestDirectory(outputDir, t.name);
- context.directory = directory;
-});
-
-test.afterEach(() =>
- fs.rmSync(context.directory, { recursive: true, force: true }),
-);
-
-test("should transpile the code snippet", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- });
+for (const bundler of bundlers) {
+ test.describe(bundler.name, () => {
+ const outputDir = path.join(__dirname, "output/loader", bundler.name);
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ // Create a separate directory for each test so that the tests
+ // can run in parallel
+ const context = { directory: undefined };
+ test.beforeEach(async t => {
+ const directory = await createTestDirectory(outputDir, t.name);
+ context.directory = directory;
+ });
- const files = fs.readdirSync(context.directory);
- assert.ok(files.length === 1);
+ test.afterEach(() =>
+ fs.rmSync(context.directory, { recursive: true, force: true }),
+ );
- const test = /var App = .*(?:_createClass\()?function App\(arg\)/;
- const subject = fs.readFileSync(
- path.resolve(context.directory, files[0]),
- "utf8",
- );
+ test("should transpile the code snippet", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ });
- assert.match(subject, test);
-});
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
-test("should not throw error on syntax error", async () => {
- const config = Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/syntax.js"),
- output: {
- path: context.directory,
- },
- });
+ const files = fs.readdirSync(context.directory);
+ assert.ok(files.length === 1);
- const stats = await webpackAsync(config);
- assert.ok(stats.compilation.errors.length === 1);
- assert.ok(stats.compilation.errors[0] instanceof Error);
- assert.deepEqual(stats.compilation.warnings, []);
-});
-
-test("should not throw without config", async () => {
- const config = {
- mode: "development",
- entry: path.join(__dirname, "fixtures/basic.js"),
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- use: babelLoader,
- exclude: /node_modules/,
+ const test = /var App = .*(?:_createClass\()?function App\(arg\)/;
+ const subject = fs.readFileSync(
+ path.resolve(context.directory, files[0]),
+ "utf8",
+ );
+
+ assert.match(subject, test);
+ });
+
+ test("should not throw error on syntax error", async () => {
+ const config = Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/syntax.js"),
+ output: {
+ path: context.directory,
},
- ],
- },
- };
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-});
-
-test("should return compilation errors with the message included in the stack trace", async () => {
- const config = Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/syntax.js"),
- output: {
- path: context.directory,
- },
- });
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.warnings, []);
- const moduleBuildError = stats.compilation.errors[0];
- const babelLoaderError = moduleBuildError.error;
- assert.match(babelLoaderError.stack, /Unexpected token/);
-});
-
-test("should load ESM config files", async () => {
- const config = Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/constant.js"),
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- // Use relative path starting with a dot to satisfy module loader.
- // https://github.com/nodejs/node/issues/31710
- // File urls doesn't work with current resolve@1.12.0 package.
- extends: (
- "." +
- path.sep +
- path.relative(
- process.cwd(),
- path.resolve(__dirname, "fixtures/babelrc.mjs"),
- )
- ).replace(/\\/g, "/"),
- babelrc: false,
- },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.ok(stats.compilation.errors.length === 1);
+ assert.ok(stats.compilation.errors[0] instanceof Error);
+ assert.equal(stats.compilation.warnings.length, 0);
+ });
+
+ test("should not throw without config", async () => {
+ const config = {
+ mode: "development",
+ entry: path.join(__dirname, "fixtures/basic.js"),
+ output: {
+ path: context.directory,
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- // Node supports ESM without a flag starting from 12.13.0 and 13.2.0.
- if (satisfies(process.version, `^12.13.0 || >=13.2.0`)) {
- assert.deepEqual(
- stats.compilation.errors.map(e => e.message),
- [],
- );
- } else {
- assert.strictEqual(stats.compilation.errors.length, 1);
- const moduleBuildError = stats.compilation.errors[0];
- const babelLoaderError = moduleBuildError.error;
- assert.ok(babelLoaderError instanceof Error);
- // Error messages are slightly different between versions:
- // "modules aren't supported" or "modules not supported".
- assert.match(babelLoaderError.message, /supported/i);
- }
- assert.deepEqual(stats.compilation.warnings, []);
-});
-
-test("should track external dependencies", async () => {
- const dep = path.join(__dirname, "fixtures/metadata.js");
- const config = Object.assign({}, globalConfig, {
- entry: path.join(__dirname, "fixtures/constant.js"),
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: babelLoader,
- options: {
- babelrc: false,
- configFile: false,
- plugins: [
- api => {
- api.cache.never();
- api.addExternalDependency(dep);
- return { visitor: {} };
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ use: babelLoader,
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ };
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+ });
+
+ test("should return compilation errors with the message included in the stack trace", async () => {
+ const config = Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/syntax.js"),
+ output: {
+ path: context.directory,
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.warnings.length, 0);
+ const moduleBuildError = stats.compilation.errors[0];
+ const babelLoaderError = moduleBuildError.error;
+ assert.match(
+ babelLoaderError.stack ?? moduleBuildError.message,
+ /Unexpected token/,
+ );
+ });
+
+ test("should load ESM config files", async () => {
+ const config = Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/constant.js"),
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ // Use relative path starting with a dot to satisfy module loader.
+ // https://github.com/nodejs/node/issues/31710
+ // File urls doesn't work with current resolve@1.12.0 package.
+ extends: (
+ "." +
+ path.sep +
+ path.relative(
+ process.cwd(),
+ path.resolve(__dirname, "fixtures/babelrc.mjs"),
+ )
+ ).replace(/\\/g, "/"),
+ babelrc: false,
},
- ],
- },
+ },
+ ],
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.ok(stats.compilation.fileDependencies.has(dep));
- assert.deepEqual(stats.compilation.warnings, []);
-});
-
-test("should output debug logs when stats.loggingDebug includes babel-loader", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- stats: {
- loggingDebug: ["babel-loader"],
- },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ // Node supports ESM without a flag starting from 12.13.0 and 13.2.0.
+ if (satisfies(process.version, `^12.13.0 || >=13.2.0`)) {
+ assert.deepEqual(
+ stats.compilation.errors.map(e => e.message),
+ [],
+ );
+ } else {
+ assert.strictEqual(stats.compilation.errors.length, 1);
+ const moduleBuildError = stats.compilation.errors[0];
+ const babelLoaderError = moduleBuildError.error;
+ assert.ok(babelLoaderError instanceof Error);
+ // Error messages are slightly different between versions:
+ // "modules aren't supported" or "modules not supported".
+ assert.match(babelLoaderError.message, /supported/i);
+ }
+ assert.equal(stats.compilation.warnings.length, 0);
+ });
+
+ test("should track external dependencies", async () => {
+ const dep = path.join(__dirname, "fixtures/metadata.js");
+ const config = Object.assign({}, globalConfig, {
+ entry: path.join(__dirname, "fixtures/constant.js"),
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ loader: babelLoader,
+ options: {
+ babelrc: false,
+ configFile: false,
+ plugins: [
+ api => {
+ api.cache.never();
+ api.addExternalDependency(dep);
+ return { visitor: {} };
+ },
+ ],
+ },
+ },
+ ],
+ },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.ok(stats.compilation.fileDependencies.has(dep));
+ assert.equal(stats.compilation.warnings.length, 0);
+ });
+ test("should output debug logs when stats.loggingDebug includes babel-loader", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ stats: {
+ loggingDebug: ["babel-loader"],
+ },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.match(
+ stats.toString(config.stats),
+ /normalizing loader options\n\s+resolving Babel configs\n\s+cache is disabled, applying Babel transform/,
+ );
+ });
});
-
- const stats = await webpackAsync(config);
- assert.match(
- stats.toString(config.stats),
- /normalizing loader options\n\s+resolving Babel configs\n\s+cache is disabled, applying Babel transform/,
- );
-});
+}
diff --git a/test/metadata.test.js b/test/metadata.test.js
index ee049a97..880ff900 100644
--- a/test/metadata.test.js
+++ b/test/metadata.test.js
@@ -3,14 +3,11 @@ import assert from "node:assert/strict";
import path from "node:path";
import fs from "node:fs";
import createTestDirectory from "./helpers/createTestDirectory.js";
-import { webpackAsync } from "./helpers/webpackAsync.js";
-import webpack from "webpack";
-const { NormalModule } = webpack;
+import { bundlers } from "./helpers/bundlers.js";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const cacheDir = path.join(__dirname, "output/cache/cachefiles");
-const outputDir = path.join(__dirname, "output/metadata");
const babelLoader = path.join(__dirname, "../lib");
function babelMetadataProvierPlugin() {
@@ -24,17 +21,17 @@ function babelMetadataProvierPlugin() {
};
}
-class WebpackMetadataSubscriberPlugin {
+class MetadataSubscriberPlugin {
static subscriber = Symbol("subscriber");
constructor(subscriberCallback) {
this.subscriberCallback = subscriberCallback;
}
apply(compiler) {
compiler.hooks.compilation.tap("plugin", compilation => {
- NormalModule.getCompilationHooks(compilation).loader.tap(
+ compiler.webpack.NormalModule.getCompilationHooks(compilation).loader.tap(
"plugin",
context => {
- context[WebpackMetadataSubscriberPlugin.subscriber] =
+ context[MetadataSubscriberPlugin.subscriber] =
this.subscriberCallback;
},
);
@@ -42,93 +39,95 @@ class WebpackMetadataSubscriberPlugin {
}
}
-// Create a separate directory for each test so that the tests
-// can run in parallel
-const context = { directory: undefined };
-test.beforeEach(async t => {
- const directory = await createTestDirectory(outputDir, t.name);
- context.directory = directory;
-});
+for (const bundler of bundlers) {
+ test.describe(bundler.name, () => {
+ const outputDir = path.join(__dirname, "output/metadata", bundler.name);
-test.afterEach(() =>
- fs.rmSync(context.directory, { recursive: true, force: true }),
-);
+ // Create a separate directory for each test so that the tests
+ // can run in parallel
+ const context = { directory: undefined };
+ test.beforeEach(async t => {
+ const directory = await createTestDirectory(outputDir, t.name);
+ context.directory = directory;
+ });
-test("should obtain metadata from the transform result", async () => {
- let actualMetadata;
+ test.afterEach(() =>
+ fs.rmSync(context.directory, { recursive: true, force: true }),
+ );
- const config = {
- mode: "development",
- entry: "./test/fixtures/basic.js",
- output: {
- path: context.directory,
- filename: "[id].metadata.js",
- },
- plugins: [
- new WebpackMetadataSubscriberPlugin(
- metadata => (actualMetadata = metadata),
- ),
- ],
- module: {
- rules: [
- {
- test: /\.js/,
- loader: babelLoader,
- options: {
- metadataSubscribers: [WebpackMetadataSubscriberPlugin.subscriber],
- plugins: [babelMetadataProvierPlugin],
- babelrc: false,
- configFile: false,
- },
- exclude: /node_modules/,
+ test("should obtain metadata from the transform result", async () => {
+ let actualMetadata;
+
+ const config = {
+ mode: "development",
+ entry: "./test/fixtures/basic.js",
+ output: {
+ path: context.directory,
+ filename: "[id].metadata.js",
},
- ],
- },
- };
+ plugins: [
+ new MetadataSubscriberPlugin(metadata => (actualMetadata = metadata)),
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.js/,
+ loader: babelLoader,
+ options: {
+ metadataSubscribers: [MetadataSubscriberPlugin.subscriber],
+ plugins: [babelMetadataProvierPlugin],
+ babelrc: false,
+ configFile: false,
+ },
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ };
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
- assert.deepEqual(actualMetadata, { hello: "world" });
-});
+ assert.deepEqual(actualMetadata, { hello: "world" });
+ });
-test("should obtain metadata from the transform result with cache", async () => {
- let actualMetadata;
+ test("should obtain metadata from the transform result with cache", async () => {
+ let actualMetadata;
- const config = {
- mode: "development",
- entry: "./test/fixtures/basic.js",
- output: {
- path: context.directory,
- filename: "[id].metadata.js",
- },
- plugins: [
- new WebpackMetadataSubscriberPlugin(
- metadata => (actualMetadata = metadata),
- ),
- ],
- module: {
- rules: [
- {
- test: /\.js/,
- loader: babelLoader,
- options: {
- cacheDirectory: cacheDir,
- metadataSubscribers: [WebpackMetadataSubscriberPlugin.subscriber],
- plugins: [babelMetadataProvierPlugin],
- babelrc: false,
- configFile: false,
- },
- exclude: /node_modules/,
+ const config = {
+ mode: "development",
+ entry: "./test/fixtures/basic.js",
+ output: {
+ path: context.directory,
+ filename: "[id].metadata.js",
},
- ],
- },
- };
+ plugins: [
+ new MetadataSubscriberPlugin(metadata => (actualMetadata = metadata)),
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.js/,
+ loader: babelLoader,
+ options: {
+ cacheDirectory: cacheDir,
+ metadataSubscribers: [MetadataSubscriberPlugin.subscriber],
+ plugins: [babelMetadataProvierPlugin],
+ babelrc: false,
+ configFile: false,
+ },
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ };
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
- assert.deepEqual(actualMetadata, { hello: "world" });
-});
+ assert.deepEqual(actualMetadata, { hello: "world" });
+ });
+ });
+}
diff --git a/test/options.test.js b/test/options.test.js
index acfe1121..03b5d21c 100644
--- a/test/options.test.js
+++ b/test/options.test.js
@@ -2,12 +2,11 @@ import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
-import { webpackAsync } from "./helpers/webpackAsync.js";
+import { bundlers } from "./helpers/bundlers.js";
import createTestDirectory from "./helpers/createTestDirectory.js";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
-const outputDir = path.join(__dirname, "output/options");
const babelLoader = path.join(__dirname, "../lib");
const globalConfig = {
mode: "development",
@@ -26,185 +25,207 @@ const globalConfig = {
},
};
-// Create a separate directory for each test so that the tests
-// can run in parallel
-const context = { directory: undefined };
-test.beforeEach(async t => {
- const directory = await createTestDirectory(outputDir, t.name);
- context.directory = directory;
-});
+function defineOptionsTests(bundler) {
+ const outputDir = path.join(__dirname, "output/options", bundler.name);
-test.afterEach(() =>
- fs.rmSync(context.directory, { recursive: true, force: true }),
-);
-
-test("should interpret options given to the loader", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- presets: ["@babel/env"],
- },
- },
- ],
- },
+ // Create a separate directory for each test so that the tests
+ // can run in parallel
+ const context = { directory: undefined };
+ test.beforeEach(async t => {
+ const directory = await createTestDirectory(outputDir, t.name);
+ context.directory = directory;
});
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
- const files = fs.readdirSync(outputDir);
- assert.ok(files.length > 0);
-});
+ test.afterEach(() =>
+ fs.rmSync(context.directory, { recursive: true, force: true }),
+ );
-test("should throw when options.metadataSubscribers is not an array", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- metadataSubscribers: function subscriber() {},
+ // Webpack validates loader options via `this.getOptions(schema)`.
+ // Rspack currently does not run equivalent schema validation here, so
+ // validation-specific assertions are webpack-only.
+ const schemaValidationTest = bundler.name === "webpack" ? test : test.skip;
+
+ test("should interpret options given to the loader", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ presets: ["@babel/env"],
+ },
},
+ ],
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(outputDir);
+ assert.ok(files.length > 0);
+ });
+
+ schemaValidationTest(
+ "should throw when options.metadataSubscribers is not an array",
+ async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
},
- ],
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ metadataSubscribers: function subscriber() {},
+ },
+ },
+ ],
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ const { errors } = stats.compilation;
+ assert.deepEqual(errors.length, 1);
+ const errorMessage = errors[0].message;
+ assert.match(
+ errorMessage,
+ /ValidationError: Invalid options object\. Babel Loader has been initialized using an options object that does not match the API schema\./,
+ );
+ assert.match(
+ errorMessage,
+ /options\.metadataSubscribers should be an array/,
+ );
},
- });
- const stats = await webpackAsync(config);
- const { errors } = stats.compilation;
- assert.deepEqual(errors.length, 1);
- const errorMessage = errors[0].message;
- assert.match(
- errorMessage,
- /ValidationError: Invalid options object\. Babel Loader has been initialized using an options object that does not match the API schema\./,
);
- assert.match(errorMessage, /options\.metadataSubscribers should be an array/);
-});
-test("should throw when options.customize is not a string", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- customize: true,
- },
+ schemaValidationTest(
+ "should throw when options.customize is not a string",
+ async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ customize: true,
+ },
+ },
+ ],
},
- ],
+ });
+ const stats = await bundler.compileAsync(config);
+ const { errors } = stats.compilation;
+ assert.deepEqual(errors.length, 1);
+ const errorMessage = errors[0].message;
+ assert.match(
+ errorMessage,
+ /ValidationError: Invalid options object\. Babel Loader has been initialized using an options object that does not match the API schema\./,
+ );
+ assert.match(
+ errorMessage,
+ /options\.customize should be one of these:\s null | string/,
+ );
},
- });
- const stats = await webpackAsync(config);
- const { errors } = stats.compilation;
- assert.deepEqual(errors.length, 1);
- const errorMessage = errors[0].message;
- assert.match(
- errorMessage,
- /ValidationError: Invalid options object\. Babel Loader has been initialized using an options object that does not match the API schema\./,
- );
- assert.match(
- errorMessage,
- /options\.customize should be one of these:\s null | string/,
);
-});
-test("should throw when options.customize is not an absolute path", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- customize: "./node_modules/babel-loader-customized",
+ test("should throw when options.customize is not an absolute path", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ customize: "./node_modules/babel-loader-customized",
+ },
},
- },
- ],
- },
+ ],
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ const { errors } = stats.compilation;
+ assert.deepEqual(errors.length, 1);
+ const errorMessage = errors[0].message;
+ assert.match(
+ errorMessage,
+ /Error: Customized loaders must be passed as absolute paths, since babel-loader has no way to know what they would be relative to\./,
+ );
});
- const stats = await webpackAsync(config);
- const { errors } = stats.compilation;
- assert.deepEqual(errors.length, 1);
- const errorMessage = errors[0].message;
- assert.match(
- errorMessage,
- /Error: Customized loaders must be passed as absolute paths, since babel-loader has no way to know what they would be relative to\./,
- );
-});
-test("should warn when options.babelrc is a string", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- babelrc: "./fixtures/babelrc",
+ test("should warn when options.babelrc is a string", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ babelrc: "./fixtures/babelrc",
+ },
},
- },
- ],
- },
+ ],
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ const { warnings } = stats.compilation;
+ assert.deepEqual(warnings.length, 1);
+ const warningMessage = warnings[0].message;
+ assert.match(
+ warningMessage,
+ /The option `babelrc` should not be set to a string anymore in the babel-loader config\./,
+ );
});
- const stats = await webpackAsync(config);
- const { warnings } = stats.compilation;
- assert.deepEqual(warnings.length, 1);
- const warningMessage = warnings[0].message;
- assert.match(
- warningMessage,
- /The option `babelrc` should not be set to a string anymore in the babel-loader config\./,
- );
-});
-test("should warn when options.forceEnv is set", async () => {
- const config = Object.assign({}, globalConfig, {
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- forceEnv: "production",
+ test("should warn when options.forceEnv is set", async () => {
+ const config = Object.assign({}, globalConfig, {
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ forceEnv: "production",
+ },
},
- },
- ],
- },
+ ],
+ },
+ });
+ const stats = await bundler.compileAsync(config);
+ const { warnings } = stats.compilation;
+ assert.deepEqual(warnings.length, 1);
+ const warningMessage = warnings[0].message;
+ assert.match(
+ warningMessage,
+ /The option `forceEnv` has been removed in favor of `envName` in Babel 7\./,
+ );
});
- const stats = await webpackAsync(config);
- const { warnings } = stats.compilation;
- assert.deepEqual(warnings.length, 1);
- const warningMessage = warnings[0].message;
- assert.match(
- warningMessage,
- /The option `forceEnv` has been removed in favor of `envName` in Babel 7\./,
- );
-});
+}
+
+for (const bundler of bundlers) {
+ test.describe(bundler.name, () => defineOptionsTests(bundler));
+}
diff --git a/test/sourcemaps.test.js b/test/sourcemaps.test.js
index f35b9f3a..dc543c7f 100644
--- a/test/sourcemaps.test.js
+++ b/test/sourcemaps.test.js
@@ -2,12 +2,11 @@ import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
-import { webpackAsync } from "./helpers/webpackAsync.js";
+import { bundlers } from "./helpers/bundlers.js";
import createTestDirectory from "./helpers/createTestDirectory.js";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
-const outputDir = path.join(__dirname, "output/sourcemaps");
const babelLoader = path.join(__dirname, "../lib");
const globalConfig = {
mode: "development",
@@ -23,234 +22,266 @@ const globalConfig = {
},
};
-// Create a separate directory for each test so that the tests
-// can run in parallel
-const context = { directory: undefined };
-test.beforeEach(async t => {
- const directory = await createTestDirectory(outputDir, t.name);
- context.directory = directory;
-});
-
-test.afterEach(() =>
- fs.rmSync(context.directory, { recursive: true, force: true }),
-);
-
-test("should output webpack's sourcemap", async () => {
- const config = Object.assign({}, globalConfig, {
- devtool: "source-map",
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- presets: ["@babel/env"],
- },
+for (const bundler of bundlers) {
+ test.describe(bundler.name, () => {
+ const outputDir = path.join(__dirname, "output/sourcemaps", bundler.name);
+ const sourceMapProtocols =
+ bundler.name === "rspack" ? ["rspack://", "webpack://"] : ["webpack://"];
+
+ // Create a separate directory for each test so that the tests
+ // can run in parallel
+ const context = { directory: undefined };
+ test.beforeEach(async t => {
+ const directory = await createTestDirectory(outputDir, t.name);
+ context.directory = directory;
+ });
+
+ test.afterEach(() =>
+ fs.rmSync(context.directory, { recursive: true, force: true }),
+ );
+
+ test("should output sourcemap", async () => {
+ const config = Object.assign({}, globalConfig, {
+ devtool: "source-map",
+ output: {
+ path: context.directory,
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- const files = fs.readdirSync(context.directory);
-
- const map = files.filter(file => file.includes(".map"));
-
- assert.ok(map.length > 0);
-
- const sourceMapContent = fs.readFileSync(
- path.resolve(context.directory, map[0]),
- "utf8",
- );
- assert.ok(sourceMapContent.includes("webpack://"));
-});
-
-test("should output webpack's sourcemap properly when set 'inline'", async () => {
- const config = Object.assign({}, globalConfig, {
- devtool: "source-map",
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- sourceMap: "inline",
- presets: [["@babel/env", { modules: "commonjs" }]],
- },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ presets: ["@babel/env"],
+ },
+ },
+ ],
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- const files = fs.readdirSync(context.directory);
- const map = files.filter(file => file.includes(".map"));
-
- assert.ok(map.length > 0);
-
- const data = fs.readFileSync(path.resolve(context.directory, map[0]));
- const mapObj = JSON.parse(data);
-
- const fixtureBasicIndex = mapObj.sources.indexOf(
- "webpack://babel-loader/./test/fixtures/basic.js",
- );
- // The index may vary across webpack versions
- assert.notStrictEqual(fixtureBasicIndex, -1);
-
- // Ensure that the map contains the original code, not the compiled src.
- assert.strictEqual(
- mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"),
- false,
- );
-});
-
-test("should output webpack's devtoolModuleFilename option", async () => {
- const config = Object.assign({}, globalConfig, {
- devtool: "source-map",
- output: {
- path: context.directory,
- devtoolModuleFilenameTemplate: "=!=!=!=[absolute-resource-path]=!=!=!=",
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- presets: ["@babel/env"],
- },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.directory);
+
+ const map = files.filter(file => file.includes(".map"));
+
+ assert.ok(map.length > 0);
+
+ const sourceMapContent = fs.readFileSync(
+ path.resolve(context.directory, map[0]),
+ "utf8",
+ );
+ assert.ok(
+ sourceMapProtocols.some(protocol =>
+ sourceMapContent.includes(protocol),
+ ),
+ );
+ });
+
+ test("should output sourcemap properly when set 'inline'", async () => {
+ const config = Object.assign({}, globalConfig, {
+ devtool: "source-map",
+ output: {
+ path: context.directory,
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- const files = fs.readdirSync(context.directory);
- const map = files.filter(file => file.includes(".map"));
-
- assert.ok(map.length > 0);
-
- const sourceMapContent = fs.readFileSync(
- path.resolve(context.directory, map[0]),
- "utf8",
- );
-
- assert.match(
- sourceMapContent,
- new RegExp(
- JSON.stringify(
- `=!=!=!=${globalConfig.entry.replace(
- // Webpack 5, webpack 4, windows, linux, ...
- /\\/g,
- "(?:/|\\\\)",
- )}=!=!=!=`,
- ),
- ),
- );
-});
-
-test("should disable sourcemap output with 'sourceMaps:false'", async () => {
- const config = Object.assign({}, globalConfig, {
- devtool: "source-map",
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- sourceMaps: false,
- presets: [["@babel/env", { modules: "commonjs" }]],
- },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ sourceMap: "inline",
+ presets: [["@babel/env", { modules: "commonjs" }]],
+ },
+ },
+ ],
},
- ],
- },
- });
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- const files = fs.readdirSync(context.directory);
- const map = files.filter(file => file.includes(".map"));
-
- assert.ok(map.length > 0);
-
- const data = fs.readFileSync(path.resolve(context.directory, map[0]));
- const mapObj = JSON.parse(data);
-
- const fixtureBasicIndex = mapObj.sources.indexOf(
- "webpack://babel-loader/./test/fixtures/basic.js",
- );
- // The index may vary across webpack versions
- assert.notStrictEqual(fixtureBasicIndex, -1);
-
- // Ensure that the code contains Babel's compiled output, because
- // sourcemaps from Babel are disabled.
- assert.ok(mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"));
-});
-
-test("should disable sourcemap output with 'sourceMap:false'", async () => {
- const config = Object.assign({}, globalConfig, {
- devtool: "source-map",
- output: {
- path: context.directory,
- },
- module: {
- rules: [
- {
- test: /\.jsx?/,
- loader: babelLoader,
- exclude: /node_modules/,
- options: {
- sourceMap: false,
- presets: [["@babel/env", { modules: "commonjs" }]],
- },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.directory);
+ const map = files.filter(file => file.includes(".map"));
+
+ assert.ok(map.length > 0);
+
+ const data = fs.readFileSync(path.resolve(context.directory, map[0]));
+ const mapObj = JSON.parse(data);
+
+ const fixtureBasicIndex =
+ sourceMapProtocols
+ .map(protocol =>
+ mapObj.sources.indexOf(
+ `${protocol}babel-loader/./test/fixtures/basic.js`,
+ ),
+ )
+ .find(index => index !== -1) ?? -1;
+ // The index may vary across webpack versions
+ assert.notStrictEqual(fixtureBasicIndex, -1);
+
+ // Ensure that the map contains the original code, not the compiled src.
+ assert.strictEqual(
+ mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"),
+ false,
+ );
+ });
+
+ test("should output devtoolModuleFilename option", async () => {
+ const config = Object.assign({}, globalConfig, {
+ devtool: "source-map",
+ output: {
+ path: context.directory,
+ devtoolModuleFilenameTemplate:
+ "=!=!=!=[absolute-resource-path]=!=!=!=",
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ presets: ["@babel/env"],
+ },
+ },
+ ],
+ },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.directory);
+ const map = files.filter(file => file.includes(".map"));
+
+ assert.ok(map.length > 0);
+
+ const sourceMapContent = fs.readFileSync(
+ path.resolve(context.directory, map[0]),
+ "utf8",
+ );
+
+ assert.match(
+ sourceMapContent,
+ new RegExp(
+ JSON.stringify(
+ `=!=!=!=${globalConfig.entry.replace(
+ // Webpack 5, webpack 4, windows, linux, ...
+ /\\/g,
+ "(?:/|\\\\)",
+ )}=!=!=!=`,
+ ),
+ ),
+ );
+ });
+
+ test("should disable sourcemap output with 'sourceMaps:false'", async () => {
+ const config = Object.assign({}, globalConfig, {
+ devtool: "source-map",
+ output: {
+ path: context.directory,
},
- ],
- },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ sourceMaps: false,
+ presets: [["@babel/env", { modules: "commonjs" }]],
+ },
+ },
+ ],
+ },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.directory);
+ const map = files.filter(file => file.includes(".map"));
+
+ assert.ok(map.length > 0);
+
+ const data = fs.readFileSync(path.resolve(context.directory, map[0]));
+ const mapObj = JSON.parse(data);
+
+ const fixtureBasicIndex =
+ sourceMapProtocols
+ .map(protocol =>
+ mapObj.sources.indexOf(
+ `${protocol}babel-loader/./test/fixtures/basic.js`,
+ ),
+ )
+ .find(index => index !== -1) ?? -1;
+ // The index may vary across webpack versions
+ assert.notStrictEqual(fixtureBasicIndex, -1);
+
+ // Ensure that the code contains Babel's compiled output, because
+ // sourcemaps from Babel are disabled.
+ assert.ok(
+ mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"),
+ );
+ });
+
+ test("should disable sourcemap output with 'sourceMap:false'", async () => {
+ const config = Object.assign({}, globalConfig, {
+ devtool: "source-map",
+ output: {
+ path: context.directory,
+ },
+ module: {
+ rules: [
+ {
+ test: /\.jsx?/,
+ loader: babelLoader,
+ exclude: /node_modules/,
+ options: {
+ sourceMap: false,
+ presets: [["@babel/env", { modules: "commonjs" }]],
+ },
+ },
+ ],
+ },
+ });
+
+ const stats = await bundler.compileAsync(config);
+ assert.equal(stats.compilation.errors.length, 0);
+ assert.equal(stats.compilation.warnings.length, 0);
+
+ const files = fs.readdirSync(context.directory);
+ const map = files.filter(file => file.includes(".map"));
+
+ assert.ok(map.length > 0);
+
+ const data = fs.readFileSync(path.resolve(context.directory, map[0]));
+ const mapObj = JSON.parse(data);
+
+ const fixtureBasicIndex =
+ sourceMapProtocols
+ .map(protocol =>
+ mapObj.sources.indexOf(
+ `${protocol}babel-loader/./test/fixtures/basic.js`,
+ ),
+ )
+ .find(index => index !== -1) ?? -1;
+ // The index may vary across webpack versions
+ assert.notStrictEqual(fixtureBasicIndex, -1);
+
+ // Ensure that the code contains Babel's compiled output, because
+ // sourcemaps from Babel are disabled.
+ assert.ok(
+ mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"),
+ );
+ });
});
-
- const stats = await webpackAsync(config);
- assert.deepEqual(stats.compilation.errors, []);
- assert.deepEqual(stats.compilation.warnings, []);
-
- const files = fs.readdirSync(context.directory);
- const map = files.filter(file => file.includes(".map"));
-
- assert.ok(map.length > 0);
-
- const data = fs.readFileSync(path.resolve(context.directory, map[0]));
- const mapObj = JSON.parse(data);
-
- const fixtureBasicIndex = mapObj.sources.indexOf(
- "webpack://babel-loader/./test/fixtures/basic.js",
- );
- // The index may vary across webpack versions
- assert.notStrictEqual(fixtureBasicIndex, -1);
-
- // Ensure that the code contains Babel's compiled output, because
- // sourcemaps from Babel are disabled.
- assert.ok(mapObj.sourcesContent[fixtureBasicIndex].includes("__esModule"));
-});
+}
diff --git a/yarn.lock b/yarn.lock
index 58e14bd5..65e493ff 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1178,6 +1178,34 @@ __metadata:
languageName: node
linkType: hard
+"@emnapi/core@npm:^1.5.0":
+ version: 1.8.1
+ resolution: "@emnapi/core@npm:1.8.1"
+ dependencies:
+ "@emnapi/wasi-threads": 1.1.0
+ tslib: ^2.4.0
+ checksum: 2a2fb36f4e2f90e25f419f8979435160313664bbb833d852d9de4487ff47f05fd36bf2cd77c3555f704ec2b67ce3a949ed5542598664c775cdd5ef35ae1c85a4
+ languageName: node
+ linkType: hard
+
+"@emnapi/runtime@npm:^1.5.0":
+ version: 1.8.1
+ resolution: "@emnapi/runtime@npm:1.8.1"
+ dependencies:
+ tslib: ^2.4.0
+ checksum: 0000a91d2d0ec3aaa37cbab9c360de3ff8250592f3ce4706b8c9c6d93e54151e623a8983c85543f33cb6f66cf30bb24bf0ddde466de484d6a6bf1fb2650382de
+ languageName: node
+ linkType: hard
+
+"@emnapi/wasi-threads@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@emnapi/wasi-threads@npm:1.1.0"
+ dependencies:
+ tslib: ^2.4.0
+ checksum: 6cffe35f3e407ae26236092991786db5968b4265e6e55f4664bf6f2ce0508e2a02a44ce6ebb16f2acd2f6589efb293f4f9d09cc9fbf80c00fc1a203accc94196
+ languageName: node
+ linkType: hard
+
"@eslint-community/eslint-utils@npm:^4.2.0":
version: 4.4.0
resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -1352,6 +1380,72 @@ __metadata:
languageName: node
linkType: hard
+"@module-federation/error-codes@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/error-codes@npm:0.22.0"
+ checksum: 624d9ecae4dd97394eb679ad82c9befc7ce2a0dc160c10c4c8442a84ab206a184dc5985e1cc923faef70034f680f28547ae78b7e1783e78a79c54b22e132c64d
+ languageName: node
+ linkType: hard
+
+"@module-federation/runtime-core@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/runtime-core@npm:0.22.0"
+ dependencies:
+ "@module-federation/error-codes": 0.22.0
+ "@module-federation/sdk": 0.22.0
+ checksum: cf524475bbd576325c1d2fa26fc48d61f5434eb714d5e0c74ba961ff657f07aa50daf1f55ef78f6671187218022428e17b3fd5f8d8438d315b3283c7c3cccd30
+ languageName: node
+ linkType: hard
+
+"@module-federation/runtime-tools@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/runtime-tools@npm:0.22.0"
+ dependencies:
+ "@module-federation/runtime": 0.22.0
+ "@module-federation/webpack-bundler-runtime": 0.22.0
+ checksum: 0e7693c1ec02fc5bef770b478c8757cad9cfefb2310d1943151d0ad079b72472d9b2c8a087299e9124dfcd6b649c83290c7fdfa333865baab4ba193f39e7b6bd
+ languageName: node
+ linkType: hard
+
+"@module-federation/runtime@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/runtime@npm:0.22.0"
+ dependencies:
+ "@module-federation/error-codes": 0.22.0
+ "@module-federation/runtime-core": 0.22.0
+ "@module-federation/sdk": 0.22.0
+ checksum: eca608be999d7d2e83abc1169643c2f795a5ed950f9e2bdf7000400a30b3e1e0ca4bdaa5daa09f55e44868383d444707e40236cec1aaa7b40432b0cce800b7f3
+ languageName: node
+ linkType: hard
+
+"@module-federation/sdk@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/sdk@npm:0.22.0"
+ checksum: 5f11f7032a9cb739265d6d9c93534ea70caeb1652d72afb8a6e8ea1b8cc3697943e295ad462fb8fcac2e12d5c3d7c882c2aec2b2428bb10d88b2627292543068
+ languageName: node
+ linkType: hard
+
+"@module-federation/webpack-bundler-runtime@npm:0.22.0":
+ version: 0.22.0
+ resolution: "@module-federation/webpack-bundler-runtime@npm:0.22.0"
+ dependencies:
+ "@module-federation/runtime": 0.22.0
+ "@module-federation/sdk": 0.22.0
+ checksum: a46cd5b7fba2481e4178aead6953aed9ba0be884ef2fc90ecce5356bbc8c299ff53e49c0feda10c8338eff38002c77e15d86c4747d3f7b7580d2a0de9f0510bd
+ languageName: node
+ linkType: hard
+
+"@napi-rs/wasm-runtime@npm:1.0.7":
+ version: 1.0.7
+ resolution: "@napi-rs/wasm-runtime@npm:1.0.7"
+ dependencies:
+ "@emnapi/core": ^1.5.0
+ "@emnapi/runtime": ^1.5.0
+ "@tybys/wasm-util": ^0.10.1
+ checksum: 9b59bd8b7310936ed163935befae0613dfffd563e7ff021d4f1b62b419fb0e3395f7206b17460a91db555bea6c471408f3472455e4e2ca9f5a0bff4468fa38d0
+ languageName: node
+ linkType: hard
+
"@nodelib/fs.scandir@npm:2.1.5":
version: 2.1.5
resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -1415,6 +1509,149 @@ __metadata:
languageName: node
linkType: hard
+"@rspack/binding-darwin-arm64@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-darwin-arm64@npm:1.7.5"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-darwin-x64@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-darwin-x64@npm:1.7.5"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-arm64-gnu@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-linux-arm64-gnu@npm:1.7.5"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-arm64-musl@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-linux-arm64-musl@npm:1.7.5"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-x64-gnu@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-linux-x64-gnu@npm:1.7.5"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-linux-x64-musl@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-linux-x64-musl@npm:1.7.5"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-wasm32-wasi@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-wasm32-wasi@npm:1.7.5"
+ dependencies:
+ "@napi-rs/wasm-runtime": 1.0.7
+ conditions: cpu=wasm32
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-arm64-msvc@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-win32-arm64-msvc@npm:1.7.5"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-ia32-msvc@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-win32-ia32-msvc@npm:1.7.5"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@rspack/binding-win32-x64-msvc@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding-win32-x64-msvc@npm:1.7.5"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@rspack/binding@npm:1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/binding@npm:1.7.5"
+ dependencies:
+ "@rspack/binding-darwin-arm64": 1.7.5
+ "@rspack/binding-darwin-x64": 1.7.5
+ "@rspack/binding-linux-arm64-gnu": 1.7.5
+ "@rspack/binding-linux-arm64-musl": 1.7.5
+ "@rspack/binding-linux-x64-gnu": 1.7.5
+ "@rspack/binding-linux-x64-musl": 1.7.5
+ "@rspack/binding-wasm32-wasi": 1.7.5
+ "@rspack/binding-win32-arm64-msvc": 1.7.5
+ "@rspack/binding-win32-ia32-msvc": 1.7.5
+ "@rspack/binding-win32-x64-msvc": 1.7.5
+ dependenciesMeta:
+ "@rspack/binding-darwin-arm64":
+ optional: true
+ "@rspack/binding-darwin-x64":
+ optional: true
+ "@rspack/binding-linux-arm64-gnu":
+ optional: true
+ "@rspack/binding-linux-arm64-musl":
+ optional: true
+ "@rspack/binding-linux-x64-gnu":
+ optional: true
+ "@rspack/binding-linux-x64-musl":
+ optional: true
+ "@rspack/binding-wasm32-wasi":
+ optional: true
+ "@rspack/binding-win32-arm64-msvc":
+ optional: true
+ "@rspack/binding-win32-ia32-msvc":
+ optional: true
+ "@rspack/binding-win32-x64-msvc":
+ optional: true
+ checksum: b7d4ce199b5d3d88d5841382deefcb2e5ad46b214977472b3898729978e664d3ab15844f9084abda47e9aa03b00fb3763acf6fe9fd02b9ab779dbb4ae6623019
+ languageName: node
+ linkType: hard
+
+"@rspack/core@npm:^1.7.5":
+ version: 1.7.5
+ resolution: "@rspack/core@npm:1.7.5"
+ dependencies:
+ "@module-federation/runtime-tools": 0.22.0
+ "@rspack/binding": 1.7.5
+ "@rspack/lite-tapable": 1.1.0
+ peerDependencies:
+ "@swc/helpers": ">=0.5.1"
+ peerDependenciesMeta:
+ "@swc/helpers":
+ optional: true
+ checksum: 35ebcb1d0b050327ab5fd3b92c7a1fd66929a6412ec2c08979ba7c6439fd8ab33e38a166ce06ff6f3e73ae5479e65c15b0fa95ddf97d996f72948010d1f56ee2
+ languageName: node
+ linkType: hard
+
+"@rspack/lite-tapable@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@rspack/lite-tapable@npm:1.1.0"
+ checksum: 7b74b5577cca5fb5be52bee8ce5c4415383ab84bdbb1eaa910b5a20aa3a6bbecd822c4d140239320d311153a3de56f3388c109c04da09d52d6c103c8e9439588
+ languageName: node
+ linkType: hard
+
+"@tybys/wasm-util@npm:^0.10.1":
+ version: 0.10.1
+ resolution: "@tybys/wasm-util@npm:0.10.1"
+ dependencies:
+ tslib: ^2.4.0
+ checksum: b8b281ffa9cd01cb6d45a4dddca2e28fd0cb6ad67cf091ba4a73ac87c0d6bd6ce188c332c489e87c20b0750b0b6fe3b99e30e1cd2227ec16da692f51c778944e
+ languageName: node
+ linkType: hard
+
"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
@@ -1803,6 +2040,7 @@ __metadata:
"@babel/core": ^8.0.0-beta.1
"@babel/eslint-parser": ^8.0.0-beta.1
"@babel/preset-env": ^8.0.0-beta.1
+ "@rspack/core": ^1.7.5
c8: ^10.1.2
eslint: ^9.6.0
eslint-config-prettier: ^9.1.0
@@ -1816,7 +2054,13 @@ __metadata:
webpack: ^5.93.0
peerDependencies:
"@babel/core": ^7.12.0 || ^8.0.0-beta.1
+ "@rspack/core": ^1.0.0 || ^2.0.0-0
webpack: ">=5.61.0"
+ peerDependenciesMeta:
+ "@rspack/core":
+ optional: true
+ webpack:
+ optional: true
languageName: unknown
linkType: soft
@@ -4143,6 +4387,13 @@ __metadata:
languageName: node
linkType: hard
+"tslib@npm:^2.4.0":
+ version: 2.8.1
+ resolution: "tslib@npm:2.8.1"
+ checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.6.2":
version: 2.6.3
resolution: "tslib@npm:2.6.3"