$(…).datetimepicker is not a function

2019-01-27 19:38发布

I use webpack and want to use bootstrap-datetimepicker. In my webpack config I use ProvidePlugin to get "jquery module".

In my code I get error $(...).datetimepicker is not a function when I call $('#datetimepicker12').datetimepicker function. I don't why $ variable doesn't contain datetimepicker function, which should be defined in var datetimepicker = require('eonasdan-bootstrap-datetimepicker');

webpack.config.js

var webpack = require('webpack');
var merge = require('webpack-merge');
var NpmInstallPlugin = require('npm-install-webpack-plugin');
var autoprefixer = require('autoprefixer');

const TARGET = process.env.npm_lifecycle_event;
console.log("target event is " + TARGET);

var common = {
  cache: true,
  debug: true,
  entry: './src/script/index.jsx',
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  output: {
    filename: 'index.js',
    sourceMapFilename: '[file].map'
  },
  module: {
    loaders: [{
      test: /\.js[x]?$/,
      loaders: ['babel'],
      exclude: /(node_modules|bower_components)/
    }, {
      test: /\.css$/,
      loaders: ['style', 'css']
    }, {
      test: /\.scss$/,
      loaders: ['style', 'css', 'postcss', 'sass']
    }, {
      test: /\.less$/,
      loaders: ['style', 'css', 'less']
    }, {
      test: /\.woff$/,
      loader: "url-loader?limit=10000&mimetype=application/font-woff&name=[path][name].[ext]"
    }, {
      test: /\.woff2$/,
      loader: "url-loader?limit=10000&mimetype=application/font-woff2&name=[path][name].[ext]"
    }, {
      test: /\.(eot|ttf|svg|gif|png)$/,
      loader: "file-loader"
    }]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    })
  ],
  postcss: function() {
    return [autoprefixer({
      browsers: ['last 3 versions']
    })];
  }
};

if (TARGET === 'dev' || !TARGET) {
  module.exports = merge(common, {
    devtool: 'eval-source-map',
    devServer: {
      historyApiFallback: true
    },
    output: {
      publicPath: 'http://localhost:8090/assets'
    },
    plugins: [
      new NpmInstallPlugin({
        save: true // --save
      })
    ]
  });
}

index.jsx

var React = require('react');
var ReactDOM = require('react-dom');

var bootstrap = require('bootstrap');
var bootstrapStyle = require("../../node_modules/bootstrap/dist/css/bootstrap.css");

var datetimepicker = require('eonasdan-bootstrap-datetimepicker');

class DateTimePicker extends React.Component {

  componentDidMount(){
    $('#datetimepicker12').datetimepicker({
              inline: true,
              sideBySide: true
          });
  }

  render() {
    return <div id="wrapper">
                <div className="form-group">
                    <div className="row">
                        <div className="col-md-8">
                            <div id="datetimepicker12"></div>
                        </div>
                    </div>
                </div>
            </div>;
  }
}

ReactDOM.render(
  <DateTimePicker/>, document.getElementById('content'));

package.json

{
  "name": "webpack-bootstrap-datetimepicker",
  "version": "0.0.0",
  "description": "webpack-bootstrap-datetimepicker",
  "main": "index.jsx",
  "scripts": {
    "start": "npm run serve | npm run dev",
    "serve": "./node_modules/.bin/http-server -p 8080",
    "dev": "webpack-dev-server -d --progress --colors --port 8090"
  },
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.5.2",
    "babel-loader": "^6.2.2",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "bootstrap": "^3.3.6",
    "css-loader": "^0.23.1",
    "file-loader": "^0.8.5",
    "html-webpack-plugin": "^2.8.1",
    "http-server": "^0.8.5",
    "jquery": "^2.2.0",
    "less": "^2.6.0",
    "less-loader": "^2.2.2",
    "node-sass": "^3.4.2",
    "npm-install-webpack-plugin": "^2.0.2",
    "postcss": "^5.0.15",
    "postcss-loader": "^0.8.1",
    "react": "^0.14.7",
    "react-dom": "^0.14.7",
    "sass-loader": "^3.1.2",
    "style-loader": "^0.13.0",
    "url-loader": "^0.5.7",
    "webpack": "^1.12.13",
    "webpack-dev-server": "^1.14.1",
    "webpack-merge": "^0.7.3"
  },
  "dependencies": {
    "eonasdan-bootstrap-datetimepicker": "^4.15.35"
  }
}

4条回答
闹够了就滚
2楼-- · 2019-01-27 20:14

Found a simpler solution here: https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1319

The solution:

var path = require('path');

module.exports = {
    resolve: {
        alias: {
            // Force all modules to use the same jquery version.
            'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')
        }
    }
};
查看更多
Explosion°爆炸
3楼-- · 2019-01-27 20:17

you need to check #datetimepicker12 is correct or not it exist to your browser or not.press F12 and press ctrl+F and find id exist. And the other way any error jquery file missing espacially datetime picker js file on your page you get error 404 about that file.put that file at the top all js files hope your problem will be solve

查看更多
Fickle 薄情
4楼-- · 2019-01-27 20:38

Solution is in pull request on Github.

查看更多
够拽才男人
5楼-- · 2019-01-27 20:39

One way of making the changes for $.fn persistent (without editing the source) is to use expose plugin in combination with imports:

module : {
    loaders : [
            {
                test : /jquery/,
                loader : 'expose-loader?$!expose?jQuery'
            },
            {
                test : /eonasdan-bootstrap-datetimepicker/,
                loader : 'imports-loader?define=>false,exports=>false,moment=moment'
            }]
}

What exactly do these arguments for imorts loader do?

When you look at the source, it starts with

'use strict';
if (typeof define === 'function' && define.amd) {
    // AMD is used - Register as an anonymous module.
    define(['jquery', 'moment'], factory);
} else if (typeof exports === 'object') {
    module.exports = factory(require('jquery'), require('moment'));

and then proceeds

} else {
// Neither AMD nor CommonJS used. Use global variables.

This part define=>false,exports=>false prepends a piece of JavaScript that sets both define and exports (inside wrapped module definition) to false, allowing it to proceed to the "use the globals" part, which is exactly what we want. moment=moment tells it to set a variable moment equal to require('moment'), now when the datepicker tries to resolve the libraries from the globals, it reaches to the var moment=... definition. If you plan to include moment from the globals (not as npm dependency), you should omit this argument.

查看更多
登录 后发表回答