Merge pull request #11267 from webpack/experiments/import-async
enable experiments.importAsync by default
This commit is contained in:
commit
1273b9eb96
|
@ -882,14 +882,6 @@ export interface Experiments {
|
|||
* Support WebAssembly as asynchronous EcmaScript Module.
|
||||
*/
|
||||
asyncWebAssembly?: boolean;
|
||||
/**
|
||||
* Allow 'import/export' syntax to import async modules.
|
||||
*/
|
||||
importAsync?: boolean;
|
||||
/**
|
||||
* Allow 'import/export await' syntax to import async modules.
|
||||
*/
|
||||
importAwait?: boolean;
|
||||
/**
|
||||
* Support .mjs files as way to define strict ESM file (node.js).
|
||||
*/
|
||||
|
|
|
@ -25,30 +25,26 @@ export const close = () => {
|
|||
But `db-connection.js` is no longer a normal module now.
|
||||
It's an **async module** now.
|
||||
Async modules have a different evaluation semantics.
|
||||
While normal modules evaluate synchronously way, async modules evaluate asynchronously.
|
||||
While normal modules evaluate synchronously, async modules evaluate asynchronously.
|
||||
|
||||
Async modules can't be imported with a normal `import`.
|
||||
They need to be imported with `import await`.
|
||||
Async modules can still be imported with a normal `import`.
|
||||
But importing an async module makes the importing module also an async module.
|
||||
|
||||
The main reason for this is to make the using module aware of the different evaluation semantics.
|
||||
The `import`s still hoist and are evaluated in parallel.
|
||||
|
||||
Using `import await` in a module also makes the module an async module.
|
||||
You can see it as a form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
All `import`s and `import await`s hoist and are evaluated in parallel.
|
||||
|
||||
`import await` doesn't affect tree shaking negatively.
|
||||
Tree shaking still works as usual.
|
||||
Here the `close` function is never used and will be removed from the output bundle in production mode.
|
||||
|
||||
# UserApi.js
|
||||
|
||||
```javascript
|
||||
import await { dbCall } from "./db-connection.js";
|
||||
import { dbCall } from "./db-connection.js";
|
||||
|
||||
export const createUser = async name => {
|
||||
command = `CREATE USER ${name}`;
|
||||
// This is a normal await, because it's in an async function
|
||||
await dbCall({ command });
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Now it looks like that this pattern will continue and will infect all using modules as async modules.
|
||||
|
@ -60,7 +56,7 @@ But you as a developer don't want this.
|
|||
You want to break the chain at a point in your module graph where it makes sense.
|
||||
Luckily there is a nice way to break the chain.
|
||||
|
||||
You can use `import("./UserApi.js")` to import the module instead of `import await`.
|
||||
You can use `import("./UserApi.js")` to import the module instead of `import`.
|
||||
As this returns a Promise it can be awaited to wait for module evaluation (including top-level-awaits) and handle failures.
|
||||
|
||||
Handling failures is an important point here.
|
||||
|
@ -99,8 +95,7 @@ export const AlternativeCreateUserAction = async name => {
|
|||
// except in rare cases. It will import modules sequentially.
|
||||
```
|
||||
|
||||
As `Actions.js` doesn't use any top-level-await nor `import await` it's not an async module.
|
||||
It's a normal module and can be used via `import`.
|
||||
As `Actions.js` doesn't use any top-level-await nor `import`s an async module directly so it's not an async module.
|
||||
|
||||
# example.js
|
||||
|
||||
|
@ -112,10 +107,6 @@ import { CreateUserAction } from "./Actions.js";
|
|||
})();
|
||||
```
|
||||
|
||||
Note that you may `import await` from a normal module too.
|
||||
This is legal, but mostly not required.
|
||||
`import await` may also be seen by developers as a hint that this dependency does some async actions and may delay evaluation.
|
||||
|
||||
As a guideline, you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
Doing async actions at application bootstrap will delay your application startup and may be negative for UX.
|
||||
Use `import()` to do async action on-demand or in the background and use spinners or other indicators to inform the user about background actions.
|
||||
|
@ -128,22 +119,41 @@ When compiling for other targets like node.js, electron or WebWorkers, it may be
|
|||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ([
|
||||
/* 0 */,
|
||||
/* 0 */
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _Actions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Actions.js */ 1);
|
||||
|
||||
|
||||
(async ()=> {
|
||||
await (0,_Actions_js__WEBPACK_IMPORTED_MODULE_0__.CreateUserAction)("John");
|
||||
})();
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/*!********************!*\
|
||||
!*** ./Actions.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! export AlternativeCreateUserAction [provided] [unused] [could be renamed] */
|
||||
/*! export CreateUserAction [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__.e, __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
|
||||
/*! export AlternativeCreateUserAction [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export CreateUserAction [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__, __webpack_require__.d, __webpack_require__.* */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "CreateUserAction": () => /* binding */ CreateUserAction
|
||||
/* harmony export */ "CreateUserAction": () => /* binding */ CreateUserAction,
|
||||
/* harmony export */ "AlternativeCreateUserAction": () => /* binding */ AlternativeCreateUserAction
|
||||
/* harmony export */ });
|
||||
/* unused harmony export AlternativeCreateUserAction */
|
||||
// import() doesn't care about whether a module is an async module or not
|
||||
const UserApi = __webpack_require__.e(/*! import() */ 497).then(__webpack_require__.bind(__webpack_require__, /*! ./UserApi.js */ 2));
|
||||
|
||||
|
@ -247,6 +257,52 @@ const AlternativeCreateUserAction = async name => {
|
|||
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/load script */
|
||||
/******/ (() => {
|
||||
/******/ var inProgress = {};
|
||||
/******/ // data-webpack is not used as build has no uniqueName
|
||||
/******/ // loadScript function to load a script via script tag
|
||||
/******/ __webpack_require__.l = (url, done, key) => {
|
||||
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
|
||||
/******/ var script, needAttach;
|
||||
/******/ if(key !== undefined) {
|
||||
/******/ var scripts = document.getElementsByTagName("script");
|
||||
/******/ for(var i = 0; i < scripts.length; i++) {
|
||||
/******/ var s = scripts[i];
|
||||
/******/ if(s.getAttribute("src") == url) { script = s; break; }
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(!script) {
|
||||
/******/ needAttach = true;
|
||||
/******/ script = document.createElement('script');
|
||||
/******/
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.timeout = 120;
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ script.src = url;
|
||||
/******/ }
|
||||
/******/ inProgress[url] = [done];
|
||||
/******/ var onScriptComplete = (prev, event) => {
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var doneFns = inProgress[url];
|
||||
/******/ delete inProgress[url];
|
||||
/******/ script.parentNode && script.parentNode.removeChild(script);
|
||||
/******/ doneFns && doneFns.forEach((fn) => fn(event));
|
||||
/******/ if(prev) return prev(event);
|
||||
/******/ }
|
||||
/******/ ;
|
||||
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
|
||||
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
|
||||
/******/ script.onload = onScriptComplete.bind(null, script.onload);
|
||||
/******/ needAttach && document.head.appendChild(script);
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
|
@ -291,49 +347,24 @@ const AlternativeCreateUserAction = async name => {
|
|||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
|
||||
/******/ var loadingEnded = () => {
|
||||
/******/ // create error before stack unwound to get useful stacktrace later
|
||||
/******/ var error = new Error();
|
||||
/******/ var loadingEnded = (event) => {
|
||||
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
|
||||
/******/ installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
|
||||
/******/ if(installedChunkData) return installedChunkData[1];
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
||||
/******/ var realSrc = event && event.target && event.target.src;
|
||||
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
||||
/******/ error.name = 'ChunkLoadError';
|
||||
/******/ error.type = errorType;
|
||||
/******/ error.request = realSrc;
|
||||
/******/ installedChunkData[1](error);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ var script = document.createElement('script');
|
||||
/******/ var onScriptComplete;
|
||||
/******/
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.timeout = 120;
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/ script.src = url;
|
||||
/******/
|
||||
/******/ // create error before stack unwound to get useful stacktrace later
|
||||
/******/ var error = new Error();
|
||||
/******/ onScriptComplete = (event) => {
|
||||
/******/ onScriptComplete = () => {
|
||||
/******/
|
||||
/******/ }
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var reportError = loadingEnded();
|
||||
/******/ if(reportError) {
|
||||
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
||||
/******/ var realSrc = event && event.target && event.target.src;
|
||||
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
||||
/******/ error.name = 'ChunkLoadError';
|
||||
/******/ error.type = errorType;
|
||||
/******/ error.request = realSrc;
|
||||
/******/ reportError(error);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ ;
|
||||
/******/ var timeout = setTimeout(() => {
|
||||
/******/ onScriptComplete({ type: 'timeout', target: script })
|
||||
/******/ }, 120000);
|
||||
/******/ script.onerror = script.onload = onScriptComplete;
|
||||
/******/ document.head.appendChild(script);
|
||||
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
|
||||
/******/ } else installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ }
|
||||
|
@ -390,22 +421,10 @@ const AlternativeCreateUserAction = async name => {
|
|||
</details>
|
||||
|
||||
``` js
|
||||
(() => {
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__ */
|
||||
/* harmony import */ var _Actions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Actions.js */ 1);
|
||||
|
||||
|
||||
(async ()=> {
|
||||
await (0,_Actions_js__WEBPACK_IMPORTED_MODULE_0__.CreateUserAction)("John");
|
||||
})();
|
||||
|
||||
})();
|
||||
|
||||
/******/ // startup
|
||||
/******/ // Load entry module
|
||||
/******/ __webpack_require__(0);
|
||||
/******/ // This entry module used 'exports' so it can't be inlined
|
||||
/******/ })()
|
||||
;
|
||||
```
|
||||
|
@ -421,8 +440,8 @@ const AlternativeCreateUserAction = async name => {
|
|||
!*** ./UserApi.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! export createUser [provided] [maybe used (runtime-defined)] [usage prevents renaming] */
|
||||
/*! other exports [not provided] [maybe used (runtime-defined)] */
|
||||
/*! export createUser [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
|
@ -440,7 +459,7 @@ const createUser = async name => {
|
|||
command = `CREATE USER ${name}`;
|
||||
// This is a normal await, because it's in an async function
|
||||
await (0,_db_connection_js__WEBPACK_IMPORTED_MODULE_0__.dbCall)({ command });
|
||||
}
|
||||
};
|
||||
|
||||
return __webpack_exports__;
|
||||
})();
|
||||
|
@ -451,18 +470,19 @@ return __webpack_exports__;
|
|||
!*** ./db-connection.js ***!
|
||||
\**************************/
|
||||
/*! namespace exports */
|
||||
/*! export close [provided] [unused] [could be renamed] */
|
||||
/*! export dbCall [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: module, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
|
||||
/*! export close [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export dbCall [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "dbCall": () => /* binding */ dbCall
|
||||
/* harmony export */ "dbCall": () => /* binding */ dbCall,
|
||||
/* harmony export */ "close": () => /* binding */ close
|
||||
/* harmony export */ });
|
||||
/* unused harmony export close */
|
||||
const connectToDB = async url => {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
};
|
||||
|
@ -499,34 +519,34 @@ return __webpack_exports__;
|
|||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
497.output.js 2.39 KiB [emitted]
|
||||
output.js 10.7 KiB [emitted] [name: main]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset 497.output.js 2.53 KiB [emitted]
|
||||
asset output.js 12.2 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js
|
||||
chunk output.js (main) 1.19 KiB (javascript) 4.76 KiB (runtime) [entry] [rendered]
|
||||
chunk output.js (main) 1.19 KiB (javascript) 5.46 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./Actions.js 1.09 KiB [built]
|
||||
[exports: AlternativeCreateUserAction, CreateUserAction]
|
||||
[only some exports used: CreateUserAction]
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./Actions.js ./example.js 1:0-48
|
||||
harmony import specifier ./Actions.js ./example.js 4:7-23
|
||||
./example.js 103 bytes [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
+ 7 hidden chunk modules
|
||||
chunk 497.output.js 622 bytes [rendered]
|
||||
+ 8 hidden chunk modules
|
||||
chunk 497.output.js 617 bytes [rendered]
|
||||
> ./UserApi.js ./Actions.js 22:30-52
|
||||
> ./UserApi.js ./Actions.js 2:16-38
|
||||
./UserApi.js 220 bytes [built]
|
||||
./UserApi.js 215 bytes [built]
|
||||
[exports: createUser]
|
||||
[used exports unknown]
|
||||
import() ./UserApi.js ./Actions.js 2:16-38
|
||||
import() ./UserApi.js ./Actions.js 22:30-52
|
||||
./db-connection.js 402 bytes [built]
|
||||
[exports: close, dbCall]
|
||||
[only some exports used: dbCall]
|
||||
harmony side effect evaluation ./db-connection.js ./UserApi.js 1:0-50
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./db-connection.js ./UserApi.js 1:0-44
|
||||
harmony import specifier ./db-connection.js ./UserApi.js 6:7-13
|
||||
```
|
||||
|
||||
|
@ -534,28 +554,27 @@ chunk 497.output.js 622 bytes [rendered]
|
|||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
497.output.js 475 bytes [emitted]
|
||||
output.js 1.65 KiB [emitted] [name: main]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset 497.output.js 475 bytes [emitted]
|
||||
asset output.js 2 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js
|
||||
chunk output.js (main) 1.19 KiB (javascript) 4.76 KiB (runtime) [entry] [rendered]
|
||||
chunk (runtime: main) output.js (main) 1.19 KiB (javascript) 5.46 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js + 1 modules 1.19 KiB [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
+ 7 hidden chunk modules
|
||||
chunk 497.output.js 622 bytes [rendered]
|
||||
+ 8 hidden chunk modules
|
||||
chunk (runtime: main) 497.output.js 617 bytes [rendered]
|
||||
> ./UserApi.js ./Actions.js 22:30-52
|
||||
> ./UserApi.js ./Actions.js 2:16-38
|
||||
./UserApi.js 220 bytes [built]
|
||||
./UserApi.js 215 bytes [built]
|
||||
[exports: createUser]
|
||||
import() ./UserApi.js ./example.js + 1 modules ./Actions.js 2:16-38
|
||||
import() ./UserApi.js ./example.js + 1 modules ./Actions.js 22:30-52
|
||||
./db-connection.js 402 bytes [built]
|
||||
[exports: close, dbCall]
|
||||
[only some exports used: dbCall]
|
||||
harmony side effect evaluation ./db-connection.js ./UserApi.js 1:0-50
|
||||
harmony side effect evaluation ./db-connection.js ./UserApi.js 1:0-44
|
||||
harmony import specifier ./db-connection.js ./UserApi.js 6:7-13
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import await { dbCall } from "./db-connection.js";
|
||||
import { dbCall } from "./db-connection.js";
|
||||
|
||||
export const createUser = async name => {
|
||||
command = `CREATE USER ${name}`;
|
||||
// This is a normal await, because it's in an async function
|
||||
await dbCall({ command });
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,16 +12,12 @@ It's an **async module** now.
|
|||
Async modules have a different evaluation semantics.
|
||||
While normal modules evaluate synchronously, async modules evaluate asynchronously.
|
||||
|
||||
Async modules can't be imported with a normal `import`.
|
||||
They need to be imported with `import await`.
|
||||
Async modules can still be imported with a normal `import`.
|
||||
But importing an async module makes the importing module also an async module.
|
||||
|
||||
The main reason for this is to make the using module aware of the different evaluation semantics.
|
||||
The `import`s still hoist and are evaluated in parallel.
|
||||
|
||||
Using `import await` in a module also makes the module an async module.
|
||||
You can see it as a form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
All `import`s and `import await`s hoist and are evaluated in parallel.
|
||||
|
||||
`import await` doesn't affect tree shaking negatively.
|
||||
Tree shaking still works as usual.
|
||||
Here the `close` function is never used and will be removed from the output bundle in production mode.
|
||||
|
||||
# UserApi.js
|
||||
|
@ -39,7 +35,7 @@ But you as a developer don't want this.
|
|||
You want to break the chain at a point in your module graph where it makes sense.
|
||||
Luckily there is a nice way to break the chain.
|
||||
|
||||
You can use `import("./UserApi.js")` to import the module instead of `import await`.
|
||||
You can use `import("./UserApi.js")` to import the module instead of `import`.
|
||||
As this returns a Promise it can be awaited to wait for module evaluation (including top-level-awaits) and handle failures.
|
||||
|
||||
Handling failures is an important point here.
|
||||
|
@ -52,8 +48,7 @@ In this example connecting to the DB may fail.
|
|||
_{{Actions.js}}_
|
||||
```
|
||||
|
||||
As `Actions.js` doesn't use any top-level-await nor `import await` it's not an async module.
|
||||
It's a normal module and can be used via `import`.
|
||||
As `Actions.js` doesn't use any top-level-await nor `import`s an async module directly so it's not an async module.
|
||||
|
||||
# example.js
|
||||
|
||||
|
@ -61,10 +56,6 @@ It's a normal module and can be used via `import`.
|
|||
_{{example.js}}_
|
||||
```
|
||||
|
||||
Note that you may `import await` from a normal module too.
|
||||
This is legal, but mostly not required.
|
||||
`import await` may also be seen by developers as a hint that this dependency does some async actions and may delay evaluation.
|
||||
|
||||
As a guideline, you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
Doing async actions at application bootstrap will delay your application startup and may be negative for UX.
|
||||
Use `import()` to do async action on-demand or in the background and use spinners or other indicators to inform the user about background actions.
|
||||
|
|
|
@ -3,7 +3,6 @@ module.exports = {
|
|||
chunkIds: "deterministic" // To keep filename consistent between different modes (for example building only)
|
||||
},
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
importAwait: true
|
||||
topLevelAwait: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# example.js
|
||||
|
||||
```javascript
|
||||
import await { get, set, getNumber } from "./magic.js";
|
||||
import { get, set, getNumber } from "./magic.js";
|
||||
|
||||
// accessing memory
|
||||
console.log(get());
|
||||
|
@ -20,7 +20,7 @@ console.log(getNumber());
|
|||
|
||||
```javascript
|
||||
// reexporting
|
||||
export await * from "./magic.wat";
|
||||
export * from "./magic.wat";
|
||||
```
|
||||
|
||||
# magic.wat
|
||||
|
@ -78,11 +78,12 @@ export const memory = await getMemoryFromParentInWorker();
|
|||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__, module, __webpack_exports__ */
|
||||
/*! exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _magic_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./magic.js */ 1);
|
||||
_magic_js__WEBPACK_IMPORTED_MODULE_0__ = await Promise.resolve(_magic_js__WEBPACK_IMPORTED_MODULE_0__);
|
||||
|
||||
|
@ -108,14 +109,15 @@ return __webpack_exports__;
|
|||
!*** ./magic.js ***!
|
||||
\******************/
|
||||
/*! namespace exports */
|
||||
/*! export get [provided] [used] [could be renamed] */
|
||||
/*! export getNumber [provided] [used] [could be renamed] */
|
||||
/*! export set [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, module, __webpack_require__.* */
|
||||
/*! export get [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export getNumber [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export set [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "get": () => /* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.get,
|
||||
/* harmony export */ "getNumber": () => /* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.getNumber,
|
||||
|
@ -135,17 +137,17 @@ return __webpack_exports__;
|
|||
!*** ./magic.wat ***!
|
||||
\*******************/
|
||||
/*! namespace exports */
|
||||
/*! export get [provided] [used] [provision prevents renaming] */
|
||||
/*! export getNumber [provided] [used] [provision prevents renaming] */
|
||||
/*! export set [provided] [used] [provision prevents renaming] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export get [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! export getNumber [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! export set [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__, __webpack_require__.* */
|
||||
/***/ ((module, exports, __webpack_require__) => {
|
||||
|
||||
/* harmony import */ var WEBPACK_IMPORTED_MODULE_0 = __webpack_require__(/*! ./memory.js */ 3);
|
||||
/* harmony import */ var WEBPACK_IMPORTED_MODULE_1 = __webpack_require__(/*! ./magic-number.js */ 4);
|
||||
module.exports = Promise.resolve(WEBPACK_IMPORTED_MODULE_0).then((WEBPACK_IMPORTED_MODULE_0) => {
|
||||
return __webpack_require__.v(exports, module.id, {
|
||||
return __webpack_require__.v(exports, module.id, "493198b38242c233ec44", {
|
||||
"./memory.js": {
|
||||
"memory": WEBPACK_IMPORTED_MODULE_0.memory
|
||||
},
|
||||
|
@ -161,12 +163,13 @@ module.exports = Promise.resolve(WEBPACK_IMPORTED_MODULE_0).then((WEBPACK_IMPORT
|
|||
!*** ./memory.js ***!
|
||||
\*******************/
|
||||
/*! namespace exports */
|
||||
/*! export memory [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: module, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
|
||||
/*! export memory [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "memory": () => /* binding */ memory
|
||||
/* harmony export */ });
|
||||
|
@ -187,16 +190,17 @@ return __webpack_exports__;
|
|||
!*** ./magic-number.js ***!
|
||||
\*************************/
|
||||
/*! namespace exports */
|
||||
/*! export getNumber [provided] [unused] [could be renamed] */
|
||||
/*! export getRandomNumber [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
|
||||
/*! export getNumber [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export getRandomNumber [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "getNumber": () => /* binding */ getNumber,
|
||||
/* harmony export */ "getRandomNumber": () => /* binding */ getRandomNumber
|
||||
/* harmony export */ });
|
||||
/* unused harmony export getNumber */
|
||||
function getNumber() {
|
||||
return 42;
|
||||
}
|
||||
|
@ -255,6 +259,17 @@ function getRandomNumber() {
|
|||
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/publicPath */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.p = "dist/";
|
||||
|
@ -262,16 +277,16 @@ function getRandomNumber() {
|
|||
/******/
|
||||
/******/ /* webpack/runtime/wasm chunk loading */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.v = function(exports, wasmModuleId, importsObj) {
|
||||
/******/ var req = fetch(__webpack_require__.p + "" + {"2":"4961ae1f00405983e33f"}[wasmModuleId] + ".module.wasm");
|
||||
/******/ if(typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/******/ __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => {
|
||||
/******/ var req = fetch(__webpack_require__.p + "" + wasmModuleHash + ".module.wasm");
|
||||
/******/ if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/******/ return WebAssembly.instantiateStreaming(req, importsObj)
|
||||
/******/ .then(function(res) { return Object.assign(exports, res.instance.exports); });
|
||||
/******/ .then((res) => Object.assign(exports, res.instance.exports));
|
||||
/******/ }
|
||||
/******/ return req
|
||||
/******/ .then(function(x) { return x.arrayBuffer(); })
|
||||
/******/ .then(function(bytes) { return WebAssembly.instantiate(bytes, importsObj); })
|
||||
/******/ .then(function(res) { return Object.assign(exports, res.instance.exports); });
|
||||
/******/ .then((x) => x.arrayBuffer())
|
||||
/******/ .then((bytes) => WebAssembly.instantiate(bytes, importsObj))
|
||||
/******/ .then((res) => Object.assign(exports, res.instance.exports));
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
|
@ -295,25 +310,24 @@ function getRandomNumber() {
|
|||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
4961ae1f00405983e33f.module.wasm 139 bytes [emitted] [immutable] [name: (main)]
|
||||
output.js 7.84 KiB [emitted] [name: main]
|
||||
Entrypoint main = output.js (4961ae1f00405983e33f.module.wasm)
|
||||
chunk output.js (main) 708 bytes (javascript) 139 bytes (webassembly) 1.01 KiB (runtime) [entry] [rendered]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset 493198b38242c233ec44.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset output.js 8.8 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js (493198b38242c233ec44.module.wasm)
|
||||
chunk output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 1.2 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 253 bytes [built]
|
||||
./example.js 247 bytes [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
./magic-number.js 124 bytes [built]
|
||||
[exports: getNumber, getRandomNumber]
|
||||
[only some exports used: getRandomNumber]
|
||||
[used exports unknown]
|
||||
wasm import ./magic-number.js ./magic.wat
|
||||
./magic.js 50 bytes [built]
|
||||
./magic.js 44 bytes [built]
|
||||
[exports: get, getNumber, set]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./magic.js ./example.js 1:0-55
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./magic.js ./example.js 1:0-49
|
||||
harmony import specifier ./magic.js ./example.js 4:12-15
|
||||
harmony import specifier ./magic.js ./example.js 5:0-3
|
||||
harmony import specifier ./magic.js ./example.js 6:12-15
|
||||
|
@ -324,28 +338,27 @@ chunk output.js (main) 708 bytes (javascript) 139 bytes (webassembly) 1.01 KiB (
|
|||
harmony import specifier ./magic.js ./example.js 13:12-21
|
||||
./magic.wat 70 bytes (javascript) 139 bytes (webassembly) [built]
|
||||
[exports: get, getNumber, set]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./magic.wat ./magic.js 2:0-34
|
||||
harmony export imported specifier ./magic.wat ./magic.js 2:0-34
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./magic.wat ./magic.js 2:0-28
|
||||
harmony export imported specifier ./magic.wat ./magic.js 2:0-28
|
||||
./memory.js 211 bytes [built]
|
||||
[exports: memory]
|
||||
[all exports used]
|
||||
[used exports unknown]
|
||||
wasm import ./memory.js ./magic.wat
|
||||
+ 4 hidden chunk modules
|
||||
+ 5 hidden chunk modules
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
4636ea8e62e0734a195f.module.wasm 139 bytes [emitted] [immutable] [name: (main)]
|
||||
output.js 1.52 KiB [emitted] [name: main]
|
||||
Entrypoint main = output.js (4636ea8e62e0734a195f.module.wasm)
|
||||
chunk output.js (main) 708 bytes (javascript) 139 bytes (webassembly) 1.01 KiB (runtime) [entry] [rendered]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset b873a21e71d2d93bad48.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset output.js 1.43 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js (b873a21e71d2d93bad48.module.wasm)
|
||||
chunk (runtime: main) output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 950 bytes (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./example.js 253 bytes [built]
|
||||
./example.js 247 bytes [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
|
@ -353,10 +366,10 @@ chunk output.js (main) 708 bytes (javascript) 139 bytes (webassembly) 1.01 KiB (
|
|||
[exports: getNumber, getRandomNumber]
|
||||
[only some exports used: getRandomNumber]
|
||||
wasm import ./magic-number.js ./magic.wat
|
||||
./magic.js 50 bytes [built]
|
||||
./magic.js 44 bytes [built]
|
||||
[exports: get, getNumber, set]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./magic.js ./example.js 1:0-55
|
||||
harmony side effect evaluation ./magic.js ./example.js 1:0-49
|
||||
harmony import specifier ./magic.js ./example.js 4:12-15
|
||||
harmony import specifier ./magic.js ./example.js 5:0-3
|
||||
harmony import specifier ./magic.js ./example.js 6:12-15
|
||||
|
@ -368,8 +381,8 @@ chunk output.js (main) 708 bytes (javascript) 139 bytes (webassembly) 1.01 KiB (
|
|||
./magic.wat 70 bytes (javascript) 139 bytes (webassembly) [built]
|
||||
[exports: get, getNumber, set]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./magic.wat ./magic.js 2:0-34
|
||||
harmony export imported specifier ./magic.wat ./magic.js 2:0-34
|
||||
harmony side effect evaluation ./magic.wat ./magic.js 2:0-28
|
||||
harmony export imported specifier ./magic.wat ./magic.js 2:0-28
|
||||
./memory.js 211 bytes [built]
|
||||
[exports: memory]
|
||||
[all exports used]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { get, set, getNumber } from "./magic.js";
|
||||
import { get, set, getNumber } from "./magic.js";
|
||||
|
||||
// accessing memory
|
||||
console.log(get());
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// reexporting
|
||||
export await * from "./magic.wat";
|
||||
export * from "./magic.wat";
|
||||
|
|
|
@ -17,7 +17,6 @@ module.exports = {
|
|||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
topLevelAwait: true,
|
||||
importAwait: true
|
||||
topLevelAwait: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
This is a simple example that shows the usage of WebAssembly.
|
||||
|
||||
WebAssembly modules can be imported like other async modules with `import await` or `import()`.
|
||||
WebAssembly modules can be imported like other async modules with `import` or `import()`.
|
||||
When importing, they are downloaded and instantiated in a streaming way.
|
||||
|
||||
# example.js
|
||||
|
||||
```javascript
|
||||
import await { add } from "./add.wasm";
|
||||
import await { add as mathAdd, factorial, factorialJavascript, fibonacci, fibonacciJavascript } from "./math";
|
||||
import { add } from "./add.wasm";
|
||||
import {
|
||||
add as mathAdd,
|
||||
factorial,
|
||||
factorialJavascript,
|
||||
fibonacci,
|
||||
fibonacciJavascript
|
||||
} from "./math";
|
||||
|
||||
console.log(add(22, 2200));
|
||||
console.log(mathAdd(10, 101));
|
||||
|
@ -21,34 +27,31 @@ timed("wasm fibonacci", () => fibonacci(22));
|
|||
timed("js fibonacci", () => fibonacciJavascript(22));
|
||||
|
||||
function timed(name, fn) {
|
||||
if(!console.time || !console.timeEnd)
|
||||
return fn();
|
||||
if (!console.time || !console.timeEnd) return fn();
|
||||
// warmup
|
||||
for(var i = 0; i < 10; i++)
|
||||
fn();
|
||||
console.time(name)
|
||||
for(var i = 0; i < 5000; i++)
|
||||
fn();
|
||||
console.timeEnd(name)
|
||||
for (var i = 0; i < 10; i++) fn();
|
||||
console.time(name);
|
||||
for (var i = 0; i < 5000; i++) fn();
|
||||
console.timeEnd(name);
|
||||
}
|
||||
```
|
||||
|
||||
# math.js
|
||||
|
||||
```javascript
|
||||
import await { add } from "./add.wasm";
|
||||
import await { factorial } from "./factorial.wasm";
|
||||
import await { fibonacci } from "./fibonacci.wasm";
|
||||
import { add } from "./add.wasm";
|
||||
import { factorial } from "./factorial.wasm";
|
||||
import { fibonacci } from "./fibonacci.wasm";
|
||||
|
||||
export { add, factorial, fibonacci };
|
||||
|
||||
export function factorialJavascript(i) {
|
||||
if(i < 1) return 1;
|
||||
if (i < 1) return 1;
|
||||
return i * factorialJavascript(i - 1);
|
||||
}
|
||||
|
||||
export function fibonacciJavascript(i) {
|
||||
if(i < 2) return 1;
|
||||
if (i < 2) return 1;
|
||||
return fibonacciJavascript(i - 1) + fibonacciJavascript(i - 2);
|
||||
}
|
||||
```
|
||||
|
@ -64,11 +67,12 @@ export function fibonacciJavascript(i) {
|
|||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! namespace exports */
|
||||
/*! exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__, module, __webpack_exports__ */
|
||||
/*! exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var _add_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add.wasm */ 1);
|
||||
/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ 2);
|
||||
([_math__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__] = await Promise.all([_math__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__]));
|
||||
|
@ -87,15 +91,12 @@ timed("wasm fibonacci", () => (0,_math__WEBPACK_IMPORTED_MODULE_1__.fibonacci)(2
|
|||
timed("js fibonacci", () => (0,_math__WEBPACK_IMPORTED_MODULE_1__.fibonacciJavascript)(22));
|
||||
|
||||
function timed(name, fn) {
|
||||
if(!console.time || !console.timeEnd)
|
||||
return fn();
|
||||
if (!console.time || !console.timeEnd) return fn();
|
||||
// warmup
|
||||
for(var i = 0; i < 10; i++)
|
||||
fn();
|
||||
console.time(name)
|
||||
for(var i = 0; i < 5000; i++)
|
||||
fn();
|
||||
console.timeEnd(name)
|
||||
for (var i = 0; i < 10; i++) fn();
|
||||
console.time(name);
|
||||
for (var i = 0; i < 5000; i++) fn();
|
||||
console.timeEnd(name);
|
||||
}
|
||||
|
||||
return __webpack_exports__;
|
||||
|
@ -107,12 +108,12 @@ return __webpack_exports__;
|
|||
!*** ./add.wasm ***!
|
||||
\******************/
|
||||
/*! namespace exports */
|
||||
/*! export add [provided] [used] [provision prevents renaming] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export add [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */
|
||||
/***/ ((module, exports, __webpack_require__) => {
|
||||
|
||||
module.exports = __webpack_require__.v(exports, module.id)
|
||||
module.exports = __webpack_require__.v(exports, module.id, "937efcc237fa853c54c5")
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
|
@ -120,16 +121,17 @@ module.exports = __webpack_require__.v(exports, module.id)
|
|||
!*** ./math.js ***!
|
||||
\*****************/
|
||||
/*! namespace exports */
|
||||
/*! export add [provided] [used] [could be renamed] */
|
||||
/*! export factorial [provided] [used] [could be renamed] */
|
||||
/*! export factorialJavascript [provided] [used] [could be renamed] */
|
||||
/*! export fibonacci [provided] [used] [could be renamed] */
|
||||
/*! export fibonacciJavascript [provided] [used] [could be renamed] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, module, __webpack_require__.* */
|
||||
/*! export add [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export factorial [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export factorialJavascript [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export fibonacci [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! export fibonacciJavascript [provided] [no usage info] [missing usage info prevents renaming] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.* */
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
module.exports = (async () => {
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "add": () => /* reexport safe */ _add_wasm__WEBPACK_IMPORTED_MODULE_0__.add,
|
||||
/* harmony export */ "factorial": () => /* reexport safe */ _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__.factorial,
|
||||
|
@ -148,12 +150,12 @@ module.exports = (async () => {
|
|||
|
||||
|
||||
function factorialJavascript(i) {
|
||||
if(i < 1) return 1;
|
||||
if (i < 1) return 1;
|
||||
return i * factorialJavascript(i - 1);
|
||||
}
|
||||
|
||||
function fibonacciJavascript(i) {
|
||||
if(i < 2) return 1;
|
||||
if (i < 2) return 1;
|
||||
return fibonacciJavascript(i - 1) + fibonacciJavascript(i - 2);
|
||||
}
|
||||
|
||||
|
@ -166,12 +168,12 @@ return __webpack_exports__;
|
|||
!*** ./factorial.wasm ***!
|
||||
\************************/
|
||||
/*! namespace exports */
|
||||
/*! export factorial [provided] [used] [provision prevents renaming] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export factorial [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */
|
||||
/***/ ((module, exports, __webpack_require__) => {
|
||||
|
||||
module.exports = __webpack_require__.v(exports, module.id)
|
||||
module.exports = __webpack_require__.v(exports, module.id, "39f1d275c85dc3f2ce74")
|
||||
|
||||
/***/ }),
|
||||
/* 4 */
|
||||
|
@ -179,12 +181,12 @@ module.exports = __webpack_require__.v(exports, module.id)
|
|||
!*** ./fibonacci.wasm ***!
|
||||
\************************/
|
||||
/*! namespace exports */
|
||||
/*! export fibonacci [provided] [used] [provision prevents renaming] */
|
||||
/*! other exports [not provided] [unused] */
|
||||
/*! export fibonacci [provided] [no usage info] [provision prevents renaming (no use info)] */
|
||||
/*! other exports [not provided] [no usage info] */
|
||||
/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */
|
||||
/***/ ((module, exports, __webpack_require__) => {
|
||||
|
||||
module.exports = __webpack_require__.v(exports, module.id)
|
||||
module.exports = __webpack_require__.v(exports, module.id, "8daa7a900abbba23d2f2")
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
|
@ -235,6 +237,17 @@ module.exports = __webpack_require__.v(exports, module.id)
|
|||
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/publicPath */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.p = "dist/";
|
||||
|
@ -242,16 +255,16 @@ module.exports = __webpack_require__.v(exports, module.id)
|
|||
/******/
|
||||
/******/ /* webpack/runtime/wasm chunk loading */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.v = function(exports, wasmModuleId, importsObj) {
|
||||
/******/ var req = fetch(__webpack_require__.p + "" + {"1":"1c8378066da027821f98","3":"9989aee1a31bab8d342f","4":"aa9360d4a460c66559cc"}[wasmModuleId] + ".wasm");
|
||||
/******/ if(typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/******/ __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => {
|
||||
/******/ var req = fetch(__webpack_require__.p + "" + wasmModuleHash + ".wasm");
|
||||
/******/ if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/******/ return WebAssembly.instantiateStreaming(req, importsObj)
|
||||
/******/ .then(function(res) { return Object.assign(exports, res.instance.exports); });
|
||||
/******/ .then((res) => Object.assign(exports, res.instance.exports));
|
||||
/******/ }
|
||||
/******/ return req
|
||||
/******/ .then(function(x) { return x.arrayBuffer(); })
|
||||
/******/ .then(function(bytes) { return WebAssembly.instantiate(bytes, importsObj); })
|
||||
/******/ .then(function(res) { return Object.assign(exports, res.instance.exports); });
|
||||
/******/ .then((x) => x.arrayBuffer())
|
||||
/******/ .then((bytes) => WebAssembly.instantiate(bytes, importsObj))
|
||||
/******/ .then((res) => Object.assign(exports, res.instance.exports));
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
|
@ -275,98 +288,96 @@ module.exports = __webpack_require__.v(exports, module.id)
|
|||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
1c8378066da027821f98.wasm 41 bytes [emitted] [immutable] [name: (main)]
|
||||
9989aee1a31bab8d342f.wasm 62 bytes [emitted] [immutable] [name: (main)]
|
||||
aa9360d4a460c66559cc.wasm 67 bytes [emitted] [immutable] [name: (main)]
|
||||
output.js 8.2 KiB [emitted] [name: main]
|
||||
Entrypoint main = output.js (1c8378066da027821f98.wasm 9989aee1a31bab8d342f.wasm aa9360d4a460c66559cc.wasm)
|
||||
chunk output.js (main) 1.3 KiB (javascript) 170 bytes (webassembly) 1.06 KiB (runtime) [entry] [rendered]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset 39f1d275c85dc3f2ce74.wasm 62 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset 8daa7a900abbba23d2f2.wasm 67 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset 937efcc237fa853c54c5.wasm 41 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset output.js 8.97 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js (39f1d275c85dc3f2ce74.wasm 8daa7a900abbba23d2f2.wasm 937efcc237fa853c54c5.wasm)
|
||||
chunk output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 1.19 KiB (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./add.wasm 50 bytes (javascript) 41 bytes (webassembly) [built]
|
||||
[exports: add]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./add.wasm ./example.js 1:0-39
|
||||
harmony import specifier ./add.wasm ./example.js 4:12-15
|
||||
harmony side effect evaluation ./add.wasm ./math.js 1:0-39
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./add.wasm ./example.js 1:0-33
|
||||
harmony import specifier ./add.wasm ./example.js 10:12-15
|
||||
harmony side effect evaluation ./add.wasm ./math.js 1:0-33
|
||||
harmony export imported specifier ./add.wasm ./math.js 5:0-37
|
||||
./example.js 761 bytes [built]
|
||||
./example.js 753 bytes [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
[used exports unknown]
|
||||
entry ./example.js main
|
||||
./factorial.wasm 50 bytes (javascript) 62 bytes (webassembly) [built]
|
||||
[exports: factorial]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./factorial.wasm ./math.js 2:0-51
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./factorial.wasm ./math.js 2:0-45
|
||||
harmony export imported specifier ./factorial.wasm ./math.js 5:0-37
|
||||
./fibonacci.wasm 50 bytes (javascript) 67 bytes (webassembly) [built]
|
||||
[exports: fibonacci]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./fibonacci.wasm ./math.js 3:0-51
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./fibonacci.wasm ./math.js 3:0-45
|
||||
harmony export imported specifier ./fibonacci.wasm ./math.js 5:0-37
|
||||
./math.js 418 bytes [built]
|
||||
./math.js 402 bytes [built]
|
||||
[exports: add, factorial, factorialJavascript, fibonacci, fibonacciJavascript]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./math ./example.js 2:0-110
|
||||
harmony import specifier ./math ./example.js 5:12-19
|
||||
harmony import specifier ./math ./example.js 6:12-21
|
||||
harmony import specifier ./math ./example.js 7:12-31
|
||||
harmony import specifier ./math ./example.js 8:12-21
|
||||
harmony import specifier ./math ./example.js 9:12-31
|
||||
harmony import specifier ./math ./example.js 10:30-39
|
||||
harmony import specifier ./math ./example.js 11:28-47
|
||||
harmony import specifier ./math ./example.js 12:30-39
|
||||
harmony import specifier ./math ./example.js 13:28-47
|
||||
+ 4 hidden chunk modules
|
||||
[used exports unknown]
|
||||
harmony side effect evaluation ./math ./example.js 2:0-8:16
|
||||
harmony import specifier ./math ./example.js 11:12-19
|
||||
harmony import specifier ./math ./example.js 12:12-21
|
||||
harmony import specifier ./math ./example.js 13:12-31
|
||||
harmony import specifier ./math ./example.js 14:12-21
|
||||
harmony import specifier ./math ./example.js 15:12-31
|
||||
harmony import specifier ./math ./example.js 16:30-39
|
||||
harmony import specifier ./math ./example.js 17:28-47
|
||||
harmony import specifier ./math ./example.js 18:30-39
|
||||
harmony import specifier ./math ./example.js 19:28-47
|
||||
+ 5 hidden chunk modules
|
||||
```
|
||||
|
||||
## Production mode
|
||||
|
||||
```
|
||||
Hash: 0a1b2c3d4e5f6a7b8c9d
|
||||
Version: webpack 5.0.0-beta.16
|
||||
Asset Size
|
||||
5ba3e3921117e9d828f5.wasm 67 bytes [emitted] [immutable] [name: (main)]
|
||||
5dd947250fab86306d49.wasm 62 bytes [emitted] [immutable] [name: (main)]
|
||||
6f6c0ffc52ce3a45ff7e.wasm 41 bytes [emitted] [immutable] [name: (main)]
|
||||
output.js 1.67 KiB [emitted] [name: main]
|
||||
Entrypoint main = output.js (5ba3e3921117e9d828f5.wasm 5dd947250fab86306d49.wasm 6f6c0ffc52ce3a45ff7e.wasm)
|
||||
chunk output.js (main) 1.3 KiB (javascript) 170 bytes (webassembly) 1.06 KiB (runtime) [entry] [rendered]
|
||||
Version: webpack 5.0.0-beta.23
|
||||
asset 402d0640d802f4390f09.wasm 41 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset 79f27550455ff7b728fb.wasm 62 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset c473e4ed21f109fed4d9.wasm 67 bytes [emitted] [immutable] (auxiliary name: main)
|
||||
asset output.js 1.58 KiB [emitted] (name: main)
|
||||
Entrypoint main = output.js (402d0640d802f4390f09.wasm 79f27550455ff7b728fb.wasm c473e4ed21f109fed4d9.wasm)
|
||||
chunk (runtime: main) output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 943 bytes (runtime) [entry] [rendered]
|
||||
> ./example.js main
|
||||
./add.wasm 50 bytes (javascript) 41 bytes (webassembly) [built]
|
||||
[exports: add]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./add.wasm ./example.js 1:0-39
|
||||
harmony import specifier ./add.wasm ./example.js 4:12-15
|
||||
harmony side effect evaluation ./add.wasm ./math.js 1:0-39
|
||||
harmony side effect evaluation ./add.wasm ./example.js 1:0-33
|
||||
harmony import specifier ./add.wasm ./example.js 10:12-15
|
||||
harmony side effect evaluation ./add.wasm ./math.js 1:0-33
|
||||
harmony export imported specifier ./add.wasm ./math.js 5:0-37
|
||||
./example.js 761 bytes [built]
|
||||
./example.js 753 bytes [built]
|
||||
[no exports]
|
||||
[no exports used]
|
||||
entry ./example.js main
|
||||
./factorial.wasm 50 bytes (javascript) 62 bytes (webassembly) [built]
|
||||
[exports: factorial]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./factorial.wasm ./math.js 2:0-51
|
||||
harmony side effect evaluation ./factorial.wasm ./math.js 2:0-45
|
||||
harmony export imported specifier ./factorial.wasm ./math.js 5:0-37
|
||||
./fibonacci.wasm 50 bytes (javascript) 67 bytes (webassembly) [built]
|
||||
[exports: fibonacci]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./fibonacci.wasm ./math.js 3:0-51
|
||||
harmony side effect evaluation ./fibonacci.wasm ./math.js 3:0-45
|
||||
harmony export imported specifier ./fibonacci.wasm ./math.js 5:0-37
|
||||
./math.js 418 bytes [built]
|
||||
./math.js 402 bytes [built]
|
||||
[exports: add, factorial, factorialJavascript, fibonacci, fibonacciJavascript]
|
||||
[all exports used]
|
||||
harmony side effect evaluation ./math ./example.js 2:0-110
|
||||
harmony import specifier ./math ./example.js 5:12-19
|
||||
harmony import specifier ./math ./example.js 6:12-21
|
||||
harmony import specifier ./math ./example.js 7:12-31
|
||||
harmony import specifier ./math ./example.js 8:12-21
|
||||
harmony import specifier ./math ./example.js 9:12-31
|
||||
harmony import specifier ./math ./example.js 10:30-39
|
||||
harmony import specifier ./math ./example.js 11:28-47
|
||||
harmony import specifier ./math ./example.js 12:30-39
|
||||
harmony import specifier ./math ./example.js 13:28-47
|
||||
harmony side effect evaluation ./math ./example.js 2:0-8:16
|
||||
harmony import specifier ./math ./example.js 11:12-19
|
||||
harmony import specifier ./math ./example.js 12:12-21
|
||||
harmony import specifier ./math ./example.js 13:12-31
|
||||
harmony import specifier ./math ./example.js 14:12-21
|
||||
harmony import specifier ./math ./example.js 15:12-31
|
||||
harmony import specifier ./math ./example.js 16:30-39
|
||||
harmony import specifier ./math ./example.js 17:28-47
|
||||
harmony import specifier ./math ./example.js 18:30-39
|
||||
harmony import specifier ./math ./example.js 19:28-47
|
||||
+ 4 hidden chunk modules
|
||||
```
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import await { add } from "./add.wasm";
|
||||
import await { add as mathAdd, factorial, factorialJavascript, fibonacci, fibonacciJavascript } from "./math";
|
||||
import { add } from "./add.wasm";
|
||||
import {
|
||||
add as mathAdd,
|
||||
factorial,
|
||||
factorialJavascript,
|
||||
fibonacci,
|
||||
fibonacciJavascript
|
||||
} from "./math";
|
||||
|
||||
console.log(add(22, 2200));
|
||||
console.log(mathAdd(10, 101));
|
||||
|
@ -13,13 +19,10 @@ timed("wasm fibonacci", () => fibonacci(22));
|
|||
timed("js fibonacci", () => fibonacciJavascript(22));
|
||||
|
||||
function timed(name, fn) {
|
||||
if(!console.time || !console.timeEnd)
|
||||
return fn();
|
||||
if (!console.time || !console.timeEnd) return fn();
|
||||
// warmup
|
||||
for(var i = 0; i < 10; i++)
|
||||
fn();
|
||||
console.time(name)
|
||||
for(var i = 0; i < 5000; i++)
|
||||
fn();
|
||||
console.timeEnd(name)
|
||||
for (var i = 0; i < 10; i++) fn();
|
||||
console.time(name);
|
||||
for (var i = 0; i < 5000; i++) fn();
|
||||
console.timeEnd(name);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import await { add } from "./add.wasm";
|
||||
import await { factorial } from "./factorial.wasm";
|
||||
import await { fibonacci } from "./fibonacci.wasm";
|
||||
import { add } from "./add.wasm";
|
||||
import { factorial } from "./factorial.wasm";
|
||||
import { fibonacci } from "./fibonacci.wasm";
|
||||
|
||||
export { add, factorial, fibonacci };
|
||||
|
||||
export function factorialJavascript(i) {
|
||||
if(i < 1) return 1;
|
||||
if (i < 1) return 1;
|
||||
return i * factorialJavascript(i - 1);
|
||||
}
|
||||
|
||||
export function fibonacciJavascript(i) {
|
||||
if(i < 2) return 1;
|
||||
if (i < 2) return 1;
|
||||
return fibonacciJavascript(i - 1) + fibonacciJavascript(i - 2);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
This is a simple example that shows the usage of WebAssembly.
|
||||
|
||||
WebAssembly modules can be imported like other async modules with `import await` or `import()`.
|
||||
WebAssembly modules can be imported like other async modules with `import` or `import()`.
|
||||
When importing, they are downloaded and instantiated in a streaming way.
|
||||
|
||||
# example.js
|
||||
|
|
|
@ -16,7 +16,6 @@ module.exports = {
|
|||
chunkIds: "deterministic" // To keep filename consistent between different modes (for example building only)
|
||||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
importAwait: true
|
||||
asyncWebAssembly: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -305,13 +305,7 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
|
||||
new RuntimePlugin().apply(compiler);
|
||||
|
||||
new InferAsyncModulesPlugin({
|
||||
errorOnImport: options.experiments.importAsync
|
||||
? false
|
||||
: options.experiments.importAwait
|
||||
? "await"
|
||||
: true
|
||||
}).apply(compiler);
|
||||
new InferAsyncModulesPlugin().apply(compiler);
|
||||
|
||||
new DataUriPlugin().apply(compiler);
|
||||
new FileUriPlugin().apply(compiler);
|
||||
|
@ -319,8 +313,7 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
new CompatibilityPlugin().apply(compiler);
|
||||
new HarmonyModulesPlugin({
|
||||
module: options.module,
|
||||
topLevelAwait: options.experiments.topLevelAwait,
|
||||
importAwait: options.experiments.importAwait
|
||||
topLevelAwait: options.experiments.topLevelAwait
|
||||
}).apply(compiler);
|
||||
if (options.amd !== false) {
|
||||
const AMDPlugin = require("./dependencies/AMDPlugin");
|
||||
|
|
|
@ -5,21 +5,12 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const WebpackError = require("../WebpackError");
|
||||
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
||||
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
|
||||
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Module")} Module */
|
||||
|
||||
class InferAsyncModulesPlugin {
|
||||
/**
|
||||
* @param {Object} options options object
|
||||
* @param {boolean | "await"=} options.errorOnImport false: no error, true: error when importing async module, "await": error when import async module without import await
|
||||
*/
|
||||
constructor({ errorOnImport = false } = {}) {
|
||||
this.errorOnImport = errorOnImport;
|
||||
}
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
|
@ -47,20 +38,6 @@ class InferAsyncModulesPlugin {
|
|||
dep instanceof HarmonyImportDependency &&
|
||||
connection.isActive(undefined)
|
||||
) {
|
||||
if (
|
||||
this.errorOnImport &&
|
||||
dep instanceof HarmonyImportSideEffectDependency &&
|
||||
(this.errorOnImport === true || !dep.await)
|
||||
) {
|
||||
const error = new WebpackError(
|
||||
this.errorOnImport === true
|
||||
? "Tried to import async module with import/export (must enable experiments.importAsync to allow this)"
|
||||
: "Tried to import async module with normal import/export (must use 'import await'/'export await' instead)"
|
||||
);
|
||||
error.module = module;
|
||||
error.loc = dep.loc;
|
||||
compilation.errors.push(error);
|
||||
}
|
||||
queue.add(connection.originModule);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,8 +222,6 @@ const applyWebpackOptionsDefaults = options => {
|
|||
const applyExperimentsDefaults = experiments => {
|
||||
D(experiments, "asset", false);
|
||||
D(experiments, "mjs", false);
|
||||
D(experiments, "importAwait", false);
|
||||
D(experiments, "importAsync", false);
|
||||
D(experiments, "topLevelAwait", false);
|
||||
D(experiments, "syncWebAssembly", false);
|
||||
D(experiments, "asyncWebAssembly", false);
|
||||
|
|
|
@ -20,7 +20,6 @@ module.exports = class HarmonyExportDependencyParserPlugin {
|
|||
constructor(options) {
|
||||
const { module: moduleOptions } = options;
|
||||
this.strictExportPresence = moduleOptions.strictExportPresence;
|
||||
this.importAwait = options.importAwait;
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
|
@ -50,15 +49,9 @@ module.exports = class HarmonyExportDependencyParserPlugin {
|
|||
source,
|
||||
parser.state.lastHarmonyImportOrder
|
||||
);
|
||||
sideEffectDep.await = statement.await;
|
||||
sideEffectDep.loc = Object.create(statement.loc);
|
||||
sideEffectDep.loc.index = -1;
|
||||
parser.state.current.addDependency(sideEffectDep);
|
||||
if (statement.await && !this.importAwait) {
|
||||
throw new Error(
|
||||
"Used 'export await' but import-await experiment is not enabled (set experiments.importAwait: true to enable it)"
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -34,7 +34,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
|||
const { module: moduleOptions } = options;
|
||||
this.strictExportPresence = moduleOptions.strictExportPresence;
|
||||
this.strictThisContextOnImports = moduleOptions.strictThisContextOnImports;
|
||||
this.importAwait = options.importAwait;
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
|
@ -51,13 +50,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
|||
parser.state.lastHarmonyImportOrder
|
||||
);
|
||||
sideEffectDep.loc = statement.loc;
|
||||
sideEffectDep.await = statement.await;
|
||||
parser.state.module.addDependency(sideEffectDep);
|
||||
if (statement.await && !this.importAwait) {
|
||||
throw new Error(
|
||||
"Used 'import await' but import-await experiment is not enabled (set experiments.importAwait: true to enable it)"
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -52,7 +52,7 @@ const EMPTY_ARRAY = [];
|
|||
|
||||
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
||||
|
||||
const parser = AcornParser.extend(require("../parsing/importAwaitAcornPlugin"));
|
||||
const parser = AcornParser;
|
||||
|
||||
class VariableInfo {
|
||||
/**
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { tokTypes: tt } = require("acorn");
|
||||
|
||||
/** @typedef {typeof import("acorn").Parser} Parser */
|
||||
|
||||
/**
|
||||
* @param {Parser} P the acorn parser
|
||||
* @returns {Parser} new acorn parser
|
||||
*/
|
||||
module.exports = P => {
|
||||
const Base = /** @type {any} */ (P);
|
||||
const NewParser = /** @type {unknown} */ (class extends Base {
|
||||
parseImport(node) {
|
||||
this.next();
|
||||
// import await '...'
|
||||
if (this.type === tt.name && this.value === "await") {
|
||||
node.await = true;
|
||||
} else {
|
||||
node.await = false;
|
||||
this.pos = this.start;
|
||||
}
|
||||
return super.parseImport(node);
|
||||
}
|
||||
parseExport(node) {
|
||||
this.next();
|
||||
// export await '...'
|
||||
if (this.type === tt.name && this.value === "await") {
|
||||
node.await = true;
|
||||
} else {
|
||||
node.await = false;
|
||||
this.pos = this.start;
|
||||
}
|
||||
const result = super.parseExport(node);
|
||||
if (node.await && !node.source) {
|
||||
this.raiseRecoverable(
|
||||
node.start,
|
||||
"Missing from source in export await"
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return /** @type {Parser} */ (NewParser);
|
||||
};
|
|
@ -368,14 +368,6 @@
|
|||
"description": "Support WebAssembly as asynchronous EcmaScript Module.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"importAsync": {
|
||||
"description": "Allow 'import/export' syntax to import async modules.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"importAwait": {
|
||||
"description": "Allow 'import/export await' syntax to import async modules.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"mjs": {
|
||||
"description": "Support .mjs files as way to define strict ESM file (node.js).",
|
||||
"type": "boolean"
|
||||
|
|
|
@ -91,8 +91,6 @@ describe("Defaults", () => {
|
|||
"experiments": Object {
|
||||
"asset": false,
|
||||
"asyncWebAssembly": false,
|
||||
"importAsync": false,
|
||||
"importAwait": false,
|
||||
"mjs": false,
|
||||
"outputModule": false,
|
||||
"syncWebAssembly": false,
|
||||
|
@ -715,9 +713,8 @@ describe("Defaults", () => {
|
|||
|
||||
@@ ... @@
|
||||
- "asyncWebAssembly": false,
|
||||
+ "asyncWebAssembly": true,
|
||||
@@ ... @@
|
||||
- "mjs": false,
|
||||
+ "asyncWebAssembly": true,
|
||||
+ "mjs": true,
|
||||
@@ ... @@
|
||||
+ },
|
||||
|
|
|
@ -179,9 +179,7 @@ const describeCases = config => {
|
|||
experiments: {
|
||||
mjs: true,
|
||||
asyncWebAssembly: true,
|
||||
topLevelAwait: true,
|
||||
importAwait: true,
|
||||
importAsync: true
|
||||
topLevelAwait: true
|
||||
}
|
||||
};
|
||||
beforeAll(done => {
|
||||
|
|
|
@ -354,32 +354,6 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"experiments-import-async": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Allow 'import/export' syntax to import async modules.",
|
||||
"multiple": false,
|
||||
"path": "experiments.importAsync",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Allow 'import/export' syntax to import async modules.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"experiments-import-await": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Allow 'import/export await' syntax to import async modules.",
|
||||
"multiple": false,
|
||||
"path": "experiments.importAwait",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Allow 'import/export await' syntax to import async modules.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"experiments-mjs": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
|
@ -4299,7 +4299,7 @@ WARNING in Terser Plugin: Dropping unused function someUnRemoteUsedFunction5 [we
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for wasm-explorer-examples-sync 1`] = `
|
||||
"Hash: 236a7aafb9e23319b3b2
|
||||
"Hash: bcdac54c787768809ad1
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
asset 0506579c50fa5de37901.module.wasm 531 bytes [emitted] [immutable]
|
||||
|
@ -4322,17 +4322,17 @@ chunk (runtime: main) bundle.js (main) 586 bytes (javascript) 5.96 KiB (runtime)
|
|||
+ 9 hidden chunk modules
|
||||
chunk (runtime: main) 230.bundle.js 50 bytes (javascript) 156 bytes (webassembly) [rendered]
|
||||
./Q_rsqrt.wasm 50 bytes (javascript) 156 bytes (webassembly) [built]
|
||||
chunk (runtime: main) 325.bundle.js 1.54 KiB (javascript) 274 bytes (webassembly) [rendered]
|
||||
chunk (runtime: main) 325.bundle.js 1.5 KiB (javascript) 274 bytes (webassembly) [rendered]
|
||||
./popcnt.wasm 50 bytes (javascript) 120 bytes (webassembly) [built]
|
||||
./testFunction.wasm 50 bytes (javascript) 154 bytes (webassembly) [built]
|
||||
./tests.js 1.44 KiB [built]
|
||||
./tests.js 1.4 KiB [built]
|
||||
chunk (runtime: main) 526.bundle.js (id hint: vendors) 34 bytes [rendered] split chunk (cache group: defaultVendors)
|
||||
./node_modules/env.js 34 bytes [built]
|
||||
chunk (runtime: main) 780.bundle.js 110 bytes (javascript) 444 bytes (webassembly) [rendered]
|
||||
./fact.wasm 50 bytes (javascript) 154 bytes (webassembly) [built]
|
||||
./fast-math.wasm 60 bytes (javascript) 290 bytes (webassembly) [built]
|
||||
./index.js 586 bytes [built]
|
||||
./tests.js 1.44 KiB [built]
|
||||
./tests.js 1.4 KiB [built]
|
||||
./Q_rsqrt.wasm 50 bytes (javascript) 156 bytes (webassembly) [built]
|
||||
./testFunction.wasm 50 bytes (javascript) 154 bytes (webassembly) [built]
|
||||
./fact.wasm 50 bytes (javascript) 154 bytes (webassembly) [built]
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
it("should allow to use import await", () => {
|
||||
return import("./reexport").then(({ default: value, other }) => {
|
||||
expect(value).toBe(42);
|
||||
expect(other).toBe(42);
|
||||
});
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
export default 42;
|
|
@ -1,4 +0,0 @@
|
|||
export await { default } from "./module";
|
||||
import await value from "./module";
|
||||
|
||||
export const other = value;
|
|
@ -1,6 +0,0 @@
|
|||
it("should allow to use import await", () => {
|
||||
return import("./reexport").then(({ default: value, other }) => {
|
||||
expect(value).toBe(42);
|
||||
expect(other).toBe(42);
|
||||
});
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
await new Promise(r => setTimeout(r, 100));
|
||||
|
||||
export default 42;
|
|
@ -1,4 +0,0 @@
|
|||
export { default } from "./module";
|
||||
import value from "./module";
|
||||
|
||||
export const other = value;
|
|
@ -1,4 +1,4 @@
|
|||
it("should allow to use import await", () => {
|
||||
it("should allow to use top-level-await", () => {
|
||||
return import("./reexport").then(({ default: value, other }) => {
|
||||
expect(value).toBe(42);
|
||||
expect(other).toBe(42);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export await { default } from "./module";
|
||||
import await value from "./module";
|
||||
export { default } from "./module";
|
||||
import value from "./module";
|
||||
|
||||
export const other = value;
|
||||
|
|
|
@ -1 +1 @@
|
|||
export await * from "./module.wat";
|
||||
export * from "./module.wat";
|
||||
|
|
2
test/cases/wasm/finalize-exports-issue-8261/node_modules/side-effect-free/index.js
generated
vendored
2
test/cases/wasm/finalize-exports-issue-8261/node_modules/side-effect-free/index.js
generated
vendored
|
@ -1 +1 @@
|
|||
export await * from "./module.wat";
|
||||
export * from "./module.wat";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { addNumber } from "./wasm.wat";
|
||||
import { addNumber } from "./wasm.wat";
|
||||
|
||||
export var result = addNumber(22);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { getResult } from "./wasm.wasm";
|
||||
import { getResult } from "./wasm.wasm";
|
||||
|
||||
export var result = getResult(1);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { getNumber as getN } from "./wasm.wasm";
|
||||
import { getNumber as getN } from "./wasm.wasm";
|
||||
|
||||
export function getNumber() {
|
||||
return getN();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import await * as a1 from "./mem-access.wat?1";
|
||||
import await * as a2 from "./mem-access.wat?2";
|
||||
import * as a1 from "./mem-access.wat?1";
|
||||
import * as a2 from "./mem-access.wat?2";
|
||||
|
||||
a1.set(42);
|
||||
export const x1 = a1.get();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { trackA, results } from "./tracker";
|
||||
import "./b.js";
|
||||
import await "./wasm.wat";
|
||||
import "./wasm.wat";
|
||||
|
||||
trackA();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { add, getNumber } from "./wasm.wat?1";
|
||||
import { add, getNumber } from "./wasm.wat?1";
|
||||
|
||||
export function run() {
|
||||
return add(getNumber(), 2);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const stringifyRequest = require("loader-utils").stringifyRequest;
|
||||
|
||||
module.exports.pitch = function(remainingRequest) {
|
||||
module.exports.pitch = function (remainingRequest) {
|
||||
return `
|
||||
import await { getString as _getString, memory } from ${stringifyRequest(
|
||||
import { getString as _getString, memory } from ${stringifyRequest(
|
||||
this,
|
||||
`${this.resourcePath}.wat!=!${remainingRequest}`
|
||||
)};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const stringifyRequest = require("loader-utils").stringifyRequest;
|
||||
|
||||
module.exports.pitch = function(remainingRequest) {
|
||||
module.exports.pitch = function (remainingRequest) {
|
||||
return `
|
||||
import await { getString as _getString, memory } from ${stringifyRequest(
|
||||
import { getString as _getString, memory } from ${stringifyRequest(
|
||||
this,
|
||||
`${this.resourcePath}.wasm!=!wast-loader!${remainingRequest}`
|
||||
)};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import await { getNumber } from "./wasm.wat";
|
||||
import { getNumber } from "./wasm.wat";
|
||||
|
||||
export function run() {
|
||||
return getNumber();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import await * as Q_rsqrt from "./Q_rsqrt.wasm";
|
||||
import await * as testFunction from "./testFunction.wasm";
|
||||
import await * as fact from "./fact.wasm";
|
||||
import await * as popcnt from "./popcnt.wasm";
|
||||
import await * as fastMath from "./fast-math.wasm";
|
||||
import await * as duff from "./duff.wasm";
|
||||
import * as Q_rsqrt from "./Q_rsqrt.wasm";
|
||||
import * as testFunction from "./testFunction.wasm";
|
||||
import * as fact from "./fact.wasm";
|
||||
import * as popcnt from "./popcnt.wasm";
|
||||
import * as fastMath from "./fast-math.wasm";
|
||||
import * as duff from "./duff.wasm";
|
||||
|
||||
export function run_Q_rsqrt() {
|
||||
const result = Q_rsqrt._Z7Q_rsqrtf(1/1764);
|
||||
|
|
|
@ -9,8 +9,5 @@ module.exports = {
|
|||
"failing-promise-external":
|
||||
"promise new Promise((resolve, reject) => setTimeout(() => reject(new Error('external reject')), 100))",
|
||||
"import-external": ["import /hello/world.js", "request"]
|
||||
},
|
||||
experiments: {
|
||||
importAsync: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { A, B, C1, C2, D1, D2, E1, E2, E3, F, G } from "./test";
|
||||
|
||||
export { a, b, c, d, e };
|
||||
export { a, b, c, d };
|
||||
|
||||
if (Math.random() > 0.5) {
|
||||
var a = () => A;
|
||||
|
@ -26,21 +26,21 @@ while (Math.random() > 0.5) {
|
|||
let d = () => D1;
|
||||
}
|
||||
|
||||
if(false) {
|
||||
if (false) {
|
||||
E1();
|
||||
}
|
||||
|
||||
export var e = true ? E2 : E3;
|
||||
|
||||
export { f, g }
|
||||
export { f, g };
|
||||
|
||||
if(true) {
|
||||
if (true) {
|
||||
let inner = () => F;
|
||||
|
||||
var f = () => inner();
|
||||
}
|
||||
|
||||
if(true) {
|
||||
if (true) {
|
||||
const inner = () => G;
|
||||
|
||||
var g = () => inner();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import await { getNumber } from "./wasm.wat?1";
|
||||
import await { getNumber as getNumber2 } from "./wasm.wat?2";
|
||||
import { getNumber } from "./wasm.wat?1";
|
||||
import { getNumber as getNumber2 } from "./wasm.wat?2";
|
||||
|
||||
export function run() {
|
||||
return getNumber() + getNumber2();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@ module.exports = {
|
|||
webassemblyModuleFilename: "[id].[hash].wasm"
|
||||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
importAwait: true
|
||||
asyncWebAssembly: true
|
||||
},
|
||||
plugins: [
|
||||
/**
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
module.exports = [[/experiments\.importAsync/]];
|
|
@ -1,3 +0,0 @@
|
|||
it("should not compile the module", function () {
|
||||
expect(() => require("./module"));
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
import { getNumber } from "./wasm.wat";
|
||||
|
||||
export default getNumber();
|
|
@ -1,5 +0,0 @@
|
|||
var supportsWebAssembly = require("../../../helpers/supportsWebAssembly");
|
||||
|
||||
module.exports = function(config) {
|
||||
return supportsWebAssembly();
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
(module
|
||||
(func $getNumber (export "getNumber") (result i32)
|
||||
(i32.const 42))
|
||||
)
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.wat$/,
|
||||
loader: "wast-loader",
|
||||
type: "webassembly/async"
|
||||
}
|
||||
]
|
||||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true
|
||||
}
|
||||
};
|
|
@ -14,7 +14,6 @@ module.exports = {
|
|||
]
|
||||
},
|
||||
experiments: {
|
||||
syncWebAssembly: true,
|
||||
importAwait: true
|
||||
syncWebAssembly: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import await * as Q_rsqrt from "./Q_rsqrt.wasm";
|
||||
import await * as testFunction from "./testFunction.wasm";
|
||||
import await * as fact from "./fact.wasm";
|
||||
import await * as popcnt from "./popcnt.wasm";
|
||||
import await * as fastMath from "./fast-math.wasm";
|
||||
import await * as duff from "./duff.wasm";
|
||||
import * as Q_rsqrt from "./Q_rsqrt.wasm";
|
||||
import * as testFunction from "./testFunction.wasm";
|
||||
import * as fact from "./fact.wasm";
|
||||
import * as popcnt from "./popcnt.wasm";
|
||||
import * as fastMath from "./fast-math.wasm";
|
||||
import * as duff from "./duff.wasm";
|
||||
|
||||
export function run_Q_rsqrt() {
|
||||
const result = Q_rsqrt._Z7Q_rsqrtf(1/1764);
|
||||
|
|
|
@ -19,7 +19,6 @@ module.exports = {
|
|||
modules: true
|
||||
},
|
||||
experiments: {
|
||||
asyncWebAssembly: true,
|
||||
importAwait: true
|
||||
asyncWebAssembly: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2521,16 +2521,6 @@ declare interface Experiments {
|
|||
*/
|
||||
asyncWebAssembly?: boolean;
|
||||
|
||||
/**
|
||||
* Allow 'import/export' syntax to import async modules.
|
||||
*/
|
||||
importAsync?: boolean;
|
||||
|
||||
/**
|
||||
* Allow 'import/export await' syntax to import async modules.
|
||||
*/
|
||||
importAwait?: boolean;
|
||||
|
||||
/**
|
||||
* Support .mjs files as way to define strict ESM file (node.js).
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue