2
votes

I'm working on an application that needs to pull in the ReadiumJS library, which uses AMD modules. The app itself is written in es6 w/ webpack and babel. I've gotten the vendor bundle working correctly, and it's pulling in the built Readium file, but when I try to require any of the modules Webpack says it can't resolve them. Anyone ever do this before with Webpack and RequireJS? Here's some info that may help - not sure what else to include as this is my first time really using Webpack..

Folder Structure

/readium-src
  /readium-js
    / *** all readium-specific files and build output (have to pull down repo and build locally)
/node_modules
/src
  /app.js -> main entry for my app

/webpack.config.babel.js

webpack.config.js entries

entry: {
    vendorJs: [
        'jquery',
        'angular',
        '../readium-src/readium-js/build-output/_single-bundle/readium-js_all.js',
        'bootstrap/js/alert.js' //bootstrap js example
    ],
    appJs: './app.js'
}

Trying to require it in app.js

var readiumSharedGlobals = require('readium_shared_js/globals');

I never really got into using RequireJS, so really struggling to understand how to consume that type of module along side other types of modules with webpack. Any help greatly appreciated :)

Update

If I change my app.js to use this instead:

window.rqReadium = require('../readium-src/readium-js/build-output/_single-bundle/readium-js_all.js');

Then it appears to try to load all the modules, but I get a strange error:

Uncaught Error: No IPv6

At this point, I'm unsure of

  1. Should I have to require the entire path like that?
  2. Is this error something from webpack, requirejs, or Readium? Tried debugging, but couldn't find anything useful...

UPDATE 8/12/2016

I think this is related to an issue with a library that Readium is depending on: https://github.com/medialize/URI.js/issues/118

However, I'm still not clear on how to correctly import AMD modules with webpack. Here's what I mean:

Let's say I have an amd module defined in moneyService.amd.js like this:

define('myMoneyService', ['jquery'], function($) {
    //contrived simple example...
    return function getDollaz() { console.log('$$$'); }
});

Then, in a sibling file, app.js, I want to pull in that file.

//this works
var getDollaz = require('./moneyService.amd.js');

//this works
require(['./moneyService.amd.js'], function(getDollaz) { getDollaz(); }

//this does not
require(['myMoneyService' /*require by its ID vs file name*/], function(getDollaz) {
    getDollaz(); 
}

So, if we cannot require named modules, how would we work with a third party lib's dist file that has all the modules bundled into a single file?

1
The require call you are using is in the CommonJS style, not AMD (RequireJS) style. You'll have to include RequireJS in your script, possibly wrap your module in define methods (or shim configs) and initiate it with a require call. It's a big paradigm shift from CommonJS (but cleaner, imho)Steve Hynding
@SteveHynding I'm using Webpack, and it already understands AMD, CommonJS, and (with babel) ES6. Have you used Webpack with requirejs, or are you answering from a purely requirejs only perspective?Bradley Gore
What's the exact error message when it says it can't resolve ReadiumJS?kentcdodds
@kentcdodds if I require the full path to the built lib, then it does pull in the entire thing, then there's an error in the console about IPv6 not being found (see first update). I believe that's an issue with their dependency on urijs and not a webpack issue. However, I'm still fuzzy on why I have to require the full file vs module's ids (see second update). Still finding my feet w/ webpack - really appreciate the help :)Bradley Gore

1 Answers

2
votes

Ok, so there's a repo out there for an Electron ePub reader using Readium, and it's using webpack: https://github.com/clebeaupin/readium-electron This shows a great way to handle pulling in RequireJS modules with webpack.

One super awesome thing I found is that you can specify output.library and output.libraryTarget and webpack will transpose from one module format to another... freaking awesome! So, I can import the requirejs module, set output library and libraryTarget to 'readium-js' and 'commonjs2' respectively, then inside my application code I can do import Readium from 'readium-js';