javascriptreactjsnpmsoundjs

Using createjs-soundjs in react web app


I would like to use https://www.npmjs.com/package/createjs-soundjs to play sounds on a react web app.

I installed the package normally with npm install createjs-soundjs and it's showing in the packages list. How should I include this to my project, so that I could use it?

I have tried the following:

import React from 'react';
import classNames from 'classnames';
import createjs from 'createjs';
import SoundJS from 'createjs-soundjs'; // this line causes an error

The error message in console: soundjs-0.6.2.min.js:17 Uncaught ReferenceError: createjs is not defined. This error message is very clear, but I have no idea where to start. Am I missing something fundamental?


Solution

  • The SoundJS core bundle is not in the proper CommonJS or ES6 format, it's a bundle that makes strong assumption that it's loaded as a top-level script in the browser. So it first tries to create the global value by assigning it to a property on this (which it assumes to be the window) and then tries to access this global values as just createjs. So obviously this doesn't work in the module context.

    There's a workaround though, the code is for Webpack 2 and based on this comment (which is for Webpack 1):

    module: {
      rules: [
        // ...
        {
          test: /createjs/,
          use: [
            'imports-loader?this=>window',
            'exports-loader?createjs'
          ]
        },
        // ...
      ]
    },
    
    plugins: [
      // ...
      new webpack.ProvidePlugin({
        'createjs': 'createjs',
      }),
      // ...
    ],
    
    resolve: {
      alias: {
        'createjs': path.resolve(__dirname, '../lib/soundjs-0.6.2.combined'),
      }
    },
    

    The 3rd entry (resolve.alias) maps the imports of createjs to the file I've downloaded and placed into my lib folder (which is not as elegant as using something from npm, but now I'm sure what I get. npm version might work as well).

    The first entry (module.rules) tells Webpack to first substitute this with window, and then to take the createjs instance from the global (window) context and make it the module export.

    Finally, the 2nd entry (ProvidePlugin) precedes all requests for global createjs (in other modules) with const createjs = require('createjs').