timecc
timecc

Reputation: 161

Webpack fails with Node FFI and Typescript - dynamic require error

In a simple Typescript program I require Node FFI with

import  * as Electron   from  'electron';`
import  * as ffi        from  'ffi';`

and then

mylib = ffi.Library('libmoi', {
  'worker': [ 'string', [ 'string' ]  ],
  'test'  : [ 'string', []            ]
  } );

Linking that up via webpack yields

WARNING in ./~/bindings/bindings.js
Critical dependencies:
76:22-40 the request of a dependency is an expression
76:43-53 the request of a dependency is an expression
 @ ./~/bindings/bindings.js 76:22-40 76:43-53

The problem seems to be that FFI has a dynamic require and the fix seems to be to apply webpack.ContextReplacementPlugin in the webpack.config.js file.

This is a bit out of my reach, but an example for an Angular case is:

plugins: [
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        root('./src') // location of your src
      )
  ]

Any idea how to do this for FFI?

Upvotes: 0

Views: 1683

Answers (2)

Vikash
Vikash

Reputation: 493

I also had a similar issue, somehow, I managed to resolve it. I will first explain my understanding.

Main work of webpack is to bundle the separate code file into one file, by default it bundles all the code that is referenced in its tree.

Generally two types of node_modules:

  1. To be used on browser side(angular, rxjs etc)
  2. To be used on nodejs side(express, ffi etc)

It is safer to bundle browser side node_module but not safer to bundle node side node_module because they are not designed like that So the solution is below two steps:

  1. Give appropriate target(node, electron etc) in webpack.config.js file e.g "target":'electron-renderer' by default it is browser
  2. Declare node_side module as external dependency in your webpack.config.js file e.g.

    "externals": {
        "bindings": "require('bindings')",
        "ffi": "require('ffi')"
    }
    

Upvotes: 0

timecc
timecc

Reputation: 161

Here is the answer: github issue comment on the Johnny-Five repo

Quoting from brodo's answer, this is what you do to stop webpack getting snarled up with "bindings" and similar:

... the webpack config looks like this:

module.exports = {
  plugins: [
    new webpack.ContextReplacementPlugin(/bindings$/, /^$/)
  ],
  externals: ["bindings"]
}

Upvotes: 3

Related Questions