diff --git a/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs b/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs index fbf3ef6890e..2618261e385 100644 --- a/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs +++ b/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs @@ -110,6 +110,10 @@ pub(crate) async fn resolve_loader( description_data, .. } = resource; + // Pitfall: `Path::ends_with` is different from `str::ends_with` + // So we need to convert `PathBuf` to `&str` + // Use `str::ends_with` instead of `Path::extension` to avoid unnecessary allocation + let path = path.as_str(); let r#type = if path.ends_with(".mjs") { Some("module") diff --git a/packages/rspack/src/loader-runner/index.ts b/packages/rspack/src/loader-runner/index.ts index 7499f0accd9..216db5d4e48 100644 --- a/packages/rspack/src/loader-runner/index.ts +++ b/packages/rspack/src/loader-runner/index.ts @@ -105,7 +105,9 @@ function createLoaderObject( obj.ident = ident; } - obj.type = value.type; + // CHANGE: `rspack_core` returns empty string for `undefined` type. + // Comply to webpack test case: tests/webpack-test/cases/loaders/cjs-loader-type/index.js + obj.type = value.type === "" ? undefined : value.type; if (obj.options === null) obj.query = ""; else if (obj.options === undefined) obj.query = ""; else if (typeof obj.options === "string") obj.query = `?${obj.options}`; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/index.js b/tests/webpack-test/cases/loaders/cjs-loader-type/index.js new file mode 100644 index 00000000000..876b8ca7369 --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/index.js @@ -0,0 +1,15 @@ +it("should pass package.json type to loader", function () { + expect(require("cjs/loader.js!")).toBe("commonjs"); + expect(require("./loader.js!")).toBe("undefined"); +}); + +it("should pass 'commonjs' type to loader for .cjs", function () { + expect(require("cjs/loader.cjs!")).toBe("commonjs"); + expect(require("./loader.cjs!")).toBe("commonjs"); + // ORIGINAL WEBPACK COMMENT: TODO need fix in v8 https://github.com/nodejs/node/issues/35889 + // ORIGINAL WEBPACK COMMENT: TODO otherwise this test case cause segment fault + // Turned on this as rspack checks extensions for loader type. + // So this will not fall into dynamic import which causes segment fault. + // See: crates/rspack_binding_options/src/plugins/js_loader/resolver.rs + expect(require("esm/loader.cjs!")).toBe("commonjs"); +}); diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/loader.cjs b/tests/webpack-test/cases/loaders/cjs-loader-type/loader.cjs new file mode 100644 index 00000000000..94974dcfad5 --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/loader.js b/tests/webpack-test/cases/loaders/cjs-loader-type/loader.js new file mode 100644 index 00000000000..94974dcfad5 --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json new file mode 100644 index 00000000000..5b56c70baa3 --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json @@ -0,0 +1,4 @@ +{ + "name": "cjs-package", + "type": "commonjs" +} diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/package.json b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/package.json new file mode 100644 index 00000000000..64069d2b941 --- /dev/null +++ b/tests/webpack-test/cases/loaders/cjs-loader-type/node_modules/esm/package.json @@ -0,0 +1,4 @@ +{ + "name": "esm-package", + "type": "module" +}