Ammo.js webpack issues

Hi folks,

I’ve been following the ES6 docs for setting up a physics plugin with Babylon, However the AmmoJSPlugin keeps giving me an error

TypeError: Ammo.btCompoundShape is not a constructor

Heres my webpack config. At the bottom I’m using the ProvidePlugin like in the docs to point Ammo to ammo.js in the npm modules folder, but it wont work with any combination of configuration I can think of.

const webpack = require('webpack')
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    entry: path.join(__dirname, "src/index.js"),
    output: {
        filename: "build.js",
        path: path.join(__dirname, "dist"),
    },
    module: {
        rules:[{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        },
        {
            test: /\.css$/,
            use: [
                {loader: "style-loader"},
                {loader: "css-loader"},
            ]
        },
        {
            test: /\.png$/,
            exclude: /assets/,
            loader: "url-loader"
        },
        {
            test: /\.(gltf|png|bin|glb)$/,
            loader: "file-loader",
            options: {
                name: 'assets/[name].[hash:7].[ext]'
            }
        },
        {
            test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
            use: [{
              loader: 'file-loader',
            }]
        },
        {
            test: /\.wasm$/,
            loader: 'wasm-loader'
        }]
    },
    optimization: {
        minimizer: [new UglifyJsPlugin({
            test: /\.js(\?.*)?$/i}
        )]
    },
    externals: [
        "fs"
    ],
    plugins: [
        new HtmlWebPackPlugin({
            template: path.join(__dirname, "src/index.html")
        }),
        new webpack.ProvidePlugin({
            Ammo: 'ammo.js'
        })
    ]
}

The issue is that webpack-stream has no ProvidePlugin method. Here’s an example of this issue a and a solution I found on GitHub.

Galen

Thanks for the suggestion but that doesn’t appear to be the solution. The issue you found is with webpack-stream which intergrates webpack with gulp, and I’m not using gulp.

Just to test that ProvidePlugin is working correctly I used it to add babylon itself to all my modules and its working fine for importing babylon but ammo is still saying everything is not a constructor

new webpack.ProvidePlugin({
    BABYLON: '@babylonjs/core',
    Ammo: 'ammo.js'
})

I noticed webpack is giving a warning about type errors with asm.js which might give us another clue as to what is going wrong.

TypeError: asm.js type error: 'undefined' not found in local or asm.js module scope

Pinging @sebavan and @trevordev

Unfortunately Ammo does not seem to be as Webpack friendly as I thought :frowning:

So here you can :
npm install kripken/ammo.js

This will install ammo as an npm dependency from github as there is no up to date package.

Then in your webpack config, do not rely on providePlugin as it would push the wrapper and not the actual Ammo.

You can instead first disable fs to prevent webpack to fail due to fs dependencies. In your webpack config add the following:

    node: {
        fs: 'empty'
    }

Then in your code using Babylon, you can inject your ammo dependency relying on this:

import * as ammo from "ammo.js";
scene.enablePhysics(new Vector3(0,-10,0), new AmmoJSPlugin(undefined, ammo));

I will reflect this in the doc as I agree it is not obvious :slight_smile:

1 Like

That seems to have done the trick. Adding this to the docs would be a great idea! That way the next poor soul doesn’t have to muck about trying to get this working.

Thanks a million @sebavan!

1 Like

I installed from npm i --save-dev kripken/ammo.js, added that node: { fs: 'empty' } and used the import statement described here. No luck, I get this in the import statement:

Naturally, it suggest that I try to install type definitions though the obvious choice for types here doesn’t exist in npm.

There is not much we can do if they do not provide the typings, Could you not cast as any for this one ? I know it is not ideal but without typings, it does not leave a lot of options.

I turned off noImplicitAny but then received advice on casting to any which I wasn’t aware of. Thanks!

1 Like