简体   繁体   中英

Webpack throws error with Emscripten: Can't resolve 'fs'

I'm encountering errors in importing a javascript file into a vue.js component:

This is the content of /components sub-folder:

/startingV/src/components$ ls -lah
total 132K
drwxr-xr-x 2 marco marco 4,0K dic 26 11:22 .
drwxr-xr-x 5 marco marco 4,0K dic 26 09:32 ..
-rw-r--r-- 1 marco marco  441 nov  2  2016 Counter.vue
-rw-r--r-- 1 marco marco  441 dic 21 15:13 FormValidation.vue
-rw-r--r-- 1 marco marco 100K dic 26 10:38 js_plumbing.js
-rw-r--r-- 1 marco marco 9,3K dic 26 10:38 js_plumbing.wasm
-rw-r--r-- 1 marco marco  473 dic 26 11:14 Result.vue

When compiling:

Failed to compile.

./src/components/js_plumbing.js
Module not found: Error: Can't resolve 'fs' in '/home/marco/cpp/WebAssemblyinAction
/Appendix_B/B.1_ccall/startingV/src/components'

this is the Result.vue file:

template>
    <p button @click="callAdd">Add!</p>
</template>

<script>
    import * as js_plumbing from './js_plumbing'
    export default {
      data () {
        return {
          result: null
        }
      },
      methods: {
        callAdd() {
          const result = Module.ccall('js_plumbing.Add',
              'number',
              ['number', 'number'],
              [1, 2]);
          console.log('Result: ${result}');
        }
      }
    }
</script>

The js_plumbing.js and the js_plumbing.wasm files have been generated through this command :

emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']

where add.c is:

#include <stdlib.h>
#include <emscripten.h>

// If this is an Emscripten (WebAssembly) build then...
#ifdef __EMSCRIPTEN__
  #include <emscripten.h>
#endif

#ifdef __cplusplus
extern "C" { // So that the C++ compiler does not rename our function names
#endif

EMSCRIPTEN_KEEPALIVE
int Add(int value1, int value2) 
{
  return (value1 + value2); 
}

#ifdef __cplusplus
}
#endif

This is the link I took some info about how to generate the .js and .wasm files: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-ccall-cwrap

Complete error message in the command line when doing npn run dev :

(base) marco@marco-U36SG:~/cpp/WebAssemblyinAction/Appendix_B 
/B.1_ccall/startingV$ npm run dev

> myproject@1.0.0 dev /home/marco/cpp/WebAssemblyinAction/Appendix_B 
/B.1_ccall/startingV
> cross-env NODE_ENV=development webpack-dev-server --open --hot

✖ 「wdm」: Hash: 12bee4de7abfde1cbc5d
Version: webpack 4.41.3
Time: 6707ms
Built at: 12/26/2019 12:37:07 PM
   Asset      Size  Chunks                    Chunk Names
build.js  2.18 MiB    main  [emitted]  [big]  main
Entrypoint main [big] = build.js
[0] multi (webpack)-dev-server/client?http://localhost:8080   
(webpack)/hot/dev-server.js ./src/main.js 52 bytes {main} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/vue/dist/vue.esm.js] 319 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http:
//localhost:8080] (webpack)-dev-server/client?http://localhost:8080  
4.29 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-
server/client/overlay.js 3.51 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-
server/client/socket.js 1.53 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/createSocketUrl.js]   
(webpack)-dev-server/client/utils/createSocketUrl.js 2.89 KiB {main} 
[built]
[./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-
server/client/utils/log.js 964 bytes {main} [built]
[./node_modules/webpack-dev-server/client/utils/reloadApp.js] 
(webpack)-dev-server/client/utils/reloadApp.js 1.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/sendMessage.js] 
(webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main}   
[built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync 
nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js
 1.59 KiB {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 
bytes {main} [built]
[./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-
apply-result.js 1.27 KiB {main} [built]
[./src/main.js] 134 bytes {main} [built]
    + 34 hidden modules

ERROR in ./src/components/js_plumbing.js
Module not found: Error: Can't resolve 'fs' in '/home/marco 
/cpp/WebAssemblyinAction/Appendix_B/B.1_ccall/startingV
/src/components'
 @ ./src/components/js_plumbing.js 88:26-39
 @ ./node_modules/babel-loader/lib!./node_modules/vue-loader
/lib/selector.js?type=script&index=0!./src/components/Result.vue
 @ ./src/components/Result.vue
 @ ./node_modules/babel-loader/lib!./node_modules/vue-loader
/lib/selector.js?type=script&index=0!./src/App.vue
 @ ./src/App.vue
 @ ./src/main.js

How to solve it? Marco

TLDR;

There are two solutions:

  1. Add -s ENVIRONMENT='web' in your emcc command, so try emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s ENVIRONMENT='web'

or

  1. Add "node": { "fs": "empty" } field in your webpack.config.js . I don't know how to do it in zero-config way though.

Why

Emscripten's emcc command produces both .js and .wasm files. The .js file is not only a wrapper of the .wasm but also provides a C/C++ runtime for the web, and more importantly in the question, a generic loader for the .wasm file.

The .js file's loader is very comprehensive that covers node, web, web worker, and D8 JS shell by default. This often make problems with bundlers such as Webpack because the bundlers try to resolve all modules in the source code, including require('fs') which is used for loading .wasm file in the nodejs environment, and the bundler produces error if any module is not available for the web environment.

One way to avoid the problem is that to use ENVIRONMENT flag in emcc command. This will remove some problematic codes such as require('fs') .

Another way is to let Webpack ignore fs module by adding "node": { "fs": "empty" } in the webpack configuration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM