$(…).modal is not a function(…) error using webpac

2019-07-27 05:34发布

问题:

I'm having an issue opening modals with the $('#modal-id').modal('show') function. After narrowing down the issues, I believe this has something to do with webpack loading my dependencies or specifically with the jQuery dependency.

Here are the necessary pieces of my webpack configuration:

entry: {
    'js/bootstrap.bundle': 'bootstrap-loader',
    'js/common.bundle': [
        path.join(PROJECT_ROOT, 'resources/assets/js/common/app.js'),
        path.join(PROJECT_ROOT, 'resources/assets/js/common/table.js')
    ],
    ...
},

...

plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery"
    })
],

So the idea is that all of the files loaded with bootstrap should be going into one file js/bootstrap.bundle.js and the jQuery dependency should be loaded into each bundle that needs it.

Other than the modal function, bootstrap-loader is completely working as it should with all styles as well as the $ and jQuery variables.

Here is my .bootstraprc file:

useFlexbox: true
bootstrapVersion: 3

preBootstrapCustomizations: ./resources/assets/scss/partials/_variables.scss
bootstrapCustomizations: ./resources/assets/scss/app.scss

styleLoaders:
  - style
  - css
  - sass

styles:
  mixins: true

  normalize: true
  print: true
  glyphicons: true

  scaffolding: true
  type: true
  code: true
  grid: true
  tables: true
  forms: true
  buttons: true

  component-animations: true
  dropdowns: true
  button-groups: true
  input-groups: true
  navs: true
  navbar: true
  breadcrumbs: true
  pagination: true
  pager: true
  labels: true
  badges: true
  jumbotron: true
  thumbnails: true
  alerts: true
  progress-bars: true
  media: true
  list-group: true
  panels: true
  wells: true
  responsive-embed: true
  close: true

  modals: true
  tooltip: true
  popovers: true
  carousel: true

  utilities: true
  responsive-utilities: true

scripts:
  transition: true
  alert: true
  button: true
  carousel: true
  collapse: true
  dropdown: true
  modal: true   // MODAL SCRIPT IS LOADED
  tooltip: true
  popover: true
  scrollspy: true
  tab: true
  affix: true

How I'm using the bundled files:

<script type="text/javascript" src="{{ asset('js/bootstrap.bundle.js') }}" charset="utf-8"></script>
<script type="text/javascript" src="{{ asset('js/common.bundle.js') }}" charset="utf-8"></script>

I'm loading pretty much everything that comes with bootstrap and the modal scripts are loaded in the bundle. But I'm at a loss for why this cannot find the modal function. Thanks in advance.

回答1:

I found a solution using the following configuration:

(js/vendor replaces js/bootstrap.bundle in the earlier example)

entry: {
    'js/vendor': 'bootstrap-loader',
    ...
},

...

plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery",
    }),
    new webpack.optimize.CommonsChunkPlugin(
        "js/vendor",
        "js/vendor.bundle.js"
    )
],

Now instead of bundling bootstrap to file js/bootstrap.bundle.js, I can list out my vendor plugins and have them all bundled into js/vendor.bundle.js, which will be shared between the other entries based on the documentation for CommonsChunkPlugin.

With that in mind, I am now able to use the modal function from a different bundle.