Skip to content

Commit

Permalink
Merge pull request #12076 from webpack/feature/side-effects-analysis
Browse files Browse the repository at this point in the history
improve side effects analysis to report imported and reexported symbols as side-effect-free
  • Loading branch information
sokra committed Nov 28, 2020
2 parents fb7d09b + cf97d04 commit 81b3b7e
Show file tree
Hide file tree
Showing 25 changed files with 352 additions and 262 deletions.
24 changes: 12 additions & 12 deletions examples/reexport-components/README.md
Expand Up @@ -26,15 +26,15 @@ export default Dashboard;
```javascript
import { Button, Dialog } from "../components";

const Dashboard = () => {
const Login = () => {
return (
<>
<Button />
<Dialog />
</>
);
};
export default Dashboard;
export default Login;
```

# components/index.js
Expand Down Expand Up @@ -193,11 +193,11 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components */ "./components/Dialog.js");


const Dashboard = () => {
const Login = () => {
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_0__.default, null), /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_1__.default, null));
};

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Dashboard);
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Login);

/***/ })

Expand All @@ -213,8 +213,8 @@ const Dashboard = () => {
## Unoptimized

```
asset output.js 10.7 KiB [emitted] (name: main)
asset pages_Login_js.output.js 2.85 KiB [emitted]
asset output.js 10.8 KiB [emitted] (name: main)
asset pages_Login_js.output.js 2.84 KiB [emitted]
asset pages_Dashboard_js.output.js 2.8 KiB [emitted]
chunk (runtime: main) output.js (main) 208 bytes (javascript) 5.42 KiB (runtime) [entry] [rendered]
> ./example.js main
Expand All @@ -231,15 +231,15 @@ chunk (runtime: main) pages_Dashboard_js.output.js 513 bytes [rendered]
[exports: default]
context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
chunk (runtime: main) pages_Login_js.output.js 512 bytes [rendered]
chunk (runtime: main) pages_Login_js.output.js 504 bytes [rendered]
> ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
> ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
dependent modules 247 bytes [dependent] 2 modules
./pages/Login.js 265 bytes [optional] [built] [code generated]
./pages/Login.js 257 bytes [optional] [built] [code generated]
[exports: default]
context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
webpack 5.7.0 compiled successfully
webpack 5.8.0 compiled successfully
```

## Production mode
Expand All @@ -263,13 +263,13 @@ chunk (runtime: main) pages_Dashboard_js.output.js 513 bytes [rendered]
[exports: default]
context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
chunk (runtime: main) pages_Login_js.output.js 512 bytes [rendered]
chunk (runtime: main) pages_Login_js.output.js 504 bytes [rendered]
> ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
> ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
dependent modules 115 bytes [dependent] 1 module
./pages/Login.js + 1 modules 397 bytes [optional] [built] [code generated]
./pages/Login.js + 1 modules 389 bytes [optional] [built] [code generated]
[exports: default]
context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
webpack 5.7.0 compiled successfully
webpack 5.8.0 compiled successfully
```
3 changes: 0 additions & 3 deletions examples/reexport-components/components/package.json

This file was deleted.

4 changes: 2 additions & 2 deletions examples/reexport-components/pages/Login.js
@@ -1,11 +1,11 @@
import { Button, Dialog } from "../components";

const Dashboard = () => {
const Login = () => {
return (
<>
<Button />
<Dialog />
</>
);
};
export default Dashboard;
export default Login;
13 changes: 13 additions & 0 deletions lib/NormalModule.js
Expand Up @@ -26,6 +26,7 @@ const ModuleWarning = require("./ModuleWarning");
const RuntimeGlobals = require("./RuntimeGlobals");
const UnhandledSchemeError = require("./UnhandledSchemeError");
const WebpackError = require("./WebpackError");
const formatLocation = require("./formatLocation");
const LazySet = require("./util/LazySet");
const { getScheme } = require("./util/URLAbsoluteSpecifier");
const {
Expand Down Expand Up @@ -248,6 +249,7 @@ class NormalModule extends Module {
this._lastSuccessfulBuildMeta = {};
this._forceBuild = true;
this._isEvaluatingSideEffects = false;
this._addedSideEffectsBailout = new WeakSet();
}

/**
Expand Down Expand Up @@ -877,6 +879,17 @@ class NormalModule extends Module {
for (const dep of this.dependencies) {
const state = dep.getModuleEvaluationSideEffectsState(moduleGraph);
if (state === true) {
if (!this._addedSideEffectsBailout.has(moduleGraph)) {
this._addedSideEffectsBailout.add(moduleGraph);
moduleGraph
.getOptimizationBailout(this)
.push(
() =>
`Dependency (${
dep.type
}) with side effects at ${formatLocation(dep.loc)}`
);
}
this._isEvaluatingSideEffects = false;
return true;
} else if (state !== ModuleGraphConnection.CIRCULAR_CONNECTION) {
Expand Down
8 changes: 8 additions & 0 deletions lib/dependencies/HarmonyExportImportedSpecifierDependency.js
Expand Up @@ -370,6 +370,14 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
};
}

/**
* @param {ModuleGraph} moduleGraph the module graph
* @returns {ConnectionState} how this dependency connects the module to referencing modules
*/
getModuleEvaluationSideEffectsState(moduleGraph) {
return false;
}

/**
* Returns list of exports referenced by this dependency
* @param {ModuleGraph} moduleGraph module graph
Expand Down
8 changes: 8 additions & 0 deletions lib/dependencies/HarmonyImportSpecifierDependency.js
Expand Up @@ -88,6 +88,14 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
this.checkUsedByExports(moduleGraph, runtime);
}

/**
* @param {ModuleGraph} moduleGraph the module graph
* @returns {ConnectionState} how this dependency connects the module to referencing modules
*/
getModuleEvaluationSideEffectsState(moduleGraph) {
return false;
}

checkUsedByExports(moduleGraph, runtime) {
if (this.usedByExports === false) return false;
if (this.usedByExports !== true && this.usedByExports !== undefined) {
Expand Down

0 comments on commit 81b3b7e

Please sign in to comment.