Importing .css via JS - webpack test issue?

Hello,

I was wondering how you are supposed to include external library css files via JS in Sage?
I added the library via yarn add ol.

I created a script under /scripts/util and imported it inside home.js where it is needed, then called new Maps();. Seems it’s working without style inclusion, but with it it throws an error.

I was following OpenLayers - Basic project setup using NPM and Vite and when importing it says:

in ./node_modules/ol/ol.css
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| .ol-box {
|   box-sizing: border-box;
|   border-radius: 2px;

Any tips appreciated - perhaps I have to edit webpack config in a way? Or should this be handled already, since I see a test for .css files in it.

The error is telling you what’s wrong:

You may need an appropriate loader to handle this file type.

Loaders are central to how Webpack works, so you might find it useful to read up on them: Loaders | webpack

The error is telling you it can’t load a CSS file because it doesn’t have a loader for CSS files. Sage comes with a loader for CSS files, but it only loads them from particular locations. You can see where that loader is defined here: https://github.com/roots/sage/blob/9a8ca10365fb8ca83a5c2714aa5f3ecbfd322034/resources/assets/build/webpack.config.js#L61-L77

As you can see, it will only load CSS files that are found in the path(s) defined in config.paths.assets. That value is defined here: https://github.com/roots/sage/blob/9a8ca10365fb8ca83a5c2714aa5f3ecbfd322034/resources/assets/build/config.js#L21

By modifying the paths it checks to include the path where your file is located, you should be able to resolve this error.

1 Like

Thanks @alwaysblank, that sure helped. Never really took time to read much about Webpack to be honest.

Was able to solve it by adding additional asset variable to build/config.js (should I be able to use an array for assets, since it did not work?:

paths: {
    root: rootPath,
    assets: path.join(rootPath, 'resources/assets'),            // <-- should be able to work as an array here but it doesn't? 
    assets_node_modules: path.join(rootPath, 'node_modules'), // <-- added this instead
    dist: path.join(rootPath, 'dist'),
  },

and within build/webpack.config.js:

{
        test: /\.css$/,
        include: [config.paths.assets, config.paths.assets_node_modules], // <-- used newly created path here

Will just add another solution as a reference: you can also import CSS for any lib separately in a relevant scss. No need to include everything via JS if you want to separate css/js clearly. An example for Magnific Popup lib:

  1. Adding external library: in your theme root yarn add magnific-popup

  2. In your relevant stylesheet scss below @import "./autoload/**/*";:
    @import "~magnific-popup/dist/magnific-popup.css";

  3. In your relevant script file on top:
    import 'magnific-popup/dist/jquery.magnific-popup.js';

@trainoasis @alwaysblank I am still a beginner with Sage and I need to add css files from an external repository that reside outside the assets folder.
I have placed them inside app/customizer/maddisondesigns/customizer-custom-controls. The reason for doing this instead of placing js and css files inside the assets directory is that now I am able to update changes to customizer-custom-controls by just doing a git pull., and also some relative paths are hardcoded inside the css files, which I would need to fix if I modify the file structure. Maybe there is a better option for doing this, but I don’t really know.
I have followed your suggestion, but I can’t make it work:

In config.js I have added a new path:

paths: {
root: rootPath,
assets: path.join(rootPath, 'resources/assets'),
customizer_custom_controls: path.join(rootPath, 'app/customizer/maddisondesigns/customizer-custom-controls/css'),
dist: path.join(rootPath, 'dist'),

},

In my build/webpack.config.json I addded:

{
    test: /\.css$/,
    include: [config.paths.assets, config.paths.customizer_custom_controls],
    use: ExtractTextPlugin.extract({
      fallback: 'style',
      use: [
        { loader: 'cache' },
        { loader: 'css', options: { sourceMap: config.enabled.sourceMaps } },
        {
          loader: 'postcss', options: {
            config: { path: __dirname, ctx: config },
            sourceMap: config.enabled.sourceMaps,
          },
        },
      ],
    }),
  },

I am getting the same error:

    ERROR  Failed to compile with 2 errors                                                                                                                                                           3:11:32 PM

error  in ./app/customizer/maddisondesigns/customizer-custom-controls/css/customizer.css

Module build failed (from /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/cache-loader/dist/cjs.js):
ModuleParseError: Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
  (Source code omitted for this binary file)
at handleParseError (/Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/webpack/lib/NormalModule.js:469:19)
at /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/webpack/lib/NormalModule.js:503:5
at /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/webpack/lib/NormalModule.js:358:12
at /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/loader-runner/lib/LoaderRunner.js:373:3
at iterateNormalLoaders (/Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
at /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/loader-runner/lib/LoaderRunner.js:205:4
at /Users/Santos/GoogleDrive/Sites/roots/web/app/themes/restaurant/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:85:15
at processTicksAndRejections (internal/process/task_queues.js:79:11)

Am I missing something?

Thanks for the help