2

I'm just getting started with Webpack (for use w/ React), and I'm running into an issues when trying to pull in bower packages. I have installed pickadate through bower and I have the following webpack config (original). Looking at the pickadate bower.json file, it has an array instead of just a string for main as it needs to pull in multiple js and css files.

// ./webpack/dev.config.js
// ...
resolve: {
  modulesDirectories: [
    'src',
    'node_modules',
    'bower_components'
  ],
  plugins: [
    new webpack.ResolverPlugin(
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
    )
  ],
  extensions: ['', '.json', '.js']
},

My Component:

import React, {Component, PropTypes} from 'react';

import $ from 'jquery';
import pickadate from 'pickadate';

class DateInput extends Component {
  // ...
}

I get the following errors for jquery and pickadate modules:

@ ./src/components/forms/DateInput.js 17:14-31
[0] ./src/components/forms/DateInput.js
[0] Module not found: Error: Cannot resolve module 'jquery' in /Users/chris7519/Desktop/react-redux-universal-hot-example/src/components/forms
[0] resolve module jquery in /Users/chris7519/Desktop/react-redux-universal-hot-example/src/components/forms
[0]   looking for modules in /Users/chris7519/Desktop/react-redux-universal-hot-example/src
[0]     /Users/chris7519/Desktop/react-redux-universal-hot-example/src/jquery doesn't exist (module as directory)
[0]     resolve 'file' jquery in /Users/chris7519/Desktop/react-redux-universal-hot-example/src
[0]       resolve file
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/jquery doesn't exist
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/jquery.json doesn't exist
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/jquery.js doesn't exist

// ...

Module not found: Error: Cannot resolve module 'pickadate' in /Users/chris7519/Desktop/react-redux-universal-hot-example/src/components/forms
[0] resolve module pickadate in /Users/chris7519/Desktop/react-redux-universal-hot-example/src/components/forms
[0]   looking for modules in /Users/chris7519/Desktop/react-redux-universal-hot-example/src
[0]     /Users/chris7519/Desktop/react-redux-universal-hot-example/src/pickadate doesn't exist (module as directory)
[0]     resolve 'file' pickadate in /Users/chris7519/Desktop/react-redux-universal-hot-example/src
[0]       resolve file
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/pickadate doesn't exist
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/pickadate.json doesn't exist
[0]         /Users/chris7519/Desktop/react-redux-universal-hot-example/src/pickadate.js doesn't exist

I attempted to install both jquery and pickadate through npm, but I still get the error Cannot find module 'pickadate'

3 Answers 3

2

The pickadate module on npm has a broken package.json file: it doesn't specify a main entry, so webpack has no idea how to resolve require('pickadate'). You should probably file an issue upstream for them to fix this, but in the meanwhile you can fix it in your webpack.config.js.

So, you want to install both pickadate and jquery through npm, and then add the following to webpack.config.js:

{
    resolve: {
        alias: {
            'pickadate' : 'pickadate/lib/picker',
        },
    },
 }

This basically treats all instances of require('pickadate') into require('pickadate/lib/picker'). This reaches into the pickadate package and actually requires a real file. If upstream fixes their package.json to have a main entry, you can delete this alias from your config and all your requires will work properly.

More information about how the alias option works: http://webpack.github.io/docs/configuration.html#resolve-alias

Sign up to request clarification or add additional context in comments.

2 Comments

I gave this a try, but I'm still getting an error stating that it cannot find module 'pickadate'
Does it work if you require pickadate/libs/picker (i.e. is it the alias that's not working?)
0

The webpack.ResolverPlugin.DirectoryDescriptionFilePlugin doesn't handle bower.json description file when the 'main' field is an array, for example Bootstrap:

"main": [
"less/bootstrap.less",
"dist/js/bootstrap.js"
]

In that case, you should install the package using npm, and require() css files explicitly

Comments

0

I faced the same issue using a pickadate wrapper (ng-pickadate), hopefully most of the quirks will apply:

  • Referencing the js files, pickadate package json entry point seems not to be ok.
  • Disabling AMD for the pickadate node modules path.
  • Add providepluing ($, Jquery, window.jquery).

Bellow the step by step guide (remove the angular part, if you just want to configure pickadate).

Following the steps mentioned in this thread, I manage to make it work without having to tweak the code under node_modules. Just a quick recap (angular 1, webpack 2 solution):

First install ng-pickadate

npm install ng-pickadate

It will download as well jquery and pickadate dependencies.

Then we need to add the depencies in our webpack.config, here there's a catch pickadate.js package json main seems not to be pointing to the right entry point, we have to manually indicate which files we want to include:

diff module.exports = { context: path.join(basePath, 'src'), resolve: { extensions: ['.js', '.ts'] }, entry: { app: './app/app.ts', vendor: [ + 'jquery', + 'angular',
+ 'pickadate/lib/picker', + 'pickadate/lib/picker.date',
+ 'ng-pickadate', ],

Now comes fun part, pickadate will try to load AMD modules, in my case we need commonjs, we don't want to change the code on the library, rather disable this using a rule (loader), just only for the pickadate folder:

diff module: { rules: [ + { + test: /pickadate/, + parser: { amd: false } + },
{ test: /\.ts$/,

Now let's review our provide plugin and ensure we have all this ways of global referencing jquery (window.jquery quite important !)

diff plugins: [ + new webpack.ProvidePlugin({ + "$": "jquery", + "jQuery": "jquery", + "window.jQuery": "jquery",
}),
It's time to start using this in our app, let's include it in the angular module where we are using it (we are using angular 1.6):

```diff import * as angular from 'angular'; import { LoginComponent } from './login.component';

export const LoginModule = angular.module('loginModule', + ['pickadate']) .component('login', LoginComponent) ; ```

And let's use the directive in the HTML (input)

diff <div class="form-group"> <label for="txtEmail">Birthdate</label> <input type="text" + pick-a-date="vm.curDate"/> </div>

All this steps are just a recap of feedback got from several issues that were open, thanks to all the chaps that were providing the right tips :-). The parts that are new are marked with "+" (it seems stackoverflow doesn't support diff).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.