Refactor how exportsType work
add flagged exportsType for __esModule flagged add getExportsType to merge strict with exportsType move CommonJsStuffPlugin into CommonJsPlugin split CommonJsPlugin into imports and exports part enable minimal tree shaking for CommonJs imports and exports
This commit is contained in:
parent
32ec03f2b2
commit
782e4535ac
|
@ -0,0 +1,282 @@
|
|||
# example.js
|
||||
|
||||
```javascript
|
||||
const inc = require("./increment").increment;
|
||||
var a = 1;
|
||||
inc(a); // 2
|
||||
```
|
||||
|
||||
# increment.js
|
||||
|
||||
```javascript
|
||||
const add = require("./math").add;
|
||||
exports.increment = function increment(val) {
|
||||
return add(val, 1);
|
||||
};
|
||||
exports.incrementBy2 = function incrementBy2(val) {
|
||||
return add(val, 2);
|
||||
};
|
||||
exports.decrement = function decrement(val) {
|
||||
return add(val, 1);
|
||||
};
|
||||
```
|
||||
|
||||
# math.js
|
||||
|
||||
```javascript
|
||||
exports.add = function add() {
|
||||
var sum = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum += args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
exports.multiply = function multiply() {
|
||||
var product = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum *= args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
```
|
||||
|
||||
# dist/output.js
|
||||
|
||||
```javascript
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ var __webpack_modules__ = ([
|
||||
/* 0 */,
|
||||
/* 1 */
|
||||
/*!**********************!*\
|
||||
!*** ./increment.js ***!
|
||||
\**********************/
|
||||
/*! exports type: default defaultObject: redirect */
|
||||
/*! export decrement [provided] [unused] [renamed to C] */
|
||||
/*! export default [provided] [unused] [no name, virtual] */
|
||||
/*! export decrement [provided] [unused] [renamed to C] */
|
||||
/*! export increment [provided] [used] [renamed to pD] */
|
||||
/*! export incrementBy2 [provided] [unused] [renamed to ju] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export increment [provided] [used] [renamed to pD] */
|
||||
/*! export incrementBy2 [provided] [unused] [renamed to ju] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_exports__ */
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
var __webpack_unused_export__;
|
||||
const add = __webpack_require__(/*! ./math */ 2)/* .add */ .K;
|
||||
exports.pD = function increment(val) {
|
||||
return add(val, 1);
|
||||
};
|
||||
__webpack_unused_export__ = function incrementBy2(val) {
|
||||
return add(val, 2);
|
||||
};
|
||||
__webpack_unused_export__ = function decrement(val) {
|
||||
return add(val, 1);
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/*!*****************!*\
|
||||
!*** ./math.js ***!
|
||||
\*****************/
|
||||
/*! exports type: default defaultObject: redirect */
|
||||
/*! export add [provided] [used] [renamed to K] */
|
||||
/*! export default [provided] [unused] [no name, virtual] */
|
||||
/*! export add [provided] [used] [renamed to K] */
|
||||
/*! export multiply [provided] [unused] [renamed to j] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export multiply [provided] [unused] [renamed to j] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_exports__ */
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
var __webpack_unused_export__;
|
||||
exports.K = function add() {
|
||||
var sum = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum += args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
__webpack_unused_export__ = function multiply() {
|
||||
var product = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum *= args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
```
|
||||
|
||||
<details><summary><code>/* webpack runtime code */</code></summary>
|
||||
|
||||
``` js
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(__webpack_module_cache__[moduleId]) {
|
||||
/******/ return __webpack_module_cache__[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
``` js
|
||||
(() => {
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! dynamic exports type */
|
||||
/*! exports [maybe provided (runtime-defined)] [unused] */
|
||||
/*! runtime requirements: __webpack_require__ */
|
||||
const inc = __webpack_require__(/*! ./increment */ 1)/* .increment */ .pD;
|
||||
var a = 1;
|
||||
inc(a); // 2
|
||||
|
||||
})();
|
||||
|
||||
/******/ })()
|
||||
;
|
||||
```
|
||||
|
||||
# dist/output.js (production)
|
||||
|
||||
```javascript
|
||||
/*! For license information please see output.js.LICENSE */
|
||||
(()=>{var r=[,(r,t,n)=>{const e=n(2).K;t.pD=function(r){return e(r,1)}},(r,t)=>{t.K=function(){for(var r=0,t=0,n=arguments,e=n.length;t<e;)r+=n[t++];return r}}],t={};function n(e){if(t[e])return t[e].exports;var o=t[e]={exports:{}};return r[e](o,o.exports,n),o.exports}(0,n(1).pD)(1)})();
|
||||
```
|
||||
|
||||
# dist/without.js (same without tree shaking)
|
||||
|
||||
```javascript
|
||||
/*! For license information please see without.js.LICENSE */
|
||||
(()=>{var n=[,(n,r,t)=>{const e=t(2).add;r.increment=function(n){return e(n,1)},r.incrementBy2=function(n){return e(n,2)},r.decrement=function(n){return e(n,1)}},(n,r)=>{r.add=function(){for(var n=0,r=0,t=arguments,e=t.length;r<e;)n+=t[r++];return n},r.multiply=function(){for(var n=0,r=arguments,t=r.length;n<t;)sum*=r[n++];return sum}}],r={};function t(e){if(r[e])return r[e].exports;var u=r[e]={exports:{}};return n[e](u,u.exports,t),u.exports}(0,t(1).increment)(1)})();
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Unoptimized
|
||||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.7
|
||||
Child
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Asset Size
|
||||
output.js 3.44 KiB [emitted] [name: main]
|
||||
Entrypoint main = output.js
|
||||
chunk output.js (main) 634 bytes [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 70 bytes [built]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
./increment.js 251 bytes [built]
|
||||
[exports: default, decrement, increment, incrementBy2]
|
||||
[only some exports used: increment]
|
||||
cjs full require ./increment ./example.js 1:12-44
|
||||
./math.js 313 bytes [built]
|
||||
[exports: default, add, multiply]
|
||||
[only some exports used: add]
|
||||
cjs full require ./math ./increment.js 1:12-33
|
||||
Child
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Asset Size
|
||||
without.js 3.7 KiB [emitted] [name: main]
|
||||
Entrypoint main = without.js
|
||||
chunk without.js (main) 634 bytes [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 70 bytes [built]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
./increment.js 251 bytes [built]
|
||||
[exports: default, decrement, increment, incrementBy2]
|
||||
[used exports unknown]
|
||||
cjs full require ./increment ./example.js 1:12-44
|
||||
./math.js 313 bytes [built]
|
||||
[exports: default, add, multiply]
|
||||
[used exports unknown]
|
||||
cjs full require ./math ./increment.js 1:12-33
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.7
|
||||
Child
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Asset Size
|
||||
output.js 348 bytes [emitted] [name: main]
|
||||
output.js.LICENSE 1.16 KiB [emitted]
|
||||
Entrypoint main = output.js
|
||||
chunk output.js (main) 634 bytes [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 70 bytes [built]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
./increment.js 251 bytes [built]
|
||||
[exports: default, decrement, increment, incrementBy2]
|
||||
[only some exports used: increment]
|
||||
cjs full require ./increment ./example.js 1:12-44
|
||||
./math.js 313 bytes [built]
|
||||
[exports: default, add, multiply]
|
||||
[only some exports used: add]
|
||||
cjs full require ./math ./increment.js 1:12-33
|
||||
Child
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Asset Size
|
||||
without.js 534 bytes [emitted] [name: main]
|
||||
without.js.LICENSE 1.49 KiB [emitted]
|
||||
Entrypoint main = without.js
|
||||
chunk without.js (main) 634 bytes [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 70 bytes [built]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
./increment.js 251 bytes [built]
|
||||
[exports: default, decrement, increment, incrementBy2]
|
||||
[used exports unknown]
|
||||
cjs full require ./increment ./example.js 1:12-44
|
||||
./math.js 313 bytes [built]
|
||||
[exports: default, add, multiply]
|
||||
[used exports unknown]
|
||||
cjs full require ./math ./increment.js 1:12-33
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
global.NO_TARGET_ARGS = true;
|
||||
require("../build-common");
|
|
@ -0,0 +1,58 @@
|
|||
BAD:
|
||||
|
||||
module.exports = abc; module.exports.xxx = abc; abc.xxx;
|
||||
exports = abc;
|
||||
module.exports
|
||||
exports
|
||||
this
|
||||
function f() { return this; } module.exports = { f }; module.exports.xxx = abc;
|
||||
|
||||
|
||||
EXPORTS:
|
||||
|
||||
exports.xxx = abc;
|
||||
|
||||
module.exports.xxx = abc;
|
||||
this.xxx = abc
|
||||
Object.defineProperty(exports, "xxx", { ... })
|
||||
Object.defineProperty(module.exports, "xxx", { ... })
|
||||
Object.defineProperty(this, "xxx", { ... })
|
||||
module.exports.xxx
|
||||
exports.xxx
|
||||
this.xxx
|
||||
module.exports = function() {}; module.exports.xxx = abc;
|
||||
module.exports = { ... }; module.exports.xxx = abc;
|
||||
|
||||
OBJECTS:
|
||||
|
||||
module.exports = { xxx: abc };
|
||||
|
||||
IMPORT:
|
||||
|
||||
require(x).xxx
|
||||
var { xxx } = require(x);
|
||||
var x = require(x); x.xxx;
|
||||
|
||||
REEXPORT:
|
||||
|
||||
module.exports.xxx = require(x);
|
||||
module.exports.xxx = require(x).xxx;
|
||||
exports.xxx = require(x);
|
||||
exports.xxx = require(x).xxx;
|
||||
module.exports = { xxx2: require(x) };
|
||||
module.exports = { xxx2: require(x).xxx };
|
||||
var xxx = require(x); exports.xxx = xxx;
|
||||
var xxx = require(x); exports.xxx = xxx.xxx;
|
||||
var xxx = require(x); module.exports = { xxx };
|
||||
var xxx = require(x); module.exports = { xxx: xxx.xxx };
|
||||
|
||||
TRANSPILED:
|
||||
|
||||
TypeScript:
|
||||
function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; }
|
||||
__export(require(x));
|
||||
|
||||
Babel:
|
||||
var xxx = _interopRequireDefault(require(x));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
xxx.xxx;
|
|
@ -0,0 +1,3 @@
|
|||
const inc = require("./increment").increment;
|
||||
var a = 1;
|
||||
inc(a); // 2
|
|
@ -0,0 +1,10 @@
|
|||
const add = require("./math").add;
|
||||
exports.increment = function increment(val) {
|
||||
return add(val, 1);
|
||||
};
|
||||
exports.incrementBy2 = function incrementBy2(val) {
|
||||
return add(val, 2);
|
||||
};
|
||||
exports.decrement = function decrement(val) {
|
||||
return add(val, 1);
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
exports.add = function add() {
|
||||
var sum = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum += args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
exports.multiply = function multiply() {
|
||||
var product = 0,
|
||||
i = 0,
|
||||
args = arguments,
|
||||
l = args.length;
|
||||
while (i < l) {
|
||||
sum *= args[i++];
|
||||
}
|
||||
return sum;
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
# example.js
|
||||
|
||||
```javascript
|
||||
_{{example.js}}_
|
||||
```
|
||||
|
||||
# increment.js
|
||||
|
||||
```javascript
|
||||
_{{increment.js}}_
|
||||
```
|
||||
|
||||
# math.js
|
||||
|
||||
```javascript
|
||||
_{{math.js}}_
|
||||
```
|
||||
|
||||
# dist/output.js
|
||||
|
||||
```javascript
|
||||
_{{dist/output.js}}_
|
||||
```
|
||||
|
||||
# dist/output.js (production)
|
||||
|
||||
```javascript
|
||||
_{{production:dist/output.js}}_
|
||||
```
|
||||
|
||||
# dist/without.js (same without tree shaking)
|
||||
|
||||
```javascript
|
||||
_{{production:dist/without.js}}_
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Unoptimized
|
||||
|
||||
```
|
||||
_{{stdout}}_
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
_{{production:stdout}}_
|
||||
```
|
|
@ -0,0 +1,26 @@
|
|||
module.exports = [
|
||||
{
|
||||
entry: "./example.js",
|
||||
output: {
|
||||
pathinfo: true,
|
||||
filename: "output.js"
|
||||
},
|
||||
optimization: {
|
||||
moduleIds: "size",
|
||||
usedExports: true,
|
||||
mangleExports: true
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: "./example.js",
|
||||
output: {
|
||||
pathinfo: true,
|
||||
filename: "without.js"
|
||||
},
|
||||
optimization: {
|
||||
moduleIds: "size",
|
||||
usedExports: false,
|
||||
mangleExports: false
|
||||
}
|
||||
}
|
||||
];
|
|
@ -1,233 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("./RuntimeGlobals");
|
||||
const RuntimeModule = require("./RuntimeModule");
|
||||
const Template = require("./Template");
|
||||
const ModuleDecoratorDependency = require("./dependencies/ModuleDecoratorDependency");
|
||||
const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
|
||||
const {
|
||||
evaluateToIdentifier,
|
||||
expressionIsUnsupported,
|
||||
toConstantDependency
|
||||
} = require("./javascript/JavascriptParserHelpers");
|
||||
|
||||
class CommonJsStuffPlugin {
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
"CommonJsStuffPlugin",
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
compilation.dependencyFactories.set(
|
||||
ModuleDecoratorDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
ModuleDecoratorDependency,
|
||||
new ModuleDecoratorDependency.Template()
|
||||
);
|
||||
|
||||
compilation.hooks.runtimeRequirementInModule
|
||||
.for(RuntimeGlobals.harmonyModuleDecorator)
|
||||
.tap("CommonJsStuffPlugin", (module, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.requireScope);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInModule
|
||||
.for(RuntimeGlobals.nodeModuleDecorator)
|
||||
.tap("CommonJsStuffPlugin", (module, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.requireScope);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.harmonyModuleDecorator)
|
||||
.tap("CommonJsStuffPlugin", (chunk, set) => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new HarmonyModuleDecoratorRuntimeModule()
|
||||
);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.nodeModuleDecorator)
|
||||
.tap("CommonJsStuffPlugin", (chunk, set) => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new NodeModuleDecoratorRuntimeModule()
|
||||
);
|
||||
});
|
||||
|
||||
const handler = (parser, parserOptions) => {
|
||||
parser.hooks.expression
|
||||
.for("require.main.require")
|
||||
.tap(
|
||||
"CommonJsStuffPlugin",
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
"require.main.require is not supported by webpack."
|
||||
)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module.parent.require")
|
||||
.tap(
|
||||
"CommonJsStuffPlugin",
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
"module.parent.require is not supported by webpack."
|
||||
)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("require.main")
|
||||
.tap(
|
||||
"CommonJsStuffPlugin",
|
||||
toConstantDependency(
|
||||
parser,
|
||||
`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
|
||||
[RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
|
||||
)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module.loaded")
|
||||
.tap("CommonJsStuffPlugin", expr => {
|
||||
parser.state.module.buildMeta.moduleConcatenationBailout =
|
||||
"module.loaded";
|
||||
const dep = new RuntimeRequirementsDependency([
|
||||
RuntimeGlobals.moduleLoaded
|
||||
]);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for("module.id")
|
||||
.tap("CommonJsStuffPlugin", expr => {
|
||||
parser.state.module.buildMeta.moduleConcatenationBailout =
|
||||
"module.id";
|
||||
const dep = new RuntimeRequirementsDependency([
|
||||
RuntimeGlobals.moduleId
|
||||
]);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for("module.exports")
|
||||
.tap("CommonJsStuffPlugin", expr => {
|
||||
const module = parser.state.module;
|
||||
const isHarmony = parser.state.harmonyModule;
|
||||
if (!isHarmony) {
|
||||
if (module.moduleArgument === "module") {
|
||||
// avoid rewriting module.exports for backward-compat
|
||||
const dep = new RuntimeRequirementsDependency([
|
||||
RuntimeGlobals.module
|
||||
]);
|
||||
dep.loc = expr.loc;
|
||||
module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
return toConstantDependency(
|
||||
parser,
|
||||
`${module.moduleArgument}.exports`,
|
||||
[RuntimeGlobals.module]
|
||||
)(expr);
|
||||
}
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for("this")
|
||||
.tap("CommonJsStuffPlugin", expr => {
|
||||
if (!parser.scope.topLevelScope) return;
|
||||
const isHarmony = parser.state.harmonyModule;
|
||||
if (!isHarmony) {
|
||||
return toConstantDependency(parser, "this", [
|
||||
RuntimeGlobals.thisAsExports
|
||||
])(expr);
|
||||
}
|
||||
});
|
||||
parser.hooks.evaluateIdentifier.for("module.hot").tap(
|
||||
"CommonJsStuffPlugin",
|
||||
evaluateToIdentifier("module.hot", "module", () => ["hot"], false)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module")
|
||||
.tap("CommonJsStuffPlugin", expr => {
|
||||
const isHarmony = parser.state.harmonyModule;
|
||||
const dep = new ModuleDecoratorDependency(
|
||||
isHarmony
|
||||
? RuntimeGlobals.harmonyModuleDecorator
|
||||
: RuntimeGlobals.nodeModuleDecorator
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/auto")
|
||||
.tap("CommonJsStuffPlugin", handler);
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/dynamic")
|
||||
.tap("CommonJsStuffPlugin", handler);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
|
||||
constructor() {
|
||||
super("harmony module decorator");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate } = this.compilation;
|
||||
return Template.asString([
|
||||
`${
|
||||
RuntimeGlobals.harmonyModuleDecorator
|
||||
} = ${runtimeTemplate.basicFunction("module", [
|
||||
"module = Object.create(module);",
|
||||
"if (!module.children) module.children = [];",
|
||||
"Object.defineProperty(module, 'exports', {",
|
||||
Template.indent([
|
||||
"enumerable: true,",
|
||||
`set: ${runtimeTemplate.basicFunction("", [
|
||||
"throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);"
|
||||
])}`
|
||||
]),
|
||||
"});",
|
||||
"return module;"
|
||||
])};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class NodeModuleDecoratorRuntimeModule extends RuntimeModule {
|
||||
constructor() {
|
||||
super("node module decorator");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate } = this.compilation;
|
||||
return Template.asString([
|
||||
`${
|
||||
RuntimeGlobals.nodeModuleDecorator
|
||||
} = ${runtimeTemplate.basicFunction("module", [
|
||||
"module.paths = [];",
|
||||
"if (!module.children) module.children = [];",
|
||||
"return module;"
|
||||
])};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CommonJsStuffPlugin;
|
|
@ -462,13 +462,12 @@ class ContextModule extends Module {
|
|||
return 9;
|
||||
}
|
||||
const moduleGraph = chunkGraph.moduleGraph;
|
||||
// bitfield
|
||||
let hasType = 0;
|
||||
const comparator = compareModulesById(chunkGraph);
|
||||
// if we filter first we get a new array
|
||||
// therefor we dont need to create a clone of dependencies explicitly
|
||||
// therefore the order of this is !important!
|
||||
let hasNonHarmony = false;
|
||||
let hasNamespace = false;
|
||||
let hasNamed = false;
|
||||
const comparator = compareModulesById(chunkGraph);
|
||||
const fakeMap = dependencies
|
||||
.map(dependency => ({
|
||||
module: moduleGraph.getModule(dependency),
|
||||
|
@ -477,30 +476,46 @@ class ContextModule extends Module {
|
|||
.filter(item => item.module)
|
||||
.sort((a, b) => comparator(a.module, b.module))
|
||||
.reduce((map, { dependency: dep, module }) => {
|
||||
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
||||
const exportsType = module.getExportsType(
|
||||
this.options.namespaceObject === "strict"
|
||||
);
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
if (!exportsType) {
|
||||
map[id] = this.options.namespaceObject === "strict" ? 1 : 7;
|
||||
hasNonHarmony = true;
|
||||
} else if (exportsType === "namespace") {
|
||||
map[id] = 9;
|
||||
hasNamespace = true;
|
||||
} else if (exportsType === "default") {
|
||||
map[id] = this.options.namespaceObject === "strict" ? 1 : 3;
|
||||
hasNamed = true;
|
||||
switch (exportsType) {
|
||||
case "namespace":
|
||||
map[id] = 9;
|
||||
hasType |= 1;
|
||||
break;
|
||||
case "dynamic":
|
||||
map[id] = 7;
|
||||
hasType |= 2;
|
||||
break;
|
||||
case "dynamic-default":
|
||||
case "default-only":
|
||||
map[id] = 1;
|
||||
hasType |= 4;
|
||||
break;
|
||||
case "default-with-named":
|
||||
map[id] = 3;
|
||||
hasType |= 8;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unexpected exports type ${exportsType}`);
|
||||
}
|
||||
return map;
|
||||
}, Object.create(null));
|
||||
if (!hasNamespace && hasNonHarmony && !hasNamed) {
|
||||
return this.options.namespaceObject === "strict" ? 1 : 7;
|
||||
}
|
||||
if (hasNamespace && !hasNonHarmony && !hasNamed) {
|
||||
if (hasType === 1) {
|
||||
return 9;
|
||||
}
|
||||
if (!hasNamespace && !hasNonHarmony && hasNamed) {
|
||||
return this.options.namespaceObject === "strict" ? 1 : 3;
|
||||
if (hasType === 2) {
|
||||
return 7;
|
||||
}
|
||||
if (!hasNamespace && !hasNonHarmony && !hasNamed) {
|
||||
if (hasType === 4) {
|
||||
return 1;
|
||||
}
|
||||
if (hasType === 8) {
|
||||
return 3;
|
||||
}
|
||||
if (hasType === 0) {
|
||||
return 9;
|
||||
}
|
||||
return fakeMap;
|
||||
|
|
|
@ -65,8 +65,8 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
* @property {string=} exportsArgument
|
||||
* @property {boolean=} strict
|
||||
* @property {string=} moduleConcatenationBailout
|
||||
* @property {("default" | "namespace")=} exportsType
|
||||
* @property {(boolean | "redirect")=} defaultObject
|
||||
* @property {("default" | "namespace" | "flagged")=} exportsType
|
||||
* @property {(boolean | "redirect" | "redirect-warn")=} defaultObject
|
||||
* @property {boolean=} strictHarmonyModule
|
||||
* @property {boolean=} async
|
||||
*/
|
||||
|
@ -365,6 +365,29 @@ class Module extends DependenciesBlock {
|
|||
return (this.buildInfo && this.buildInfo.moduleArgument) || "module";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} strict the importing module is strict
|
||||
* @returns {"dynamic" | "dynamic-default" | "namespace" | "default-only" | "default-with-named"} export type
|
||||
*/
|
||||
getExportsType(strict) {
|
||||
switch (this.buildMeta && this.buildMeta.exportsType) {
|
||||
case "flagged":
|
||||
return strict ? "dynamic-default" : "namespace";
|
||||
case "namespace":
|
||||
return "namespace";
|
||||
case "default":
|
||||
switch (this.buildMeta.defaultObject) {
|
||||
case "redirect":
|
||||
case "redirect-warn":
|
||||
return strict ? "default-only" : "default-with-named";
|
||||
default:
|
||||
return "default-only";
|
||||
}
|
||||
default:
|
||||
return strict ? "dynamic-default" : "dynamic";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Dependency} presentationalDependency dependency being tied to module.
|
||||
* This is a Dependency without edge in the module graph. It's only for presentation.
|
||||
|
|
|
@ -130,13 +130,8 @@ class ExportsInfo {
|
|||
this._exportsAreOrdered = true;
|
||||
}
|
||||
|
||||
setRedirectToDefaultObject() {
|
||||
const defaultInfo = this.getExportInfo("default");
|
||||
defaultInfo.canMangleProvide = false;
|
||||
defaultInfo.provided = true;
|
||||
defaultInfo.usedName = "";
|
||||
const inner = defaultInfo.createNestedExportsInfo();
|
||||
this._redirectTo = inner;
|
||||
setRedirectNamedTo(exportsInfo) {
|
||||
this._redirectTo = exportsInfo;
|
||||
}
|
||||
|
||||
setHasProvideInfo() {
|
||||
|
@ -958,8 +953,21 @@ class ModuleGraph {
|
|||
* @returns {void}
|
||||
*/
|
||||
finishModule(module) {
|
||||
if (module.buildMeta.defaultObject) {
|
||||
this.getExportsInfo(module).setRedirectToDefaultObject();
|
||||
if (module.buildMeta.exportsType === "default") {
|
||||
const exportsInfo = this.getExportsInfo(module);
|
||||
const defaultInfo = exportsInfo.getExportInfo("default");
|
||||
defaultInfo.canMangleProvide = false;
|
||||
defaultInfo.provided = true;
|
||||
defaultInfo.usedName = "";
|
||||
if (module.buildMeta.defaultObject) {
|
||||
const innerObject = defaultInfo.createNestedExportsInfo();
|
||||
if (
|
||||
module.buildMeta.defaultObject === "redirect" ||
|
||||
module.buildMeta.defaultObject === "redirect-warn"
|
||||
) {
|
||||
exportsInfo.setRedirectNamedTo(innerObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,18 @@ class ModuleInfoHeaderPlugin {
|
|||
source.add("/*!****" + reqStrStar + "****!*\\\n");
|
||||
source.add(" !*** " + reqStr + " ***!\n");
|
||||
source.add(" \\****" + reqStrStar + "****/\n");
|
||||
const exportsType = module.buildMeta.exportsType;
|
||||
source.add(
|
||||
Template.toComment(
|
||||
exportsType
|
||||
? `exports type: ${exportsType}${
|
||||
exportsType === "default"
|
||||
? ` defaultObject: ${module.buildMeta.defaultObject}`
|
||||
: ""
|
||||
}`
|
||||
: "dynamic exports type"
|
||||
) + "\n"
|
||||
);
|
||||
const exportsInfo = moduleGraph.getExportsInfo(module);
|
||||
printExportsInfoToSource(source, "", exportsInfo);
|
||||
source.add(
|
||||
|
|
|
@ -326,25 +326,26 @@ class RuntimeTemplate {
|
|||
request,
|
||||
weak
|
||||
});
|
||||
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
||||
if (exportsType === "namespace") {
|
||||
const rawModule = this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
return rawModule;
|
||||
} else if (strict) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;
|
||||
} else if (exportsType === "default") {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;
|
||||
const exportsType = module.getExportsType(strict);
|
||||
switch (exportsType) {
|
||||
case "namespace":
|
||||
return this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
case "default-with-named":
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;
|
||||
case "default-only":
|
||||
case "dynamic-default":
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;
|
||||
case "dynamic":
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,54 +428,46 @@ class RuntimeTemplate {
|
|||
request,
|
||||
weak
|
||||
});
|
||||
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
||||
if (exportsType === "namespace") {
|
||||
if (header) {
|
||||
const rawModule = this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${rawModule};`
|
||||
);
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.require);
|
||||
getModuleFunction = `__webpack_require__.bind(__webpack_require__, ${comment}${idExpr})`;
|
||||
}
|
||||
} else if (strict) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 1)`;
|
||||
getModuleFunction = header
|
||||
? this.basicFunction("", `${header}return ${returnExpression};`)
|
||||
: this.returningFunction(returnExpression);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 1)`;
|
||||
}
|
||||
} else if (exportsType === "default") {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 3)`;
|
||||
getModuleFunction = header
|
||||
? this.basicFunction("", `${header}return ${returnExpression};`)
|
||||
: this.returningFunction(returnExpression);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 3)`;
|
||||
}
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, 7)`;
|
||||
getModuleFunction = header
|
||||
? this.basicFunction("", `${header}return ${returnExpression};`)
|
||||
: this.returningFunction(returnExpression);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, 7)`;
|
||||
}
|
||||
const exportsType = module.getExportsType(strict);
|
||||
let fakeType = 0;
|
||||
switch (exportsType) {
|
||||
case "namespace":
|
||||
if (header) {
|
||||
const rawModule = this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
getModuleFunction = this.basicFunction(
|
||||
"",
|
||||
`${header}return ${rawModule};`
|
||||
);
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.require);
|
||||
getModuleFunction = `__webpack_require__.bind(__webpack_require__, ${comment}${idExpr})`;
|
||||
}
|
||||
break;
|
||||
case "dynamic":
|
||||
fakeType |= 7;
|
||||
/* fall through */
|
||||
case "default-with-named":
|
||||
fakeType |= 3;
|
||||
/* fall through */
|
||||
case "default-only":
|
||||
case "dynamic-default":
|
||||
fakeType |= 1;
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
if (header) {
|
||||
const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, ${fakeType})`;
|
||||
getModuleFunction = header
|
||||
? this.basicFunction("", `${header}return ${returnExpression};`)
|
||||
: this.returningFunction(returnExpression);
|
||||
} else {
|
||||
getModuleFunction = `${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, ${fakeType})`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return `${promise || "Promise.resolve()"}.then(${getModuleFunction})`;
|
||||
|
@ -552,6 +545,7 @@ class RuntimeTemplate {
|
|||
* @param {boolean} options.asiSafe true, if location is safe for ASI, a bracket can be emitted
|
||||
* @param {boolean} options.isCall true, if expression will be called
|
||||
* @param {boolean} options.callContext when false, call context will not be preserved
|
||||
* @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated
|
||||
* @param {string} options.importVar the identifier name of the import variable
|
||||
* @param {InitFragment[]} options.initFragments init fragments will be added here
|
||||
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
|
||||
|
@ -566,6 +560,7 @@ class RuntimeTemplate {
|
|||
asiSafe,
|
||||
isCall,
|
||||
callContext,
|
||||
defaultInterop,
|
||||
importVar,
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
|
@ -580,26 +575,43 @@ class RuntimeTemplate {
|
|||
}
|
||||
const exportsType = module.buildMeta && module.buildMeta.exportsType;
|
||||
|
||||
if (!exportsType) {
|
||||
if (exportName.length > 0 && exportName[0] === "default") {
|
||||
if (!originModule.buildMeta.strictHarmonyModule) {
|
||||
if (isCall) {
|
||||
return `${importVar}_default()${propertyAccess(exportName, 1)}`;
|
||||
} else if (asiSafe) {
|
||||
return `(${importVar}_default()${propertyAccess(exportName, 1)})`;
|
||||
if (defaultInterop) {
|
||||
if (!exportsType) {
|
||||
if (exportName.length > 0 && exportName[0] === "default") {
|
||||
if (!originModule.buildMeta.strictHarmonyModule) {
|
||||
if (isCall) {
|
||||
return `${importVar}_default()${propertyAccess(exportName, 1)}`;
|
||||
} else if (asiSafe) {
|
||||
return `(${importVar}_default()${propertyAccess(exportName, 1)})`;
|
||||
} else {
|
||||
return `${importVar}_default.a${propertyAccess(exportName, 1)}`;
|
||||
}
|
||||
} else {
|
||||
return `${importVar}_default.a${propertyAccess(exportName, 1)}`;
|
||||
return `${importVar}${propertyAccess(exportName, 1)}`;
|
||||
}
|
||||
} else if (originModule.buildMeta.strictHarmonyModule) {
|
||||
if (exportName.length > 0) {
|
||||
return (
|
||||
"/* non-default import from non-esm module */undefined" +
|
||||
propertyAccess(exportName, 1)
|
||||
);
|
||||
} else {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
`var ${importVar}_namespace_cache;\n`,
|
||||
InitFragment.STAGE_CONSTANTS,
|
||||
-1,
|
||||
`${importVar}_namespace_cache`
|
||||
)
|
||||
);
|
||||
return `/*#__PURE__*/ (${importVar}_namespace_cache || (${importVar}_namespace_cache = ${RuntimeGlobals.createFakeNamespaceObject}(${importVar})))`;
|
||||
}
|
||||
} else {
|
||||
return `${importVar}${propertyAccess(exportName, 1)}`;
|
||||
}
|
||||
} else if (originModule.buildMeta.strictHarmonyModule) {
|
||||
if (exportName.length > 0) {
|
||||
return (
|
||||
"/* non-default import from non-esm module */undefined" +
|
||||
propertyAccess(exportName, 1)
|
||||
);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (exportsType === "default") {
|
||||
if (exportName.length === 0) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
|
@ -609,30 +621,20 @@ class RuntimeTemplate {
|
|||
`${importVar}_namespace_cache`
|
||||
)
|
||||
);
|
||||
return `/*#__PURE__*/ (${importVar}_namespace_cache || (${importVar}_namespace_cache = ${RuntimeGlobals.createFakeNamespaceObject}(${importVar})))`;
|
||||
const content = `${importVar}_namespace_cache || (${importVar}_namespace_cache = ${
|
||||
RuntimeGlobals.createFakeNamespaceObject
|
||||
}(${importVar}, ${
|
||||
originModule.buildMeta.strictHarmonyModule ? 0 : 2
|
||||
}))`;
|
||||
if (asiSafe) {
|
||||
return `/*#__PURE__*/ (${content})`;
|
||||
} else {
|
||||
return `/*#__PURE__*/ Object(${content})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exportsType === "default") {
|
||||
if (exportName.length === 0) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
`var ${importVar}_namespace_cache;\n`,
|
||||
InitFragment.STAGE_CONSTANTS,
|
||||
-1,
|
||||
`${importVar}_namespace_cache`
|
||||
)
|
||||
);
|
||||
return `/*#__PURE__*/ (${importVar}_namespace_cache || (${importVar}_namespace_cache = ${
|
||||
RuntimeGlobals.createFakeNamespaceObject
|
||||
}(${importVar}, ${
|
||||
originModule.buildMeta.strictHarmonyModule ? 0 : 2
|
||||
})))`;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportName.length > 0) {
|
||||
const exportsInfo = moduleGraph.getExportsInfo(module);
|
||||
const used = exportsInfo.getUsedName(exportName);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class SelfModuleFactory {
|
||||
constructor(moduleGraph) {
|
||||
this.moduleGraph = moduleGraph;
|
||||
}
|
||||
|
||||
create(data, callback) {
|
||||
const module = this.moduleGraph.getParentModule(data.dependencies[0]);
|
||||
callback(null, {
|
||||
module
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SelfModuleFactory;
|
|
@ -18,7 +18,6 @@ const RecordIdsPlugin = require("./RecordIdsPlugin");
|
|||
const RuntimePlugin = require("./RuntimePlugin");
|
||||
|
||||
const APIPlugin = require("./APIPlugin");
|
||||
const CommonJsStuffPlugin = require("./CommonJsStuffPlugin");
|
||||
const CompatibilityPlugin = require("./CompatibilityPlugin");
|
||||
const ConstPlugin = require("./ConstPlugin");
|
||||
const ExportsInfoApiPlugin = require("./ExportsInfoApiPlugin");
|
||||
|
@ -341,7 +340,6 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
const NodeStuffPlugin = require("./NodeStuffPlugin");
|
||||
new NodeStuffPlugin(options.node).apply(compiler);
|
||||
}
|
||||
new CommonJsStuffPlugin().apply(compiler);
|
||||
new APIPlugin().apply(compiler);
|
||||
new ExportsInfoApiPlugin().apply(compiler);
|
||||
new ConstPlugin().apply(compiler);
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const InitFragment = require("../InitFragment");
|
||||
const { UsageState } = require("../ModuleGraph");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const propertyAccess = require("../util/propertyAccess");
|
||||
const NullDependency = require("./NullDependency");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("../Dependency")} Dependency */
|
||||
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
|
||||
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
|
||||
class CommonJsExportsDependency extends NullDependency {
|
||||
constructor(range, base, names) {
|
||||
super();
|
||||
this.range = range;
|
||||
this.base = base;
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "cjs exports";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exported names
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {ExportsSpec | undefined} export names
|
||||
*/
|
||||
getExports(moduleGraph) {
|
||||
return {
|
||||
exports: [this.names[0]],
|
||||
dependencies: undefined
|
||||
};
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.range);
|
||||
write(this.base);
|
||||
write(this.names);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.range = read();
|
||||
this.base = read();
|
||||
this.names = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
CommonJsExportsDependency,
|
||||
"webpack/lib/dependencies/CommonJsExportsDependency"
|
||||
);
|
||||
|
||||
CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate extends NullDependency.Template {
|
||||
/**
|
||||
* @param {Dependency} dependency the dependency for which the template should be applied
|
||||
* @param {ReplaceSource} source the current replace source which can be modified
|
||||
* @param {DependencyTemplateContext} templateContext the context object
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(
|
||||
dependency,
|
||||
source,
|
||||
{ module, moduleGraph, initFragments, runtimeRequirements }
|
||||
) {
|
||||
const dep = /** @type {CommonJsExportsDependency} */ (dependency);
|
||||
let used;
|
||||
if (module.buildMeta.exportsType === "default") {
|
||||
const defaultInfo = moduleGraph.getExportInfo(module, "default");
|
||||
if (defaultInfo.used === UsageState.Used) {
|
||||
used = dep.names;
|
||||
} else {
|
||||
used = defaultInfo.exportsInfo.getUsedName(dep.names);
|
||||
}
|
||||
} else {
|
||||
used = moduleGraph.getExportsInfo(module).getUsedName(dep.names);
|
||||
}
|
||||
if (!used) {
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
"var __webpack_unused_export__;\n",
|
||||
InitFragment.STAGE_CONSTANTS,
|
||||
0,
|
||||
"__webpack_unused_export__"
|
||||
)
|
||||
);
|
||||
source.replace(
|
||||
dep.range[0],
|
||||
dep.range[1] - 1,
|
||||
"__webpack_unused_export__"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let base = undefined;
|
||||
switch (dep.base) {
|
||||
case "exports":
|
||||
runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
base = module.exportsArgument;
|
||||
break;
|
||||
case "module.exports":
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
base = `${module.moduleArgument}.exports`;
|
||||
break;
|
||||
case "this":
|
||||
runtimeRequirements.add(RuntimeGlobals.thisAsExports);
|
||||
base = "this";
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported base ${dep.base}`);
|
||||
}
|
||||
|
||||
source.replace(
|
||||
dep.range[0],
|
||||
dep.range[1] - 1,
|
||||
`${base}${propertyAccess(used)}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CommonJsExportsDependency;
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const { evaluateToString } = require("../javascript/JavascriptParserHelpers");
|
||||
const CommonJsExportsDependency = require("./CommonJsExportsDependency");
|
||||
const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
|
||||
const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
|
||||
|
||||
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
||||
|
||||
class CommonJsExportsDependencyParserPlugin {
|
||||
/**
|
||||
* @param {JavascriptParser} parser the parser
|
||||
*/
|
||||
apply(parser) {
|
||||
const bailedOut = new WeakSet();
|
||||
const enableModuleExports = () => {
|
||||
if (!parser.state.module.buildMeta.exportsType) {
|
||||
if (bailedOut.has(parser.state)) return;
|
||||
parser.state.module.buildMeta.exportsType = "default";
|
||||
parser.state.module.buildMeta.defaultObject = "redirect";
|
||||
}
|
||||
};
|
||||
const checkNamespace = (members, valueExpr) => {
|
||||
if (members.length > 0 && members[0] === "__esModule") {
|
||||
if (
|
||||
valueExpr &&
|
||||
valueExpr.type === "Literal" &&
|
||||
valueExpr.value === true
|
||||
) {
|
||||
parser.state.module.buildMeta.exportsType = "flagged";
|
||||
} else {
|
||||
bailoutModuleExports();
|
||||
}
|
||||
}
|
||||
};
|
||||
const bailoutModuleExports = () => {
|
||||
bailedOut.add(parser.state);
|
||||
parser.state.module.buildMeta.exportsType = undefined;
|
||||
parser.state.module.buildMeta.defaultObject = false;
|
||||
};
|
||||
|
||||
// metadata //
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("module")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", evaluateToString("object"));
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("exports")
|
||||
.tap("CommonJsPlugin", evaluateToString("object"));
|
||||
|
||||
// exporting //
|
||||
parser.hooks.assignMemberChain
|
||||
.for("exports")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", (expr, members) => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
enableModuleExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
"exports",
|
||||
members
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.assignMemberChain
|
||||
.for("this")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", (expr, members) => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
if (!parser.scope.topLevelScope) return;
|
||||
enableModuleExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
"this",
|
||||
members
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.assignMemberChain
|
||||
.for("module")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", (expr, members) => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
if (members[0] !== "exports" || members.length <= 1) return;
|
||||
enableModuleExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
"module.exports",
|
||||
members.slice(1)
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Self reference //
|
||||
parser.hooks.expression
|
||||
.for("exports")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", expr => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
bailoutModuleExports();
|
||||
const dep = new CommonJsSelfReferenceDependency(
|
||||
expr.range,
|
||||
"exports",
|
||||
[]
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for("module.exports")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", expr => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
bailoutModuleExports();
|
||||
const dep = new CommonJsSelfReferenceDependency(
|
||||
expr.range,
|
||||
"module.exports",
|
||||
[]
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.expression
|
||||
.for("this")
|
||||
.tap("CommonJsExportsDependencyParserPlugin", expr => {
|
||||
if (parser.state.harmonyModule) return;
|
||||
if (!parser.scope.topLevelScope) return;
|
||||
bailoutModuleExports();
|
||||
const dep = new CommonJsSelfReferenceDependency(expr.range, "this", []);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Bailouts //
|
||||
parser.hooks.expression.for("module").tap("CommonJsPlugin", expr => {
|
||||
bailoutModuleExports();
|
||||
const isHarmony = parser.state.harmonyModule;
|
||||
const dep = new ModuleDecoratorDependency(
|
||||
isHarmony
|
||||
? RuntimeGlobals.harmonyModuleDecorator
|
||||
: RuntimeGlobals.nodeModuleDecorator
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = CommonJsExportsDependencyParserPlugin;
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ModuleDependency = require("./ModuleDependency");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("../Dependency")} Dependency */
|
||||
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
|
||||
class CommonJsFullRequireDependency extends ModuleDependency {
|
||||
/**
|
||||
* @param {string} request the request string
|
||||
* @param {[number, number]} range location in source code
|
||||
* @param {string[]} names accessed properties on module
|
||||
*/
|
||||
constructor(request, range, names) {
|
||||
super(request);
|
||||
this.range = range;
|
||||
this.names = names;
|
||||
this.call = false;
|
||||
this.asiSafe = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of exports referenced by this dependency
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {string[][]} referenced exports
|
||||
*/
|
||||
getReferencedExports(moduleGraph) {
|
||||
if (this.call) {
|
||||
const importedModule = moduleGraph.getModule(this);
|
||||
if (
|
||||
!importedModule ||
|
||||
importedModule.getExportsType(false) !== "namespace"
|
||||
) {
|
||||
return [this.names.slice(0, -1)];
|
||||
}
|
||||
}
|
||||
return [this.names];
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.names);
|
||||
write(this.call);
|
||||
write(this.asiSafe);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.names = read();
|
||||
this.call = read();
|
||||
this.asiSafe = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "cjs full require";
|
||||
}
|
||||
}
|
||||
|
||||
CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemplate extends ModuleDependency.Template {
|
||||
/**
|
||||
* @param {Dependency} dependency the dependency for which the template should be applied
|
||||
* @param {ReplaceSource} source the current replace source which can be modified
|
||||
* @param {DependencyTemplateContext} templateContext the context object
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(
|
||||
dependency,
|
||||
source,
|
||||
{
|
||||
module,
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
runtimeRequirements,
|
||||
initFragments
|
||||
}
|
||||
) {
|
||||
const dep = /** @type {CommonJsFullRequireDependency} */ (dependency);
|
||||
if (!dep.range) return;
|
||||
const importedModule = moduleGraph.getModule(dep);
|
||||
const exports = runtimeTemplate.moduleExports({
|
||||
module: importedModule,
|
||||
chunkGraph,
|
||||
request: dep.request,
|
||||
weak: dep.weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
const exportExpr = runtimeTemplate.exportFromImport({
|
||||
moduleGraph,
|
||||
module: importedModule,
|
||||
request: dep.request,
|
||||
exportName: dep.names,
|
||||
originModule: module,
|
||||
asiSafe: dep.asiSafe,
|
||||
isCall: dep.call,
|
||||
callContext: undefined,
|
||||
defaultInterop: false,
|
||||
importVar: exports,
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
});
|
||||
source.replace(dep.range[0], dep.range[1] - 1, exportExpr);
|
||||
}
|
||||
};
|
||||
|
||||
makeSerializable(
|
||||
CommonJsFullRequireDependency,
|
||||
"webpack/lib/dependencies/CommonJsFullRequireDependency"
|
||||
);
|
||||
|
||||
module.exports = CommonJsFullRequireDependency;
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const {
|
||||
evaluateToIdentifier,
|
||||
evaluateToString,
|
||||
expressionIsUnsupported,
|
||||
toConstantDependency
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
|
||||
const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
|
||||
const CommonJsRequireDependency = require("./CommonJsRequireDependency");
|
||||
const ConstDependency = require("./ConstDependency");
|
||||
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
||||
const LocalModuleDependency = require("./LocalModuleDependency");
|
||||
const { getLocalModule } = require("./LocalModulesHelpers");
|
||||
const RequireHeaderDependency = require("./RequireHeaderDependency");
|
||||
const RequireResolveContextDependency = require("./RequireResolveContextDependency");
|
||||
const RequireResolveDependency = require("./RequireResolveDependency");
|
||||
const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
|
||||
|
||||
class CommonJsImportsParserPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
|
||||
// metadata //
|
||||
const tapRequireExpression = (expression, getMembers) => {
|
||||
parser.hooks.typeof
|
||||
.for(expression)
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("function"))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for(expression)
|
||||
.tap("CommonJsPlugin", evaluateToString("function"));
|
||||
parser.hooks.evaluateIdentifier
|
||||
.for(expression)
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
evaluateToIdentifier(expression, "require", getMembers, true)
|
||||
);
|
||||
};
|
||||
tapRequireExpression("require", () => []);
|
||||
tapRequireExpression("require.resolve", () => ["resolve"]);
|
||||
tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
|
||||
|
||||
// Weird stuff //
|
||||
parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => {
|
||||
// to not leak to global "require", we need to define a local require here.
|
||||
const dep = new ConstDependency("var require;", 0);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Unsupported //
|
||||
parser.hooks.expression
|
||||
.for("require.main.require")
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
"require.main.require is not supported by webpack."
|
||||
)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module.parent.require")
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
expressionIsUnsupported(
|
||||
parser,
|
||||
"module.parent.require is not supported by webpack."
|
||||
)
|
||||
);
|
||||
|
||||
// renaming //
|
||||
parser.hooks.canRename.for("require").tap("CommonJsPlugin", () => true);
|
||||
parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => {
|
||||
// To avoid "not defined" error, replace the value with undefined
|
||||
const dep = new ConstDependency("undefined", expr.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return false;
|
||||
});
|
||||
|
||||
// inspection //
|
||||
parser.hooks.expression
|
||||
.for("require.cache")
|
||||
.tap(
|
||||
"CommonJsImportsParserPlugin",
|
||||
toConstantDependency(parser, RuntimeGlobals.moduleCache, [
|
||||
RuntimeGlobals.moduleCache,
|
||||
RuntimeGlobals.moduleId,
|
||||
RuntimeGlobals.moduleLoaded
|
||||
])
|
||||
);
|
||||
|
||||
// require as expression //
|
||||
parser.hooks.expression
|
||||
.for("require")
|
||||
.tap("CommonJsImportsParserPlugin", expr => {
|
||||
const dep = new CommonJsRequireContextDependency(
|
||||
{
|
||||
request: options.unknownContextRequest,
|
||||
recursive: options.unknownContextRecursive,
|
||||
regExp: options.unknownContextRegExp,
|
||||
mode: "sync"
|
||||
},
|
||||
expr.range
|
||||
);
|
||||
dep.critical =
|
||||
options.unknownContextCritical &&
|
||||
"require function is used in a way in which dependencies cannot be statically extracted";
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
// require //
|
||||
const processRequireItem = (expr, param) => {
|
||||
if (param.isString()) {
|
||||
const dep = new CommonJsRequireDependency(param.string, param.range);
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processRequireContext = (expr, param) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
CommonJsRequireContextDependency,
|
||||
expr.range,
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{},
|
||||
parser
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
const createRequireHandler = callNew => expr => {
|
||||
if (expr.arguments.length !== 1) return;
|
||||
let localModule;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
let isExpression = false;
|
||||
for (const p of param.options) {
|
||||
const result = processRequireItem(expr, p);
|
||||
if (result === undefined) {
|
||||
isExpression = true;
|
||||
}
|
||||
}
|
||||
if (!isExpression) {
|
||||
const dep = new RequireHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
param.isString() &&
|
||||
(localModule = getLocalModule(parser.state, param.string))
|
||||
) {
|
||||
localModule.flagUsed();
|
||||
const dep = new LocalModuleDependency(localModule, expr.range, callNew);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
} else {
|
||||
const result = processRequireItem(expr, param);
|
||||
if (result === undefined) {
|
||||
processRequireContext(expr, param);
|
||||
} else {
|
||||
const dep = new RequireHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
parser.hooks.call
|
||||
.for("require")
|
||||
.tap("CommonJsImportsParserPlugin", createRequireHandler(false));
|
||||
parser.hooks.new
|
||||
.for("require")
|
||||
.tap("CommonJsImportsParserPlugin", createRequireHandler(true));
|
||||
parser.hooks.call
|
||||
.for("module.require")
|
||||
.tap("CommonJsImportsParserPlugin", createRequireHandler(false));
|
||||
parser.hooks.new
|
||||
.for("module.require")
|
||||
.tap("CommonJsImportsParserPlugin", createRequireHandler(true));
|
||||
|
||||
// require with property access //
|
||||
const chainHandler = (expr, calleeMembers, callExpr, members) => {
|
||||
if (callExpr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(callExpr.arguments[0]);
|
||||
if (param.isString() && !getLocalModule(parser.state, param.string)) {
|
||||
const dep = new CommonJsFullRequireDependency(
|
||||
param.string,
|
||||
expr.range,
|
||||
members
|
||||
);
|
||||
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const callChainHandler = (expr, calleeMembers, callExpr, members) => {
|
||||
if (callExpr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(callExpr.arguments[0]);
|
||||
if (param.isString() && !getLocalModule(parser.state, param.string)) {
|
||||
const dep = new CommonJsFullRequireDependency(
|
||||
param.string,
|
||||
expr.callee.range,
|
||||
members
|
||||
);
|
||||
dep.call = true;
|
||||
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
|
||||
dep.loc = expr.callee.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
parser.hooks.memberChainOfCallMemberChain
|
||||
.for("require")
|
||||
.tap("CommonJsImportsParserPlugin", chainHandler);
|
||||
parser.hooks.memberChainOfCallMemberChain
|
||||
.for("module.require")
|
||||
.tap("CommonJsImportsParserPlugin", chainHandler);
|
||||
parser.hooks.callMemberChainOfCallMemberChain
|
||||
.for("require")
|
||||
.tap("CommonJsImportsParserPlugin", callChainHandler);
|
||||
parser.hooks.callMemberChainOfCallMemberChain
|
||||
.for("module.require")
|
||||
.tap("CommonJsImportsParserPlugin", callChainHandler);
|
||||
|
||||
// require.resolve //
|
||||
const processResolve = (expr, weak) => {
|
||||
if (expr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
for (const option of param.options) {
|
||||
const result = processResolveItem(expr, option, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, option, weak);
|
||||
}
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
} else {
|
||||
const result = processResolveItem(expr, param, weak);
|
||||
if (result === undefined) {
|
||||
processResolveContext(expr, param, weak);
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processResolveItem = (expr, param, weak) => {
|
||||
if (param.isString()) {
|
||||
const dep = new RequireResolveDependency(param.string, param.range);
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
dep.weak = weak;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processResolveContext = (expr, param, weak) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
RequireResolveContextDependency,
|
||||
param.range,
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
mode: weak ? "weak" : "sync"
|
||||
},
|
||||
parser
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
parser.hooks.call
|
||||
.for("require.resolve")
|
||||
.tap("RequireResolveDependencyParserPlugin", expr => {
|
||||
return processResolve(expr, false);
|
||||
});
|
||||
parser.hooks.call
|
||||
.for("require.resolveWeak")
|
||||
.tap("RequireResolveDependencyParserPlugin", expr => {
|
||||
return processResolve(expr, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = CommonJsImportsParserPlugin;
|
|
@ -5,22 +5,27 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
const SelfModuleFactory = require("../SelfModuleFactory");
|
||||
const Template = require("../Template");
|
||||
const CommonJsExportsDependency = require("./CommonJsExportsDependency");
|
||||
const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
|
||||
const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
|
||||
const CommonJsRequireDependency = require("./CommonJsRequireDependency");
|
||||
const ConstDependency = require("./ConstDependency");
|
||||
const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
|
||||
const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
|
||||
const RequireHeaderDependency = require("./RequireHeaderDependency");
|
||||
const RequireResolveContextDependency = require("./RequireResolveContextDependency");
|
||||
const RequireResolveDependency = require("./RequireResolveDependency");
|
||||
const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
|
||||
const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency");
|
||||
|
||||
const CommonJsRequireDependencyParserPlugin = require("./CommonJsRequireDependencyParserPlugin");
|
||||
const RequireResolveDependencyParserPlugin = require("./RequireResolveDependencyParserPlugin");
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin");
|
||||
const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
|
||||
|
||||
const {
|
||||
evaluateToIdentifier,
|
||||
evaluateToString,
|
||||
toConstantDependency
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
|
||||
|
@ -43,6 +48,15 @@ class CommonJsPlugin {
|
|||
new CommonJsRequireDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
CommonJsFullRequireDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CommonJsFullRequireDependency,
|
||||
new CommonJsFullRequireDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
CommonJsRequireContextDependency,
|
||||
contextModuleFactory
|
||||
|
@ -80,72 +94,116 @@ class CommonJsPlugin {
|
|||
new RequireHeaderDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyTemplates.set(
|
||||
CommonJsExportsDependency,
|
||||
new CommonJsExportsDependency.Template()
|
||||
);
|
||||
|
||||
const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
CommonJsSelfReferenceDependency,
|
||||
selfFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CommonJsSelfReferenceDependency,
|
||||
new CommonJsSelfReferenceDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
ModuleDecoratorDependency,
|
||||
selfFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
ModuleDecoratorDependency,
|
||||
new ModuleDecoratorDependency.Template()
|
||||
);
|
||||
|
||||
compilation.hooks.runtimeRequirementInModule
|
||||
.for(RuntimeGlobals.harmonyModuleDecorator)
|
||||
.tap("CommonJsPlugin", (module, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.requireScope);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInModule
|
||||
.for(RuntimeGlobals.nodeModuleDecorator)
|
||||
.tap("CommonJsPlugin", (module, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.requireScope);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.harmonyModuleDecorator)
|
||||
.tap("CommonJsPlugin", (chunk, set) => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new HarmonyModuleDecoratorRuntimeModule()
|
||||
);
|
||||
});
|
||||
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.nodeModuleDecorator)
|
||||
.tap("CommonJsPlugin", (chunk, set) => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new NodeModuleDecoratorRuntimeModule()
|
||||
);
|
||||
});
|
||||
|
||||
const handler = (parser, parserOptions) => {
|
||||
if (parserOptions.commonjs !== undefined && !parserOptions.commonjs)
|
||||
return;
|
||||
|
||||
const tapRequireExpression = (expression, getMembers) => {
|
||||
parser.hooks.typeof
|
||||
.for(expression)
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("function"))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for(expression)
|
||||
.tap("CommonJsPlugin", evaluateToString("function"));
|
||||
parser.hooks.evaluateIdentifier
|
||||
.for(expression)
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
evaluateToIdentifier(expression, "require", getMembers, true)
|
||||
);
|
||||
};
|
||||
tapRequireExpression("require", () => []);
|
||||
tapRequireExpression("require.resolve", () => ["resolve"]);
|
||||
tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
|
||||
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("module")
|
||||
.tap("CommonJsPlugin", evaluateToString("object"));
|
||||
parser.hooks.expression.for("exports").tap("CommonJsPlugin", expr => {
|
||||
const module = parser.state.module;
|
||||
const isHarmony = parser.state.harmonyModule;
|
||||
if (!isHarmony) {
|
||||
return toConstantDependency(parser, module.exportsArgument, [
|
||||
RuntimeGlobals.exports
|
||||
])(expr);
|
||||
}
|
||||
});
|
||||
parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => {
|
||||
// to not leak to global "require", we need to define a local require here.
|
||||
const dep = new ConstDependency("var require;", 0);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.canRename
|
||||
.for("require")
|
||||
.tap("CommonJsPlugin", () => true);
|
||||
parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => {
|
||||
// To avoid "not defined" error, replace the value with undefined
|
||||
const dep = new ConstDependency("undefined", expr.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return false;
|
||||
});
|
||||
parser.hooks.typeof
|
||||
.for("module")
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("object"))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("exports")
|
||||
.tap("CommonJsPlugin", evaluateToString("object"));
|
||||
|
||||
new CommonJsRequireDependencyParserPlugin(options).apply(parser);
|
||||
new RequireResolveDependencyParserPlugin(options).apply(parser);
|
||||
parser.hooks.expression
|
||||
.for("require.main")
|
||||
.tap(
|
||||
"CommonJsPlugin",
|
||||
toConstantDependency(
|
||||
parser,
|
||||
`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
|
||||
[RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
|
||||
)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module.loaded")
|
||||
.tap("CommonJsPlugin", expr => {
|
||||
parser.state.module.buildMeta.moduleConcatenationBailout =
|
||||
"module.loaded";
|
||||
const dep = new RuntimeRequirementsDependency([
|
||||
RuntimeGlobals.moduleLoaded
|
||||
]);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
parser.hooks.expression
|
||||
.for("module.id")
|
||||
.tap("CommonJsPlugin", expr => {
|
||||
parser.state.module.buildMeta.moduleConcatenationBailout =
|
||||
"module.id";
|
||||
const dep = new RuntimeRequirementsDependency([
|
||||
RuntimeGlobals.moduleId
|
||||
]);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
parser.hooks.evaluateIdentifier.for("module.hot").tap(
|
||||
"CommonJsPlugin",
|
||||
evaluateToIdentifier("module.hot", "module", () => ["hot"], false)
|
||||
);
|
||||
|
||||
new CommonJsImportsParserPlugin(options).apply(parser);
|
||||
new CommonJsExportsParserPlugin().apply(parser);
|
||||
};
|
||||
|
||||
normalModuleFactory.hooks.parser
|
||||
|
@ -158,4 +216,57 @@ class CommonJsPlugin {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
|
||||
constructor() {
|
||||
super("harmony module decorator");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate } = this.compilation;
|
||||
return Template.asString([
|
||||
`${
|
||||
RuntimeGlobals.harmonyModuleDecorator
|
||||
} = ${runtimeTemplate.basicFunction("module", [
|
||||
"module = Object.create(module);",
|
||||
"if (!module.children) module.children = [];",
|
||||
"Object.defineProperty(module, 'exports', {",
|
||||
Template.indent([
|
||||
"enumerable: true,",
|
||||
`set: ${runtimeTemplate.basicFunction("", [
|
||||
"throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);"
|
||||
])}`
|
||||
]),
|
||||
"});",
|
||||
"return module;"
|
||||
])};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class NodeModuleDecoratorRuntimeModule extends RuntimeModule {
|
||||
constructor() {
|
||||
super("node module decorator");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate } = this.compilation;
|
||||
return Template.asString([
|
||||
`${
|
||||
RuntimeGlobals.nodeModuleDecorator
|
||||
} = ${runtimeTemplate.basicFunction("module", [
|
||||
"module.paths = [];",
|
||||
"if (!module.children) module.children = [];",
|
||||
"return module;"
|
||||
])};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CommonJsPlugin;
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const {
|
||||
toConstantDependency
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
|
||||
const CommonJsRequireDependency = require("./CommonJsRequireDependency");
|
||||
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
||||
const LocalModuleDependency = require("./LocalModuleDependency");
|
||||
const { getLocalModule } = require("./LocalModulesHelpers");
|
||||
const RequireHeaderDependency = require("./RequireHeaderDependency");
|
||||
|
||||
class CommonJsRequireDependencyParserPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
|
||||
const processItem = (expr, param) => {
|
||||
if (param.isString()) {
|
||||
const dep = new CommonJsRequireDependency(param.string, param.range);
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processContext = (expr, param) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
CommonJsRequireContextDependency,
|
||||
expr.range,
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{},
|
||||
parser
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
parser.hooks.expression
|
||||
.for("require.cache")
|
||||
.tap(
|
||||
"CommonJsRequireDependencyParserPlugin",
|
||||
toConstantDependency(parser, RuntimeGlobals.moduleCache, [
|
||||
RuntimeGlobals.moduleCache
|
||||
])
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("require")
|
||||
.tap("CommonJsRequireDependencyParserPlugin", expr => {
|
||||
const dep = new CommonJsRequireContextDependency(
|
||||
{
|
||||
request: options.unknownContextRequest,
|
||||
recursive: options.unknownContextRecursive,
|
||||
regExp: options.unknownContextRegExp,
|
||||
mode: "sync"
|
||||
},
|
||||
expr.range
|
||||
);
|
||||
dep.critical =
|
||||
options.unknownContextCritical &&
|
||||
"require function is used in a way in which dependencies cannot be statically extracted";
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
|
||||
const createHandler = callNew => expr => {
|
||||
if (expr.arguments.length !== 1) return;
|
||||
let localModule;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
let isExpression = false;
|
||||
for (const p of param.options) {
|
||||
const result = processItem(expr, p);
|
||||
if (result === undefined) {
|
||||
isExpression = true;
|
||||
}
|
||||
}
|
||||
if (!isExpression) {
|
||||
const dep = new RequireHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
param.isString() &&
|
||||
(localModule = getLocalModule(parser.state, param.string))
|
||||
) {
|
||||
localModule.flagUsed();
|
||||
const dep = new LocalModuleDependency(localModule, expr.range, callNew);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
} else {
|
||||
const result = processItem(expr, param);
|
||||
if (result === undefined) {
|
||||
processContext(expr, param);
|
||||
} else {
|
||||
const dep = new RequireHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
parser.hooks.call
|
||||
.for("require")
|
||||
.tap("CommonJsRequireDependencyParserPlugin", createHandler(false));
|
||||
parser.hooks.new
|
||||
.for("require")
|
||||
.tap("CommonJsRequireDependencyParserPlugin", createHandler(true));
|
||||
parser.hooks.call
|
||||
.for("module.require")
|
||||
.tap("CommonJsRequireDependencyParserPlugin", createHandler(false));
|
||||
parser.hooks.new
|
||||
.for("module.require")
|
||||
.tap("CommonJsRequireDependencyParserPlugin", createHandler(true));
|
||||
}
|
||||
}
|
||||
module.exports = CommonJsRequireDependencyParserPlugin;
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { UsageState } = require("../ModuleGraph");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const propertyAccess = require("../util/propertyAccess");
|
||||
const NullDependency = require("./NullDependency");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("../Dependency")} Dependency */
|
||||
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
|
||||
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
|
||||
class CommonJsSelfReferenceDependency extends NullDependency {
|
||||
constructor(range, base, names) {
|
||||
super();
|
||||
this.range = range;
|
||||
this.base = base;
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "cjs self exports reference";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `self`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of exports referenced by this dependency
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {string[][]} referenced exports
|
||||
*/
|
||||
getReferencedExports(moduleGraph) {
|
||||
return [this.names];
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.range);
|
||||
write(this.base);
|
||||
write(this.names);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.range = read();
|
||||
this.base = read();
|
||||
this.names = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
CommonJsSelfReferenceDependency,
|
||||
"webpack/lib/dependencies/CommonJsSelfReferenceDependency"
|
||||
);
|
||||
|
||||
CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependencyTemplate extends NullDependency.Template {
|
||||
/**
|
||||
* @param {Dependency} dependency the dependency for which the template should be applied
|
||||
* @param {ReplaceSource} source the current replace source which can be modified
|
||||
* @param {DependencyTemplateContext} templateContext the context object
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(
|
||||
dependency,
|
||||
source,
|
||||
{ module, moduleGraph, initFragments, runtimeRequirements }
|
||||
) {
|
||||
const dep = /** @type {CommonJsSelfReferenceDependency} */ (dependency);
|
||||
let used;
|
||||
if (dep.names.length === 0) {
|
||||
used = dep.names;
|
||||
} else if (module.buildMeta && module.buildMeta.exportsType === "default") {
|
||||
const defaultInfo = moduleGraph.getExportInfo(module, "default");
|
||||
if (defaultInfo.used === UsageState.Used) {
|
||||
used = dep.names;
|
||||
} else {
|
||||
used = defaultInfo.exportsInfo.getUsedName(dep.names);
|
||||
}
|
||||
} else {
|
||||
used = moduleGraph.getExportsInfo(module).getUsedName(dep.names);
|
||||
}
|
||||
if (!used) {
|
||||
throw new Error(
|
||||
"Self-reference dependency has unused export name: This should not happen"
|
||||
);
|
||||
}
|
||||
|
||||
let base = undefined;
|
||||
switch (dep.base) {
|
||||
case "exports":
|
||||
runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
base = module.exportsArgument;
|
||||
break;
|
||||
case "module.exports":
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
base = `${module.moduleArgument}.exports`;
|
||||
break;
|
||||
case "this":
|
||||
runtimeRequirements.add(RuntimeGlobals.thisAsExports);
|
||||
base = "this";
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported base ${dep.base}`);
|
||||
}
|
||||
|
||||
if (base === dep.base && used.join() === dep.names.join()) {
|
||||
// Nothing has to be changed
|
||||
// We don't use a replacement for compat reasons
|
||||
// for plugins that update `module._source` which they
|
||||
// shouldn't do!
|
||||
return;
|
||||
}
|
||||
|
||||
source.replace(
|
||||
dep.range[0],
|
||||
dep.range[1] - 1,
|
||||
`/* self exports access */ ${base}${propertyAccess(used)}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CommonJsSelfReferenceDependency;
|
|
@ -77,15 +77,13 @@ module.exports = class HarmonyDetectionParserPlugin {
|
|||
});
|
||||
|
||||
const skipInHarmony = () => {
|
||||
const module = parser.state.module;
|
||||
if (module && module.buildMeta && module.buildMeta.exportsType) {
|
||||
if (parser.state.harmonyModule) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const nullInHarmony = () => {
|
||||
const module = parser.state.module;
|
||||
if (module && module.buildMeta && module.buildMeta.exportsType) {
|
||||
if (parser.state.harmonyModule) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
|
|||
/** @typedef {import("../WebpackError")} WebpackError */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
|
||||
/** @typedef {"missing"|"unused"|"empty-star"|"reexport-non-harmony-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-named-namespace-object"|"reexport-fake-namespace-object"|"reexport-non-harmony-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
|
||||
/** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-dynamic-default-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
|
||||
|
||||
const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
|
||||
|
||||
|
@ -190,30 +190,35 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
return mode;
|
||||
}
|
||||
|
||||
const strictHarmonyModule = parentModule.buildMeta.strictHarmonyModule;
|
||||
const importedExportsType = importedModule.getExportsType(
|
||||
parentModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
|
||||
const isNotAHarmonyModule =
|
||||
importedModule.buildMeta && !importedModule.buildMeta.exportsType;
|
||||
const isNamedModule =
|
||||
importedModule.buildMeta &&
|
||||
importedModule.buildMeta.exportsType === "default";
|
||||
const isDynamic = importedExportsType === "dynamic";
|
||||
const isDynamicDefault = importedExportsType === "dynamic-default";
|
||||
const isDefaultOnly = importedExportsType === "default-only";
|
||||
const isDefaultWithNamed = importedExportsType === "default-with-named";
|
||||
|
||||
// Special handling for reexporting the default export
|
||||
// from non-harmony modules
|
||||
// from non-namespace modules
|
||||
if (name && ids.length > 0 && ids[0] === "default") {
|
||||
if (isNotAHarmonyModule) {
|
||||
const mode = new ExportMode("reexport-non-harmony-default");
|
||||
if (isDynamic) {
|
||||
const mode = new ExportMode("reexport-dynamic-default");
|
||||
|
||||
mode.name = name;
|
||||
|
||||
return mode;
|
||||
} else if (isNamedModule) {
|
||||
} else if (isDefaultOnly || isDefaultWithNamed) {
|
||||
const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
|
||||
const mode = new ExportMode("reexport-named-default");
|
||||
|
||||
mode.name = name;
|
||||
mode.partialNamespaceExportInfo = exportInfo;
|
||||
|
||||
return mode;
|
||||
} else if (isDynamicDefault) {
|
||||
const mode = new ExportMode("reexport-dynamic-default-default");
|
||||
mode.name = name;
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
@ -225,8 +230,8 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
|
||||
if (ids.length > 0) {
|
||||
// export { name as name }
|
||||
if ((isNotAHarmonyModule || isNamedModule) && strictHarmonyModule) {
|
||||
mode = new ExportMode("reexport-non-harmony-undefined");
|
||||
if (isDefaultOnly || isDynamicDefault) {
|
||||
mode = new ExportMode("reexport-undefined");
|
||||
mode.name = name;
|
||||
} else {
|
||||
mode = new ExportMode("normal-reexport");
|
||||
|
@ -235,14 +240,16 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
}
|
||||
} else {
|
||||
// export { * as name }
|
||||
if (isNotAHarmonyModule && strictHarmonyModule) {
|
||||
if (isDefaultOnly || isDynamicDefault) {
|
||||
mode = new ExportMode("reexport-fake-namespace-object");
|
||||
mode.name = name;
|
||||
} else if (isNamedModule) {
|
||||
mode = new ExportMode("reexport-fake-named-namespace-object");
|
||||
mode.partialNamespaceExportInfo = exportInfo;
|
||||
mode.fakeType = 0;
|
||||
} else if (isDefaultWithNamed) {
|
||||
mode = new ExportMode("reexport-fake-namespace-object");
|
||||
mode.name = name;
|
||||
mode.partialNamespaceExportInfo = exportInfo;
|
||||
mode.fakeType = strictHarmonyModule ? 0 : 2;
|
||||
mode.fakeType = 2;
|
||||
} else {
|
||||
mode = new ExportMode("reexport-namespace-object");
|
||||
mode.name = name;
|
||||
|
@ -363,10 +370,10 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
case "missing":
|
||||
case "unused":
|
||||
case "empty-star":
|
||||
case "reexport-non-harmony-undefined":
|
||||
case "reexport-undefined":
|
||||
return Dependency.NO_EXPORTS_REFERENCED;
|
||||
|
||||
case "reexport-non-harmony-default":
|
||||
case "reexport-dynamic-default":
|
||||
return Dependency.DEFAULT_EXPORT_REFERENCED;
|
||||
|
||||
case "reexport-named-default": {
|
||||
|
@ -383,7 +390,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
}
|
||||
|
||||
case "reexport-namespace-object":
|
||||
case "reexport-fake-named-namespace-object": {
|
||||
case "reexport-fake-namespace-object": {
|
||||
if (!mode.partialNamespaceExportInfo)
|
||||
return Dependency.NS_OBJECT_REFERENCED;
|
||||
/** @type {string[][]} */
|
||||
|
@ -396,8 +403,8 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
return referencedExports;
|
||||
}
|
||||
|
||||
case "reexport-fake-namespace-object":
|
||||
case "dynamic-reexport":
|
||||
case "reexport-dynamic-default-default":
|
||||
return Dependency.NS_OBJECT_REFERENCED;
|
||||
|
||||
case "normal-reexport":
|
||||
|
@ -468,14 +475,14 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
})),
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "reexport-fake-namespace-object":
|
||||
case "reexport-non-harmony-default":
|
||||
case "reexport-non-harmony-undefined":
|
||||
case "reexport-dynamic-default":
|
||||
case "reexport-dynamic-default-default":
|
||||
case "reexport-undefined":
|
||||
return {
|
||||
exports: [mode.name],
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "reexport-fake-named-namespace-object":
|
||||
case "reexport-fake-namespace-object":
|
||||
case "reexport-namespace-object":
|
||||
return {
|
||||
exports: [
|
||||
|
@ -678,23 +685,33 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|||
);
|
||||
break;
|
||||
|
||||
case "reexport-non-harmony-default":
|
||||
case "reexport-dynamic-default":
|
||||
initFragments.push(
|
||||
this.getReexportFragment(
|
||||
module,
|
||||
"reexport default from non-harmony",
|
||||
"reexport default from dynamic",
|
||||
module.getUsedName(moduleGraph, mode.name),
|
||||
importVar,
|
||||
module.buildMeta && module.buildMeta.strictHarmonyModule
|
||||
? ""
|
||||
: null,
|
||||
null,
|
||||
runtimeRequirements
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case "reexport-dynamic-default-default":
|
||||
initFragments.push(
|
||||
this.getReexportFragment(
|
||||
module,
|
||||
"reexport dynamic as default",
|
||||
module.getUsedName(moduleGraph, mode.name),
|
||||
importVar,
|
||||
"",
|
||||
runtimeRequirements
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case "reexport-fake-namespace-object":
|
||||
case "reexport-fake-named-namespace-object":
|
||||
initFragments.push(
|
||||
...this.getReexportFakeNamespaceObjectFragments(
|
||||
module,
|
||||
|
@ -706,7 +723,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|||
);
|
||||
break;
|
||||
|
||||
case "reexport-non-harmony-undefined":
|
||||
case "reexport-undefined":
|
||||
initFragments.push(
|
||||
this.getReexportFragment(
|
||||
module,
|
||||
|
|
|
@ -94,68 +94,68 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
return;
|
||||
}
|
||||
|
||||
const exportsType =
|
||||
importedModule.buildMeta && importedModule.buildMeta.exportsType;
|
||||
if (!exportsType) {
|
||||
// It's not an harmony module
|
||||
if (
|
||||
ids.length > 0 &&
|
||||
ids[0] !== "default" &&
|
||||
moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
|
||||
) {
|
||||
// In strict harmony modules we only support the default export
|
||||
const parentModule = moduleGraph.getParentModule(this);
|
||||
const exportsType = importedModule.getExportsType(
|
||||
parentModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
switch (exportsType) {
|
||||
case "default-only":
|
||||
case "dynamic-default":
|
||||
// It's has only a default export
|
||||
if (ids.length > 0 && ids[0] !== "default") {
|
||||
// In strict harmony modules we only support the default export
|
||||
return [
|
||||
new HarmonyLinkingError(
|
||||
`Can't import the named export ${ids
|
||||
.map(id => `'${id}'`)
|
||||
.join(
|
||||
"."
|
||||
)} ${additionalMessage} from default-exporting module (only default export is available)`
|
||||
)
|
||||
];
|
||||
}
|
||||
return;
|
||||
case "default-with-named":
|
||||
// It has a default export and named properties redirect
|
||||
// In some cases we still want to warn here
|
||||
if (
|
||||
ids.length > 0 &&
|
||||
ids[0] !== "default" &&
|
||||
importedModule.buildMeta.defaultObject === "redirect-warn"
|
||||
) {
|
||||
// For these modules only the default export is supported
|
||||
return [
|
||||
new HarmonyLinkingError(
|
||||
`Should not import the named export ${ids
|
||||
.map(id => `'${id}'`)
|
||||
.join(
|
||||
"."
|
||||
)} ${additionalMessage} from default-exporting module (only default export is available soon)`
|
||||
)
|
||||
];
|
||||
}
|
||||
return;
|
||||
case "namespace":
|
||||
if (ids.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleGraph.isExportProvided(importedModule, ids) !== false) {
|
||||
// It's provided or we are not sure
|
||||
return;
|
||||
}
|
||||
|
||||
// We are sure that it's not provided
|
||||
return [
|
||||
new HarmonyLinkingError(
|
||||
`Can't import the named export ${ids
|
||||
`export ${ids
|
||||
.map(id => `'${id}'`)
|
||||
.join(
|
||||
"."
|
||||
)} ${additionalMessage} from non EcmaScript module (only default export is available)`
|
||||
.join(".")} ${additionalMessage} was not found in '${
|
||||
this.userRequest
|
||||
}'`
|
||||
)
|
||||
];
|
||||
}
|
||||
return;
|
||||
} else if (exportsType === "default") {
|
||||
if (
|
||||
ids.length > 0 &&
|
||||
ids[0] !== "default" &&
|
||||
(moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
|
||||
? importedModule.buildMeta.defaultObject !== "redirect"
|
||||
: importedModule.buildMeta.defaultObject === false)
|
||||
) {
|
||||
// For these modules only the default export is supported
|
||||
return [
|
||||
new HarmonyLinkingError(
|
||||
`Can't import the named export ${ids
|
||||
.map(id => `'${id}'`)
|
||||
.join(
|
||||
"."
|
||||
)} ${additionalMessage} from default-exporting module (only default export is available)`
|
||||
)
|
||||
];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ids.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleGraph.isExportProvided(importedModule, ids) !== false) {
|
||||
// It's provided or we are not sure
|
||||
return;
|
||||
}
|
||||
|
||||
// We are sure that it's not provided
|
||||
return [
|
||||
new HarmonyLinkingError(
|
||||
`export ${ids
|
||||
.map(id => `'${id}'`)
|
||||
.join(".")} ${additionalMessage} was not found in '${
|
||||
this.userRequest
|
||||
}'`
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,12 +167,15 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
updateHash(hash, chunkGraph) {
|
||||
super.updateHash(hash, chunkGraph);
|
||||
const importedModule = chunkGraph.moduleGraph.getModule(this);
|
||||
hash.update(
|
||||
(importedModule &&
|
||||
(!importedModule.buildMeta || importedModule.buildMeta.exportsType)) +
|
||||
""
|
||||
);
|
||||
if (chunkGraph.moduleGraph.isAsync(importedModule)) hash.update("async");
|
||||
if (importedModule) {
|
||||
const parentModule = chunkGraph.moduleGraph.getParentModule(this);
|
||||
hash.update(
|
||||
importedModule.getExportsType(
|
||||
parentModule.buildMeta && parentModule.buildMeta.strictHarmonyModule
|
||||
)
|
||||
);
|
||||
if (chunkGraph.moduleGraph.isAsync(importedModule)) hash.update("async");
|
||||
}
|
||||
hash.update(`${this.sourceOrder}`);
|
||||
if (this.await) hash.update("await");
|
||||
}
|
||||
|
|
|
@ -171,9 +171,6 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
if (importedModule) {
|
||||
const exportsInfo = moduleGraph.getExportsInfo(importedModule);
|
||||
hash.update(`${exportsInfo.getUsedName(ids)}`);
|
||||
hash.update(
|
||||
(!importedModule.buildMeta || importedModule.buildMeta.exportsType) + ""
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,6 +243,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|||
asiSafe: dep.asiSafe || dep.shorthand,
|
||||
isCall: dep.call,
|
||||
callContext: !dep.directImport,
|
||||
defaultInterop: true,
|
||||
importVar: dep.getImportVar(moduleGraph),
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
|
|
|
@ -18,6 +18,7 @@ class HarmonyTopLevelThisParserPlugin {
|
|||
const dep = new ConstDependency("undefined", node.range, null);
|
||||
dep.loc = node.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -34,6 +34,22 @@ class ModuleDecoratorDependency extends NullDependency {
|
|||
return "module decorator";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `self`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of exports referenced by this dependency
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {string[][]} referenced exports
|
||||
*/
|
||||
getReferencedExports(moduleGraph) {
|
||||
return [[]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the hash
|
||||
* @param {Hash} hash hash to be updated
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const Dependency = require("../Dependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ModuleDependency = require("./ModuleDependency");
|
||||
const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId");
|
||||
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
|
||||
class RequireResolveDependency extends ModuleDependency {
|
||||
constructor(request, range) {
|
||||
super(request);
|
||||
|
@ -20,6 +23,16 @@ class RequireResolveDependency extends ModuleDependency {
|
|||
return "require.resolve";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of exports referenced by this dependency
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {string[][]} referenced exports
|
||||
*/
|
||||
getReferencedExports(moduleGraph) {
|
||||
// This doesn't use any export
|
||||
return Dependency.NO_EXPORTS_REFERENCED;
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
||||
const RequireResolveContextDependency = require("./RequireResolveContextDependency");
|
||||
const RequireResolveDependency = require("./RequireResolveDependency");
|
||||
const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
|
||||
|
||||
class RequireResolveDependencyParserPlugin {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
|
||||
const process = (expr, weak) => {
|
||||
if (expr.arguments.length !== 1) return;
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
if (param.isConditional()) {
|
||||
for (const option of param.options) {
|
||||
const result = processItem(expr, option, weak);
|
||||
if (result === undefined) {
|
||||
processContext(expr, option, weak);
|
||||
}
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
} else {
|
||||
const result = processItem(expr, param, weak);
|
||||
if (result === undefined) {
|
||||
processContext(expr, param, weak);
|
||||
}
|
||||
const dep = new RequireResolveHeaderDependency(expr.callee.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processItem = (expr, param, weak) => {
|
||||
if (param.isString()) {
|
||||
const dep = new RequireResolveDependency(param.string, param.range);
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
dep.weak = weak;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const processContext = (expr, param, weak) => {
|
||||
const dep = ContextDependencyHelpers.create(
|
||||
RequireResolveContextDependency,
|
||||
param.range,
|
||||
param,
|
||||
expr,
|
||||
options,
|
||||
{
|
||||
mode: weak ? "weak" : "sync"
|
||||
},
|
||||
parser
|
||||
);
|
||||
if (!dep) return;
|
||||
dep.loc = expr.loc;
|
||||
dep.optional = !!parser.scope.inTry;
|
||||
parser.state.current.addDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
parser.hooks.call
|
||||
.for("require.resolve")
|
||||
.tap("RequireResolveDependencyParserPlugin", expr => {
|
||||
return process(expr, false);
|
||||
});
|
||||
parser.hooks.call
|
||||
.for("require.resolveWeak")
|
||||
.tap("RequireResolveDependencyParserPlugin", expr => {
|
||||
return process(expr, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = RequireResolveDependencyParserPlugin;
|
|
@ -10,6 +10,7 @@ const { SyncBailHook, HookMap } = require("tapable");
|
|||
const vm = require("vm");
|
||||
const Parser = require("../Parser");
|
||||
const StackedMap = require("../util/StackedMap");
|
||||
const memorize = require("../util/memorize");
|
||||
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
||||
|
||||
/** @typedef {import("acorn").Options} AcornOptions */
|
||||
|
@ -41,6 +42,8 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|||
/** @typedef {import("../Parser").ParserState} ParserState */
|
||||
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
||||
|
||||
const EMPTY_ARRAY = [];
|
||||
|
||||
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
||||
|
||||
const parser = AcornParser.extend(require("../parsing/importAwaitAcornPlugin"));
|
||||
|
@ -84,6 +87,25 @@ const joinRanges = (startRange, endRange) => {
|
|||
return [startRange[0], endRange[1]];
|
||||
};
|
||||
|
||||
const objectAndMembersToName = (object, membersReversed) => {
|
||||
let name = object;
|
||||
for (let i = membersReversed.length - 1; i >= 0; i--) {
|
||||
name = name + "." + membersReversed[i];
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const getRootName = expression => {
|
||||
switch (expression.type) {
|
||||
case "Identifier":
|
||||
return expression.name;
|
||||
case "ThisExpression":
|
||||
return "this";
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {AcornOptions} */
|
||||
const defaultParserOptions = {
|
||||
ranges: true,
|
||||
|
@ -186,6 +208,10 @@ class JavascriptParser extends Parser {
|
|||
rename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
||||
/** @type {HookMap<SyncBailHook<[import("estree").AssignmentExpression], boolean | void>>} */
|
||||
assign: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[import("estree").AssignmentExpression, string[]], boolean | void>>} */
|
||||
assignMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
typeof: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {SyncBailHook<[ExpressionNode], boolean | void>} */
|
||||
|
@ -194,15 +220,38 @@ class JavascriptParser extends Parser {
|
|||
topLevelAwait: new SyncBailHook(["expression"]),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
call: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, any[]], boolean | void>>} */
|
||||
/** Something like "a.b()" */
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
|
||||
callMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
/** Something like "a.b().c.d" */
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[], CallExpressionNode, string[]], boolean | void>>} */
|
||||
memberChainOfCallMemberChain: new HookMap(
|
||||
() =>
|
||||
new SyncBailHook([
|
||||
"expression",
|
||||
"calleeMembers",
|
||||
"callExpression",
|
||||
"members"
|
||||
])
|
||||
),
|
||||
/** Something like "a.b().c.d()"" */
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[], CallExpressionNode, string[]], boolean | void>>} */
|
||||
callMemberChainOfCallMemberChain: new HookMap(
|
||||
() =>
|
||||
new SyncBailHook([
|
||||
"expression",
|
||||
"calleeMembers",
|
||||
"innerCallExpression",
|
||||
"members"
|
||||
])
|
||||
),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
new: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
expression: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, any[]], boolean | void>>} */
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
|
||||
expressionMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
|
@ -219,6 +268,7 @@ class JavascriptParser extends Parser {
|
|||
this.sourceType = sourceType;
|
||||
/** @type {ScopeInfo} */
|
||||
this.scope = undefined;
|
||||
/** @type {ParserState} */
|
||||
this.state = undefined;
|
||||
this.comments = undefined;
|
||||
this.semicolons = undefined;
|
||||
|
@ -1996,6 +2046,23 @@ class JavascriptParser extends Parser {
|
|||
}
|
||||
});
|
||||
this.walkPattern(expression.left);
|
||||
} else if (expression.left.type === "MemberExpression") {
|
||||
const exprName = this.getMemberExpressionInfo(expression.left, [
|
||||
"expression"
|
||||
]);
|
||||
if (exprName) {
|
||||
if (
|
||||
this.callHooksForInfo(
|
||||
this.hooks.assignMemberChain,
|
||||
exprName.rootInfo,
|
||||
expression,
|
||||
exprName.getMembers()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.walkExpression(expression.left);
|
||||
} else {
|
||||
this.walkExpression(expression.left);
|
||||
}
|
||||
|
@ -2140,6 +2207,22 @@ class JavascriptParser extends Parser {
|
|||
// (function(…) { }(…))
|
||||
this._walkIIFE(expression.callee, expression.arguments, null);
|
||||
} else {
|
||||
if (expression.callee.type === "MemberExpression") {
|
||||
const exprInfo = this.getMemberExpressionInfo(expression.callee, [
|
||||
"call"
|
||||
]);
|
||||
if (exprInfo && exprInfo.type === "call") {
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.callMemberChainOfCallMemberChain,
|
||||
exprInfo.rootInfo,
|
||||
expression,
|
||||
exprInfo.getCalleeMembers(),
|
||||
exprInfo.call,
|
||||
exprInfo.getMembers()
|
||||
);
|
||||
if (result === true) return;
|
||||
}
|
||||
}
|
||||
const callee = this.evaluateExpression(expression.callee);
|
||||
if (callee.isIdentifier()) {
|
||||
const result1 = this.callHooksForInfo(
|
||||
|
@ -2157,40 +2240,72 @@ class JavascriptParser extends Parser {
|
|||
if (result2 === true) return;
|
||||
}
|
||||
|
||||
if (expression.callee) this.walkExpression(expression.callee);
|
||||
if (expression.callee) {
|
||||
if (expression.callee.type === "MemberExpression") {
|
||||
// because of call context we need to walk the call context as expression
|
||||
this.walkExpression(expression.callee.object);
|
||||
if (expression.callee.computed === true)
|
||||
this.walkExpression(expression.callee.property);
|
||||
} else {
|
||||
this.walkExpression(expression.callee);
|
||||
}
|
||||
}
|
||||
if (expression.arguments) this.walkExpressions(expression.arguments);
|
||||
}
|
||||
}
|
||||
|
||||
walkMemberExpression(expression) {
|
||||
const exprName = this.getNameForExpression(expression);
|
||||
if (exprName) {
|
||||
this.walkMemberExpressionWithExpressionName(
|
||||
expression,
|
||||
exprName.name,
|
||||
exprName.rootInfo,
|
||||
exprName.getMembers()
|
||||
);
|
||||
return;
|
||||
const exprInfo = this.getMemberExpressionInfo(expression, [
|
||||
"call",
|
||||
"expression"
|
||||
]);
|
||||
if (exprInfo) {
|
||||
switch (exprInfo.type) {
|
||||
case "expression": {
|
||||
const members = exprInfo.getMembers();
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.expressionMemberChain,
|
||||
exprInfo.rootInfo,
|
||||
expression,
|
||||
members
|
||||
);
|
||||
if (result === true) return;
|
||||
this.walkMemberExpressionWithExpressionName(
|
||||
expression,
|
||||
exprInfo.name,
|
||||
exprInfo.rootInfo,
|
||||
members
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "call": {
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.memberChainOfCallMemberChain,
|
||||
exprInfo.rootInfo,
|
||||
expression,
|
||||
exprInfo.getCalleeMembers(),
|
||||
exprInfo.call,
|
||||
exprInfo.getMembers()
|
||||
);
|
||||
if (result === true) return;
|
||||
// Fast skip over the member chain as we already called memberChainOfCallMemberChain
|
||||
// and call computed property are literals anyway
|
||||
this.walkExpression(exprInfo.call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.walkExpression(expression.object);
|
||||
if (expression.computed === true) this.walkExpression(expression.property);
|
||||
}
|
||||
|
||||
walkMemberExpressionWithExpressionName(expression, name, rootInfo, members) {
|
||||
const result1 = this.callHooksForInfo(
|
||||
this.hooks.expressionMemberChain,
|
||||
rootInfo,
|
||||
expression,
|
||||
members
|
||||
);
|
||||
if (result1 === true) return;
|
||||
const result2 = this.callHooksForInfo(
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.expression,
|
||||
name,
|
||||
expression
|
||||
);
|
||||
if (result2 === true) return;
|
||||
if (result === true) return;
|
||||
if (expression.object.type === "MemberExpression") {
|
||||
// optimize case where expression.object is a MemberExpression too.
|
||||
// we can keep info here when calling walkMemberExpression directly
|
||||
|
@ -2219,7 +2334,7 @@ class JavascriptParser extends Parser {
|
|||
}
|
||||
|
||||
callHooksForExpression(hookMap, expr, ...args) {
|
||||
const exprName = this.getNameForExpression(expr);
|
||||
const exprName = this.getMemberExpressionInfo(expr, ["expression"]);
|
||||
if (exprName !== undefined) {
|
||||
return this.callHooksForInfoWithFallback(
|
||||
hookMap,
|
||||
|
@ -2235,7 +2350,7 @@ class JavascriptParser extends Parser {
|
|||
* @template T
|
||||
* @template R
|
||||
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
||||
* @param {ExpressionNode} expr expression info
|
||||
* @param {MemberExpressionNode} expr expression info
|
||||
* @param {function(string, string | ScopeInfo | VariableInfo, function(): string[]): any} fallback callback when variable in not handled by hooks
|
||||
* @param {function(string): any} defined callback when variable is defined
|
||||
* @param {AsArray<T>} args args for the hook
|
||||
|
@ -2248,7 +2363,7 @@ class JavascriptParser extends Parser {
|
|||
defined,
|
||||
...args
|
||||
) {
|
||||
const exprName = this.getNameForExpression(expr);
|
||||
const exprName = this.getMemberExpressionInfo(expr, ["expression"]);
|
||||
if (exprName !== undefined) {
|
||||
return this.callHooksForInfoWithFallback(
|
||||
hookMap,
|
||||
|
@ -2677,6 +2792,7 @@ class JavascriptParser extends Parser {
|
|||
isStrict: false,
|
||||
definitions: new StackedMap()
|
||||
};
|
||||
/** @type {ParserState} */
|
||||
this.state = state;
|
||||
this.comments = comments;
|
||||
this.semicolons = semicolons;
|
||||
|
@ -2691,6 +2807,7 @@ class JavascriptParser extends Parser {
|
|||
}
|
||||
this.hooks.finish.call(ast, comments);
|
||||
this.scope = oldScope;
|
||||
/** @type {ParserState} */
|
||||
this.state = oldState;
|
||||
this.comments = oldComments;
|
||||
this.semicolons = oldSemicolons;
|
||||
|
@ -2843,60 +2960,112 @@ class JavascriptParser extends Parser {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {ExpressionNode} expression an expression
|
||||
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]}} name info
|
||||
* @param {MemberExpressionNode} expression an member expression
|
||||
* @returns {{ members: string[], object: ExpressionNode | SuperNode }} member names (reverse order) and remaining object
|
||||
*/
|
||||
getNameForExpression(expression) {
|
||||
extractMemberExpressionChain(expression) {
|
||||
/** @type {AnyNode} */
|
||||
let expr = expression;
|
||||
const exprName = [];
|
||||
const members = [];
|
||||
while (expr.type === "MemberExpression") {
|
||||
if (expr.object.type === "Super") return undefined;
|
||||
if (expr.computed) {
|
||||
if (expr.property.type !== "Literal") break;
|
||||
exprName.push(`${expr.property.value}`);
|
||||
members.push(`${expr.property.value}`);
|
||||
} else {
|
||||
if (expr.property.type !== "Identifier") break;
|
||||
exprName.push(expr.property.name);
|
||||
members.push(expr.property.name);
|
||||
}
|
||||
expr = expr.object;
|
||||
}
|
||||
let rootName;
|
||||
if (expr.type === "Identifier") {
|
||||
rootName = expr.name;
|
||||
} else if (expr.type === "ThisExpression") {
|
||||
rootName = "this";
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
const rootInfo = this.getVariableInfo(rootName);
|
||||
/** @type {string | ScopeInfo | true} */
|
||||
let resolvedRoot;
|
||||
if (rootInfo instanceof VariableInfo) {
|
||||
resolvedRoot = rootInfo.freeName;
|
||||
} else {
|
||||
resolvedRoot = rootInfo;
|
||||
}
|
||||
if (typeof resolvedRoot !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
let name = resolvedRoot;
|
||||
for (let i = exprName.length - 1; i >= 0; i--) {
|
||||
name = name + "." + exprName[i];
|
||||
}
|
||||
let reversed = false;
|
||||
return {
|
||||
name,
|
||||
rootInfo,
|
||||
getMembers: () => {
|
||||
if (!reversed) {
|
||||
exprName.reverse();
|
||||
reversed = true;
|
||||
}
|
||||
return exprName;
|
||||
}
|
||||
members,
|
||||
object: expr
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} varName variable name
|
||||
* @returns {{name: string, info: VariableInfo | string}} name of the free variable and variable info for that
|
||||
*/
|
||||
getFreeInfoFromVariable(varName) {
|
||||
const info = this.getVariableInfo(varName);
|
||||
let name;
|
||||
if (info instanceof VariableInfo) {
|
||||
name = info.freeName;
|
||||
if (typeof name !== "string") return undefined;
|
||||
} else if (typeof info !== "string") {
|
||||
return undefined;
|
||||
} else {
|
||||
name = info;
|
||||
}
|
||||
return { info, name };
|
||||
}
|
||||
|
||||
/** @typedef {{ type: "call", call: CallExpressionNode, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[]}} CallExpressionInfo */
|
||||
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[]}} ExpressionExpressionInfo */
|
||||
|
||||
/**
|
||||
* @param {MemberExpressionNode} expression an member expression
|
||||
* @param {("call"|"expression")[]} allowedTypes which types should be returned
|
||||
* @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
|
||||
*/
|
||||
getMemberExpressionInfo(expression, allowedTypes) {
|
||||
const possibleTypes = new Set(allowedTypes);
|
||||
const { object, members } = this.extractMemberExpressionChain(expression);
|
||||
switch (object.type) {
|
||||
case "CallExpression": {
|
||||
if (!possibleTypes.has("call")) return undefined;
|
||||
let callee = object.callee;
|
||||
let rootMembers = EMPTY_ARRAY;
|
||||
if (callee.type === "MemberExpression") {
|
||||
({
|
||||
object: callee,
|
||||
members: rootMembers
|
||||
} = this.extractMemberExpressionChain(callee));
|
||||
}
|
||||
const rootName = getRootName(callee);
|
||||
if (!rootName) return undefined;
|
||||
const result = this.getFreeInfoFromVariable(rootName);
|
||||
if (!result) return undefined;
|
||||
const { info: rootInfo, name: resolvedRoot } = result;
|
||||
const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
|
||||
return {
|
||||
type: "call",
|
||||
call: object,
|
||||
calleeName,
|
||||
rootInfo,
|
||||
getCalleeMembers: memorize(() => rootMembers.reverse()),
|
||||
name: objectAndMembersToName(`${calleeName}()`, members),
|
||||
getMembers: memorize(() => members.reverse())
|
||||
};
|
||||
}
|
||||
case "Identifier":
|
||||
case "ThisExpression": {
|
||||
if (!possibleTypes.has("expression")) return undefined;
|
||||
const rootName = getRootName(object);
|
||||
if (!rootName) return undefined;
|
||||
|
||||
const result = this.getFreeInfoFromVariable(rootName);
|
||||
if (!result) return undefined;
|
||||
const { info: rootInfo, name: resolvedRoot } = result;
|
||||
return {
|
||||
type: "expression",
|
||||
name: objectAndMembersToName(resolvedRoot, members),
|
||||
rootInfo,
|
||||
getMembers: memorize(() => members.reverse())
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MemberExpressionNode} expression an expression
|
||||
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]}} name info
|
||||
*/
|
||||
getNameForExpression(expression) {
|
||||
return this.getMemberExpressionInfo(expression, ["expression"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code source code
|
||||
* @param {ParseOptions} options parsing options
|
||||
|
|
|
@ -44,7 +44,8 @@ class JsonParser extends Parser {
|
|||
state.module.buildInfo.jsonData = data;
|
||||
state.module.buildInfo.strict = true;
|
||||
state.module.buildMeta.exportsType = "default";
|
||||
state.module.buildMeta.defaultObject = true;
|
||||
state.module.buildMeta.defaultObject =
|
||||
typeof data === "object" ? "redirect-warn" : false;
|
||||
state.module.addDependency(
|
||||
new JsonExportsDependency(JsonExportsDependency.getExportsFromData(data))
|
||||
);
|
||||
|
|
|
@ -232,48 +232,50 @@ const getExternalImport = (
|
|||
? ""
|
||||
: Template.toNormalComment(`${exportName.join(".")}`);
|
||||
let exprStart;
|
||||
const exportsType = importedModule.getExportsType(strictHarmonyModule);
|
||||
if (exportName.length === 0) {
|
||||
switch (importedModule.buildMeta.exportsType) {
|
||||
case "default":
|
||||
switch (exportsType) {
|
||||
case "dynamic-default":
|
||||
case "default-only":
|
||||
case "default-with-named":
|
||||
info.interopNamespaceObjectUsed = true;
|
||||
exprStart = info.interopNamespaceObjectName;
|
||||
break;
|
||||
case "namespace":
|
||||
exprStart = info.name;
|
||||
break;
|
||||
case "dynamic":
|
||||
exprStart = info.name;
|
||||
break;
|
||||
default:
|
||||
if (strictHarmonyModule) {
|
||||
info.interopNamespaceObjectUsed = true;
|
||||
exprStart = info.interopNamespaceObjectName;
|
||||
break;
|
||||
} else {
|
||||
exprStart = info.name;
|
||||
break;
|
||||
}
|
||||
throw new Error(`Unexpected exportsType ${exportsType}`);
|
||||
}
|
||||
} else {
|
||||
switch (importedModule.buildMeta.exportsType) {
|
||||
case "default":
|
||||
switch (exportsType) {
|
||||
case "default-with-named":
|
||||
case "namespace":
|
||||
break;
|
||||
default:
|
||||
if (strictHarmonyModule) {
|
||||
if (exportName[0] === "default") {
|
||||
exprStart = info.name;
|
||||
} else {
|
||||
exprStart = "/* non-default import from non-esm module */undefined";
|
||||
}
|
||||
case "default-only":
|
||||
case "dynamic-default":
|
||||
if (exportName[0] === "default") {
|
||||
exprStart = info.name;
|
||||
} else {
|
||||
if (exportName[0] === "default") {
|
||||
info.interopDefaultAccessUsed = true;
|
||||
exprStart = asCall
|
||||
? `${info.interopDefaultAccessName}()`
|
||||
: asiSafe
|
||||
? `(${info.interopDefaultAccessName}())`
|
||||
: `${info.interopDefaultAccessName}.a`;
|
||||
}
|
||||
exprStart =
|
||||
"/* non-default import from default-exporting module */undefined";
|
||||
}
|
||||
break;
|
||||
case "dynamic":
|
||||
if (exportName[0] === "default") {
|
||||
info.interopDefaultAccessUsed = true;
|
||||
exprStart = asCall
|
||||
? `${info.interopDefaultAccessName}()`
|
||||
: asiSafe
|
||||
? `(${info.interopDefaultAccessName}())`
|
||||
: `${info.interopDefaultAccessName}.a`;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unexpected exportsType ${exportsType}`);
|
||||
}
|
||||
}
|
||||
if (exprStart) {
|
||||
|
@ -978,6 +980,7 @@ class ConcatenatedModule extends Module {
|
|||
info.name = externalName;
|
||||
if (
|
||||
info.module.buildMeta.exportsType === "default" ||
|
||||
info.module.buildMeta.exportsType === "flagged" ||
|
||||
!info.module.buildMeta.exportsType
|
||||
) {
|
||||
const externalNameInterop = this.findNewName(
|
||||
|
@ -1090,7 +1093,10 @@ class ConcatenatedModule extends Module {
|
|||
result.add(
|
||||
`var ${info.interopNamespaceObjectName} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${info.name}, 2);\n`
|
||||
);
|
||||
} else if (!info.module.buildMeta.exportsType) {
|
||||
} else if (
|
||||
info.module.buildMeta.exportsType === "flagged" ||
|
||||
!info.module.buildMeta.exportsType
|
||||
) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
result.add(
|
||||
`var ${info.interopNamespaceObjectName} = /*#__PURE__*/${RuntimeGlobals.createFakeNamespaceObject}(${info.name});\n`
|
||||
|
|
|
@ -32,8 +32,14 @@ module.exports = {
|
|||
require("../dependencies/CachedConstDependency"),
|
||||
"dependencies/CommonJsRequireContextDependency": () =>
|
||||
require("../dependencies/CommonJsRequireContextDependency"),
|
||||
"dependencies/CommonJsExportsDependency": () =>
|
||||
require("../dependencies/CommonJsExportsDependency"),
|
||||
"dependencies/CommonJsFullRequireDependency": () =>
|
||||
require("../dependencies/CommonJsFullRequireDependency"),
|
||||
"dependencies/CommonJsRequireDependency": () =>
|
||||
require("../dependencies/CommonJsRequireDependency"),
|
||||
"dependencies/CommonJsSelfReferenceDependency": () =>
|
||||
require("../dependencies/CommonJsSelfReferenceDependency"),
|
||||
"dependencies/ConstDependency": () =>
|
||||
require("../dependencies/ConstDependency"),
|
||||
"dependencies/ContextDependency": () =>
|
||||
|
|
|
@ -57,6 +57,7 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
|
|||
runtimeRequirements
|
||||
} = generateContext;
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
runtimeRequirements.add(RuntimeGlobals.moduleId);
|
||||
runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
runtimeRequirements.add(RuntimeGlobals.instantiateWasm);
|
||||
/** @type {InitFragment[]} */
|
||||
|
@ -120,6 +121,7 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
|
|||
asiSafe: true,
|
||||
isCall: false,
|
||||
callContext: false,
|
||||
defaultInterop: true,
|
||||
importVar,
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
|
@ -143,7 +145,7 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
|
|||
: undefined;
|
||||
|
||||
const instantiateCall =
|
||||
`${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${module.moduleArgument}.i` +
|
||||
`${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${module.moduleArgument}.id` +
|
||||
(importsObj ? `, ${importsObj})` : `)`);
|
||||
|
||||
const source = new RawSource(
|
||||
|
|
|
@ -100,6 +100,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
|
|||
asiSafe: true,
|
||||
isCall: false,
|
||||
callContext: null,
|
||||
defaultInterop: true,
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
})
|
||||
|
@ -127,6 +128,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
|
|||
asiSafe: true,
|
||||
isCall: false,
|
||||
callContext: null,
|
||||
defaultInterop: true,
|
||||
initFragments,
|
||||
runtimeRequirements
|
||||
})};`,
|
||||
|
@ -164,6 +166,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
|
|||
|
||||
// need these globals
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
runtimeRequirements.add(RuntimeGlobals.moduleId);
|
||||
runtimeRequirements.add(RuntimeGlobals.wasmInstances);
|
||||
if (exportsInfo.otherExportsInfo.used !== UsageState.Unused) {
|
||||
runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
|
||||
|
@ -178,7 +181,7 @@ class WebAssemblyJavascriptGenerator extends Generator {
|
|||
[
|
||||
'"use strict";',
|
||||
"// Instantiate WebAssembly module",
|
||||
`var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.i];`,
|
||||
`var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.id];`,
|
||||
|
||||
exportsInfo.otherExportsInfo.used !== UsageState.Unused
|
||||
? `${RuntimeGlobals.makeNamespaceObject}(${module.exportsArgument});`
|
||||
|
|
|
@ -202,10 +202,10 @@ describe("Stats", () => {
|
|||
"comparedForEmit": false,
|
||||
"emitted": true,
|
||||
"info": Object {
|
||||
"size": 198,
|
||||
"size": 182,
|
||||
},
|
||||
"name": "entryA.js",
|
||||
"size": 198,
|
||||
"size": 182,
|
||||
},
|
||||
Object {
|
||||
"auxiliaryChunkIdHints": Array [],
|
||||
|
@ -217,10 +217,10 @@ describe("Stats", () => {
|
|||
"comparedForEmit": false,
|
||||
"emitted": true,
|
||||
"info": Object {
|
||||
"size": 1881,
|
||||
"size": 1865,
|
||||
},
|
||||
"name": "entryB.js",
|
||||
"size": 1881,
|
||||
"size": 1865,
|
||||
},
|
||||
],
|
||||
"assetsByChunkName": Object {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,8 @@ it("should bailout when reading whole exports object from module.exports", () =>
|
|||
});
|
||||
|
||||
it("should reassigning exports (assign values)", () => {
|
||||
expect(require("./assign-exports-assign").abc).toBe("abc");
|
||||
expect(require("./assign-exports-assign").def).toBe(undefined);
|
||||
expect(require("./assign-exports-assign?1").abc).toBe("abc");
|
||||
expect(require("./assign-exports-assign?2").def).toBe(undefined);
|
||||
});
|
||||
|
||||
it("should reassigning exports (define values)", () => {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
module.exports = [
|
||||
[
|
||||
/Can't import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available soon\)/
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
module.exports = [
|
||||
[
|
||||
/Can't import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export '2' \(imported as 'c'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'aa' \(imported as 'aa'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'bb' \(imported as 'bb'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'named' \(imported as 'named'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'named' \(imported as 'gnamed'\) from default-exporting module \(only default export is available soon\)/
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module.exports = [
|
||||
[
|
||||
/Can't import the named export 'named' \(reexported as 'fNamed'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'named' \(reexported as 'fNamed'\) from default-exporting module \(only default export is available soon\)/
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
module.exports = [
|
||||
[
|
||||
/Can't import the named export 'data' \(imported as 'data'\) from non EcmaScript module \(only default export is available\)/
|
||||
/Can't import the named export 'data' \(imported as 'data'\) from default-exporting module \(only default export is available\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'data' \(imported as 'data'\) from non EcmaScript module \(only default export is available\)/
|
||||
/Can't import the named export 'data' \(imported as 'data'\) from default-exporting module \(only default export is available\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'data' \(reexported as 'data'\) from non EcmaScript module \(only default export is available\)/
|
||||
/Can't import the named export 'data' \(reexported as 'data'\) from default-exporting module \(only default export is available\)/
|
||||
]
|
||||
];
|
||||
|
|
|
@ -53,8 +53,7 @@ function contextMixed(name) {
|
|||
|
||||
function promiseTest(promise, equalsTo) {
|
||||
return promise.then(function(results) {
|
||||
for(const result of results)
|
||||
expect(result).toEqual(equalsTo);
|
||||
expect(results).toEqual(results.map(() => equalsTo));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ it("should not overwrite when using star export (known exports)", function() {
|
|||
expect(x4).toBe("b");
|
||||
expect(x5).toBe("c");
|
||||
expect(x6).toBe("a");
|
||||
expect(x7).toBe("b"); // Looks wrong, but is irrelevant as this should be an error anyway
|
||||
expect(x7).toBe("d"); // Looks wrong, but is irrelevant as this should be an error anyway
|
||||
});
|
||||
|
||||
it("should not overwrite when using star export (unknown exports)", function() {
|
||||
|
@ -31,5 +31,5 @@ it("should not overwrite when using star export (unknown exports)", function() {
|
|||
expect(y4).toBe("b");
|
||||
expect(y5).toBe("c");
|
||||
expect(y6).toBe("a");
|
||||
expect(y7).toBe("b"); // Looks wrong, but is irrelevant as this should be an error anyway
|
||||
expect(y7).toBe("d"); // Looks wrong, but is irrelevant as this should be an error anyway
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
module.exports = [
|
||||
[
|
||||
/Can't import the named export 'a' \(reexported as 'a'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'a' \(reexported as 'a'\) from default-exporting module \(only default export is available soon\)/
|
||||
],
|
||||
[
|
||||
/Can't import the named export 'b' \(reexported as 'b'\) from default-exporting module \(only default export is available\)/
|
||||
/Should not import the named export 'b' \(reexported as 'b'\) from default-exporting module \(only default export is available soon\)/
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1 +1 @@
|
|||
module.exports = [[/Can't import the named export/]];
|
||||
module.exports = [[/Should not import the named export/]];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.export = function someUsedFunction() {};
|
||||
module.exports = function someUsedFunction() {};
|
||||
|
||||
function someRemoteUnUsedFunction1() {}
|
||||
function someRemoteUnUsedFunction2() {}
|
||||
|
|
Loading…
Reference in New Issue