问题
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'
回答1:
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
回答2:
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
回答3:
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).
来源:https://stackoverflow.com/questions/31863079/webpack-bower-multiple-css-js-files