Require third party RequireJS modules with Webpack - javascript

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
Should I have to require the entire path like that?
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?

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';

Related

Making Webpack register modules in RequireJS cache

Currently I'm using RequireJS for all my modules.
I'm considering using Webpack for my main project but need to load modules not known during build time. Like plugins.
One approach would be to use Webpack at build time and then use RequireJS at runtime. The only problem is that files loaded from Webpack bundle won't be found in the RequireJS cache.
If I manually register them it works:
import jQuery from 'jquery';
define('jquery', [], function() { return jQuery; });
But is there some easier way? Like Webpack generating code that does this?
I ended up writing a custom loader that added the code at the end of each file. Using window.define instead of define makes Webpack leave it intact for RequireJS.

Can I use unpkg or browserify to include single NPM packages in a frontend project?

So I'm working with JS on the frontend, building something for a client. Details aren't super important except that I do not have access to node.
I'm using unpkg to include various NPM packages in the browser (like React/ReactDOM/Babel for instance). These packages have a UMD build so they work out of the box.
However, there are a few packages I'd like to use that do not have a UMD build (namely react-dates or react-datepicker). I've tried serving different files via unpkg and referencing the exported modules. Since they don't have UMD builds, I'll either get an error module is not defined which makes sense, or that the module I'm referencing DatePicker is not defined.
So I thought maybe I could build a single file with browserify but I've never used it before and any docs I could find are lacking. Heres what I did
var DatePicker = require("react-dates");
In a file called test.js and then:
browserify test.js -o bundle.js
Output that, upload it to the client assets, reference it like:
<script src="/js/bundle.js"></script>
But var DatePicker = require("DatePicker") throws error require is not defined (I thought that was the point of browserify?) and console.log(DatePicker) throws is not defined as well.
At this point I'm at a loss. I'm being stubborn but I really really just want to use a react datepicker and avoid adding jQuery to this project for the sole purpose of a datepicker. As far as I can tell unpkg is not an option but I feel like browserify could work and I'm just doing something wrong.
Any help is greatly appreciated!
You don't have to do this, you can find the needed files in the dist folder (New folder\node_modules\react-datepicker) after you "npm install react-datepicker" within a folder, but be sure you have a package file into that, otherwise the install won't work.
The files should look like this
EDIT:
The requirejs code that you need is
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.2/require.min.js"></script>
<script>
requirejs.config({
paths: {
'react': 'https://unpkg.com/react#15.3.2/dist/react',
'react-dom': 'https://unpkg.com/react-dom#15.3.2/dist/react-dom',
'prop-types': 'https://unpkg.com/prop-types#15.6.0/prop-types',
'react-onclickoutside': 'https://unpkg.com/react-onclickoutside#6.7.0/dist/react-onclickoutside',
'react-popper': 'https://unpkg.com/react-popper#0.7.4/dist/react-popper',
'moment': 'https://unpkg.com/moment#2.19.3/moment',
'datepicker': 'https://unpkg.com/react-datepicker#0.61.0/dist/react-datepicker'
}
});
requirejs(['react', 'react-dom', 'prop-types', 'react-onclickoutside', 'react-popper', 'moment', 'datepicker'], function(React, ReactDOM, PropTypes, onClickOutside, Popper, moment, DatePicker) {
ReactDOM.render(
React.createElement('p', {}, 'Hello, World!'),
document.getElementById('root')
)
});
but as far as I got, datepicker requested for "module" which is not defined, this can be the same problem as here. I will investigate more about this issue.

import requirejs amd module with webpack

I'm using Converse.js and it's prebuilt into the RequireJS/AMD syntax. Including the file from a CDN you could use it like require(['converse'], function (converse) { /* .. */ }). How is it possible to use this with webpack? I would like to bundle converse.js with my webpack output.
I have the file on disk, and want to import it like
import converse from './converse.js';
converse.initialize({ .. });
Webpack picks up the file and bundles it correctly, although it's not useable yet as it throws 'initialize is not a function'. What am I missing?
I suspect the way their bundle is built will not work correctly with how Webpack evaluates modules in a limited context.
From their builds, taking the built AMD module via NPM without dependencies should be parsable by Webpack and it will enable you to provide the dependencies to avoid dupes in the final output.
If all else fails, using the script-loader will evaluate the script in the global context and you'd get the same experience as if you'd have followed their usage guidelines to reference it from a CDN, just don't forget to configure the globals for your linter.

Resolving alias in webpack

I am trying to resolve an alias in webpack but can't seem to figure out why this isn't working. I am using a library called GoJS. I have the below code in my module.exports of webpack:
resolve: {
alias: {
go: path.resolve(__dirname, './go.min.js')
}
}
This file is in my root project directory for now. At the top of my ES6 module I have:
import go from 'go';
I have also tried:
var go = require("go");
The library does seem to be loading. If I console.log(go) within the module, it returns an empty object. Do I need to load this file a different way because of how it is designed? Or is something wrong with my webpack settings?
Here is the javascript file I am trying to load
This is solved by updating GoJS to a later (1.5 or beyond probably) version, as it handles modules/requires/imports differently after that.

RequireJS tries to load webpack externals

Using Webpack, I'm exporting two distribution files for a project. One with dependencies bundled and one without.
Throughout the application, we use commonjs require('lodash.assign'); includes which webpack understands.
However, I've configured one of our builds to ignore these (for users who already use lodash and have it available).
externals = {
'lodash.assign': 'var _.assign',
'lodash.clonedeep': 'var _.cloneDeep'
};
This works as expected. However, because our libraryTarget is umd we support RequireJS. However, RequireJS still actually thinks these files should be loaded and I'm seeing a ton of errors:
require.min.js:1 GET http://127.0.0.1/_.assign.js req.load
# Uncaught Error: Script error for "_.assign"
It can't figure out where to find script. How can I configure webpack, or even requirejs to ignore these, since they're being mapped by webpack?
By looking at the compiled output, I see the reason requirejs thinks it's supposed to load these files:
define(["_.assign", "_.cloneDeep"], factory);
When I manually modify code to the following, it works:
define(['lodash'], factory);

Categories

Resources