Repository: webpack/webpack
File: lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js (JavaScript)

Code before:
				"Object.getPrototypeOf(obj)",
				"obj"
			)} : ${runtimeTemplate.returningFunction("obj.__proto__", "obj")};`,
			"var leafPrototypes;",
			"// create a fake namespace object",
			"// mode & 1: value is a module id, require it",
			"// mode & 2: merge all properties of value into the ns",
			"// mode & 4: return value when already ns object",
			"// mode & 16: return value when it's Promise-like",
			"// mode & 8|1: behave like require",
			// Note: must be a function (not arrow), because this is used in body!
			`${fn} = function(value, mode) {`,
			Template.indent([
				"if(mode & 1) value = this(value);",
				"if(mode & 8) return value;",
				"if(typeof value === 'object' && value) {",
				Template.indent([
					"if((mode & 4) && value.__esModule) return value;",
					"if((mode & 16) && typeof value.then === 'function') return value;"
				]),
				"}",
				"var ns = Object.create(null);",
				`${RuntimeGlobals.makeNamespaceObject}(ns);`,
				"var def = {};",
				"leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];",
				"for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {",
				Template.indent([
					`Object.getOwnPropertyNames(current).forEach(${runtimeTemplate.expressionFunction(
						`def[key] = ${runtimeTemplate.returningFunction("value[key]", "")}`,
						"key"
					)});`
				]),
				"}",
				`def['default'] = ${runtimeTemplate.returningFunction("value", "")};`,
				`${RuntimeGlobals.definePropertyGetters}(ns, def);`,
				"return ns;"
			]),
			"};"
		]);
	}
}

module.exports = CreateFakeNamespaceObjectRuntimeModule;


Review comment (suggestion):
`function` have several own properties, such as name/length/prototype/caller...

Using `Object.getOwnPropertyNames(fn)` retrieves both enumerable and non-enumerable own properties. It will return  `["length", "name", "arguments", "caller", "prototype"]`.

When bundle following code based changes in this PR.

```js
import * as ns1 from "module";

import("module").then((ns2) => {
  const ns1Keys = Object.keys(ns1);
  const ns2Keys = Object.keys(ns2);
  console.log(
    "Diff:",
    ns2Keys.filter((key) => !ns1Keys.includes(key))
  );
});

```

It results in:

```js
Diff: [
  'length',
  'name',
  'prototype',
  '_stat',
  'wrap',
  'wrapper',
  '_readPackage',
  'default'
]
```

I think `default` is expected and others is unexpected...

Code after:
				"Object.getPrototypeOf(obj)",
				"obj"
			)} : ${runtimeTemplate.returningFunction("obj.__proto__", "obj")};`,
			"var leafPrototypes;",
			"// create a fake namespace object",
			"// mode & 1: value is a module id, require it",
			"// mode & 2: merge all properties of value into the ns",
			"// mode & 4: return value when already ns object",
			"// mode & 16: return value when it's Promise-like",
			"// mode & 8|1: behave like require",
			// Note: must be a function (not arrow), because this is used in body!
			`${fn} = function(value, mode) {`,
			Template.indent([
				"if(mode & 1) value = this(value);",
				"if(mode & 8) return value;",
				"if(typeof value === 'object' && value) {",
				Template.indent([
					"if((mode & 4) && value.__esModule) return value;",
					"if((mode & 16) && typeof value.then === 'function') return value;"
				]),
				"}",
				"var ns = Object.create(null);",
				`${RuntimeGlobals.makeNamespaceObject}(ns);`,
				"var def = {};",
				"leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];",
				"for(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) {",
				Template.indent([
					`Object.getOwnPropertyNames(current).forEach(${runtimeTemplate.expressionFunction(
						`def[key] = ${runtimeTemplate.returningFunction("value[key]", "")}`,
						"key"
					)});`
				]),
				"}",
				`def['default'] = ${runtimeTemplate.returningFunction("value", "")};`,
				`${RuntimeGlobals.definePropertyGetters}(ns, def);`,
				"return ns;"
			]),
			"};"
		]);
	}
}

module.exports = CreateFakeNamespaceObjectRuntimeModule;