Search code examples
javascriptjquery-uiwebpackloaderwebpacker

Webpack | jQuery UI => relative image urls for icon set are not being loaded


This error :

ERROR in ./app/javascript/packs/admin.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve './images/ui-icons_444444_256x240.png' in '/Users/trip/Sites/the_website/app/javascript/packs'

Stems from this code snippet within jQuery UI

.ui-icon,
.ui-widget-content .ui-icon {
    background-image: url("images/ui-icons_444444_256x240.png");
}

Now this can be solved, by me manually copying and moving a copy of these files to the entrypoint of my webpack. The issue I believe is that Webpacker is not telling the CSS file where the public_output_path is

My Webpack Config :

    rules: [{
      test: /\.(css|less|scss|sass)$/i,
      include: /node_modules/,      
      exclude: [
        /\.module\.(css|less)$/,
        /\.(config|variables|overrides)$/ 
      ],
      use: [
        MiniCssExtractPlugin.loader,
        {loader: 'css-loader'},
        {loader: 'postcss-loader'},
        {loader: 'resolve-url-loader'},
        {loader: 'less-loader'},
        {loader: 'sass-loader', options: {implementation: require('sass')}},
      ],
    },
...
    {
      test: /\.(jpg|jpeg|png|gif)$/i,
      use: [{
        loader:  'file-loader',
        options: {
          name: isProduction ? '[name]-[hash].[ext]' : '[name].[ext]'
        },
      }],
    }, {
...
  resolve: {
    alias: {
      'jquery-ui'   : 'jquery-ui-dist/jquery-ui',

And then it is called here from Admin.scss :

@import 'jquery-ui/themes/base/all.css';

Would anyone have any idea what I am possibly doing wrong here? Anything to perhaps look into? All comments/questions/haikus welcome :)


Solution

  • Since this question doesn't have an answer, and I basically had the same problem, I'll share what worked for me when using Webpack 5 and jquery-ui 1.12.1.

    In my case, a jquery-ui dialog was popping up, but the close icon in the top-right was missing, the button icons were missing, and the buttons were not styled.

    I had some jquery-ui imports in my root webpack entry named base.js:

    import "jquery-ui/ui/widgets/autocomplete"; // !! [1]
    import "jquery-ui/ui/widgets/sortable"; // !! [1]
    import "jquery-ui/ui/effects/effect-highlight"; // !! [1]
    

    jquery-ui version 1.12.1 doesn't come with a /dist/ folder and I needed this specific version because of another script. Long story short.

    Since I needed dialog, I added to base.js:

    ... stuff above +
    import "jquery-ui/ui/widgets/dialog";
    

    This did not work in my case because I was instantiating the jquery-ui dialog on a button click event:

    mydialog.js

      trackNotesButton.addEventListener("click", showNotesDialog);
    
      function showNotesDialog(e) {
        ...
        $(dialog).dialog({
          title: "Notes",
          closeOnEscape: false,
          ...
    

    dialog example

    The Solution (for me)

    I removed the import from base.js entry and imported the jquery-ui dialog widget in the file where $(dialog).dialog(...) occurred.

    mydialog.js

    import "jquery-ui/ui/widgets/dialog"; // <-- this was the key!
    
    trackNotesButton.addEventListener("click", showNotesDialog);
    
    function showNotesDialog(e) {
      ...
      $(dialog).dialog({
        title: "Notes",
        closeOnEscape: false,
        ...
    

    This may sound super-obvious to most, but I thought importing the dialog into the root entry point would have been enough. Maybe it is necessary for events that don't fire immediately.

    dialog with icons