diff --git a/packages/react-scripts/config/jest/wasmTransform.js b/packages/react-scripts/config/jest/wasmTransform.js
new file mode 100644
index 00000000000..fb20489aeaa
--- /dev/null
+++ b/packages/react-scripts/config/jest/wasmTransform.js
@@ -0,0 +1,31 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2018-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const path = require('path');
+
+// This is a custom Jest transformer for WASM imports.
+// http://facebook.github.io/jest/docs/en/webpack.html
+
+module.exports = {
+ process(src, filename) {
+ const assetFilename = JSON.stringify(path.basename(filename));
+
+ return `
+ const fs = require('fs');
+ const buffer = fs.readFileSync(${assetFilename});
+ const module = new WebAssembly.Module(buffer);
+ const instance = new WebAssembly.Instance(module);
+
+ module.exports = {
+ __esmodule: true,
+ default: instance.exports,
+ }`;
+ },
+};
diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js
index b719054583b..c4549cc14e2 100644
--- a/packages/react-scripts/config/paths.js
+++ b/packages/react-scripts/config/paths.js
@@ -58,6 +58,7 @@ const moduleFileExtensions = [
'json',
'web.jsx',
'jsx',
+ 'wasm',
];
// Resolve file paths in the same order as webpack
diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js
index 746884a03eb..4a558d6b1e1 100644
--- a/packages/react-scripts/config/webpack.config.js
+++ b/packages/react-scripts/config/webpack.config.js
@@ -506,7 +506,7 @@ module.exports = function(webpackEnv) {
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
- exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
+ exclude: [/\.(js|mjs|jsx|ts|tsx|wasm)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
index 32c9b47a48d..a08b71f8ce2 100644
--- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
@@ -146,5 +146,11 @@ describe('Integration', () => {
);
doc.defaultView.close();
});
+
+ it('wasm inclusion', async () => {
+ const doc = await initDOM('wasm-inclusion');
+
+ expect(doc.getElementById('wasm-inclusion').textContent).toBe('11');
+ });
});
});
diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js
index 380a49fc639..6464e22be18 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/App.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/App.js
@@ -222,6 +222,11 @@ class App extends Component {
this.setFeature(f.default)
);
break;
+ case 'wasm-inclusion':
+ import('./features/webpack/WasmInclusion').then(f =>
+ this.setFeature(f.default)
+ );
+ break;
default:
throw new Error(`Missing feature "${feature}"`);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.js
new file mode 100644
index 00000000000..f8e54d7774d
--- /dev/null
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.js
@@ -0,0 +1,6 @@
+import React from 'react';
+import('./assets/add.wasm')
+ .then(console.log)
+ .catch(console.log);
+
+export default () => ;
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.test.js
new file mode 100644
index 00000000000..aeb2cb59d44
--- /dev/null
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/WasmInclusion.test.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import WasmInclusion from './WasmInclusion';
+
+describe('wasm inclusion', () => {
+ it('renders without crashing', () => {
+ const div = document.createElement('div');
+ ReactDOM.render(, div);
+ });
+});
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/add.wasm b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/add.wasm
new file mode 100644
index 00000000000..357f72da7a0
Binary files /dev/null and b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/add.wasm differ
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index 1f6b8cfafec..c27b8eb16b0 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -67,7 +67,7 @@
"style-loader": "0.23.0",
"terser-webpack-plugin": "1.1.0",
"url-loader": "1.1.1",
- "webpack": "4.19.1",
+ "webpack": "4.23.0",
"webpack-dev-server": "3.1.9",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "3.6.3"
diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js
index 58c2ad48812..d01a092c6ac 100644
--- a/packages/react-scripts/scripts/utils/createJestConfig.js
+++ b/packages/react-scripts/scripts/utils/createJestConfig.js
@@ -52,6 +52,7 @@ module.exports = (resolve, rootDir, isEjecting) => {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': resolve(
'config/jest/fileTransform.js'
),
+ '^.+\\.wasm': resolve('config/jest/wasmTransform.js'),
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$',