Open sohnjunior opened 6 months ago
Investigation:
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["exports"], factory);
} else if (typeof exports !== "undefined") {
factory(exports);
} else {
var mod = {
exports: {}
};
factory(mod.exports);
global.repl = mod.exports;
}
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) {
"use strict";
'use client';
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.ClientComponent = ClientComponent;
function ClientComponent() {
return 'Hello world';
}
});
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
// @module: umd
'use client';
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientComponent = void 0;
function ClientComponent() {
return 'Hello world';
}
exports.ClientComponent = ClientComponent;
});
The
use strict
directive must be inside the UMD function and not outside, because UMD is safe to be used with simple file concatenation and thus directives at the top of the files would risk getting lost (and just transformed into normal string expression statements)from @nicolo-ribaudo (https://x.com/NicoloRibaudo/status/1767871497400373272)
I fully agree with this statement. For UMD (as well as similar AMD and SystemJS), the actual module code resides within its function body segment. Given that the toolchain needs to accommodate more generic logic, we don't want to mess with how things currently work.
In the case of UMD, there is a common expectation that it can be easily concatenated together. In such scenarios, we want directives to only affect the code inside the module, rather than the global code.
The root of this issue lies in the differences between toolchain's expectations of directives and how React perceives directives. Within React, directives need to be at the file level and must be at the top of the file to take effect. Conversely, in the toolchain's perspective, directives function at the block level and can be safely relocated to their new scope during the transformation process.
This misalignment of expectations has led to several challenges. We've got a few ways to tackle it:
Thank you for your feedback. Fortunately, I identified that I no longer needed to build modules with UMD in my environment, so I decided to adopt the CJS modular approach.
Describe the bug
The 'use client' directive is defined inside the factory function.
Perhaps because of this, an error saying 'use client directive does not exist' is occurring in the Next.js environment that uses the App directory.
This issue is related with #7315
Input code
No response
Config
No response
Playground link (or link to the minimal reproduction)
https://play.swc.rs/?version=1.3.100&code=H4sIAAAAAAAAAx3LMQqAMAxG4T2n%2BLfqYg%2Fg2MV71AiFmpQ2RUG8u8XtwcfzHklKt8Uaud4YMScWcysR30Wr4egSLakg%2FBL0LCojphkPAZWtV4HbOGfFpTXvY37pA1C%2FhblZAAAA&config=H4sIAAAAAAAAA1WPSw7DIAwF95wCed1tN71DD4GIE1GFj2wjFUW5eyGFtNnh98YMbEpreLGFh97qsQ7JECOdc024BDHvmoCUhGzJJYHbaIVbNZuV8Yj2bwNiaEFpW8j3jsMaI%2BPAe%2BZdcHP5F9roEyHzFWyoCcuKV53qSvBxykfZP9Ie2%2FTZT%2FCDhuy8GBw%2Fx6ZQRrV%2FAL%2FpEOoUAQAA
SWC Info output
No response
Expected behavior
The 'use client' directive is kept at the top of the file.
Actual behavior
No response
Version
1.3.101
Additional context
No response