mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
When use externalType: `global` or `script` under utoopack(turbopack
only use esm or cjs external): like externalType is global , and the
external package is react.
The generate external module code like:
```ts
263: ((__turbopack_context__) => {
"use strict";
const mod = globalThis["react"];
__turbopack_context__.n(mod);
}),
```
The real function of runtime code `__turbopack_context__.n` is
`exportNamespace`, its code as follows:
```ts
module.exports = module.namespaceObject = namespace
```
And when we import the module as following:
```ts
import react from "react";
console.log(react.version);
```
it will be bundled as:
```ts
var __TURBOPACK__imported__module__263__ = __turbopack_context__.i(263);
console.log(__TURBOPACK__imported__module__263__["default"]);
```
The `__turbopack_context__i` is esmImport, it will return the module
when the module contains `namespaceObject` without `interopEsm`:
```ts
function esmImport() {
const module = getOrInstantiateModuleFromParent(id, this.m)
// any ES module has to have `module.namespaceObject` defined.
if (module.namespaceObject) return module.namespaceObject
return interopEsm();
}
```
So the following case if we use a react umd module(which doesn't have a
`default export`) as our external package, code
`console.log(__TURBOPACK__imported__module__263__["default"]);` will
output `undefined`(which webpack can output the right version).
I just change export wrapper the externalType: global and script
here(which now only consumed by utoopack), so the esmImport will execute
`interopEsm` function here to make our code work fine.
We test the case under utoopack and here is our pr:
https://github.com/umijs/mako/pull/2097/files.
---------
Co-authored-by: Niklas Mischkulnig <[email protected]>
69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
/// <reference path="./types.d.ts" />
|
|
|
|
const jest = require('jest-circus')
|
|
const expectMod = require('expect')
|
|
|
|
function setupGlobals() {
|
|
globalThis.describe = jest.describe
|
|
globalThis.it = jest.it
|
|
globalThis.test = jest.test
|
|
// @ts-ignore Property 'expect' does not exist on type 'typeof globalThis'
|
|
globalThis.expect = expectMod.expect
|
|
|
|
// Set up global external values for testing
|
|
// @ts-ignore Property 'testGlobalExternalValue' does not exist on type 'typeof globalThis'
|
|
globalThis.testGlobalExternalValue = { bar: '11' }
|
|
|
|
// From https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/test/TestCases.template.js#L422
|
|
globalThis.nsObj = function nsObj(obj) {
|
|
Object.defineProperty(obj, Symbol.toStringTag, {
|
|
value: 'Module',
|
|
})
|
|
return obj
|
|
}
|
|
}
|
|
|
|
const uncaughtExceptions: string[] = []
|
|
const unhandledRejections: string[] = []
|
|
|
|
process.on('uncaughtException', (e) => {
|
|
uncaughtExceptions.push(String(e))
|
|
})
|
|
|
|
process.on('unhandledRejection', (e) => {
|
|
unhandledRejections.push(String(e))
|
|
})
|
|
|
|
export default async function run() {
|
|
setupGlobals()
|
|
|
|
await import('TESTS')
|
|
|
|
let jestResult = await jest.run()
|
|
// Jest test results can contain references to arbitrary objects.
|
|
// Defensively remove circular references to avoid breaking our serialization protocol.
|
|
const seen = new Set()
|
|
jestResult = JSON.parse(
|
|
JSON.stringify(jestResult, (k, v) => {
|
|
if (v != null && typeof v === 'object') {
|
|
if (!seen.has(v)) {
|
|
seen.add(v)
|
|
return v
|
|
} else {
|
|
return 'CIRCULAR_REFERENCE_REMOVED'
|
|
}
|
|
}
|
|
return v
|
|
})
|
|
)
|
|
|
|
// Wait a full tick for unhandledRejection handlers to run -- a microtask is not sufficient.
|
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
|
|
return {
|
|
jestResult,
|
|
uncaughtExceptions,
|
|
unhandledRejections,
|
|
}
|
|
}
|