Webpack won't load relative images from node module css - javascript

I'm trying to import css (and through that, a relative image path) from a node module.
Adding the npm package works fine,
yarn add #claviska/jquery-minicolors
Importing the css works fine,
#import '~#claviska/jquery-minicolors/jquery.minicolors';
But then when I view my site, I get the following webpack error,
Module not found: Error: Can't resolve './jquery.minicolors.png'
This is the offending image path from the css:
.minicolors-sprite {
background-image: url(jquery.minicolors.png);
}
The css, image, and js files are all in the same npm folder:
node_modules/#claviska/jquery-minicolors/jquery.minicolors.css
node_modules/#claviska/jquery-minicolors/jquery.minicolors.png
node_modules/#claviska/jquery-minicolors/jquery.minicolors.js
If I copy that image from /node_modules and paste it into my webpack /css folder then everything works!
How can I teach webpack to load relative image paths from css included in my node_module packages?

Found a reasonable solution to this though there are probably better ones.
Moved my css import from my main scss file src/application.scss
#import '~#claviska/jquery-minicolors/jquery.minicolors';
to my main js file packs/application.js
// Import js
import '#claviska/jquery-minicolors';
// Import css
import '#claviska/jquery-minicolors/jquery.minicolors.css';
It's possible that the js and css imports need to be in the same document in order for webpack to discover the problematic relative image path url(jquery.minicolors.png).
Would love to hear other suggestions.

Related

loading all css files from 'assets' directory in NUXT

I'd like to load a couple of css files from the assets folder in my nuxt project.
currently I'm loading files individually via nuxt.config.js
export default {
head: {
css: [
'~/assets/css/fonts.css'
],
}
}
which works perfectly fine for a single file. is there any way to import all files at once that are in the /assets/css folder?
I suggest you an alternative way that you can import your css or scss files by sass.
Create a folder in your assets called scss : /assets/scss/.
Install import-glob-loader by running this command:
npm install import-glob-loader --save-dev
Create a file in assets/scss/ path call it main.scss.
Open main.scss and add this code on it:
#import "imports/**/*";
Create a folder in assets/scss/ call it imports/ that involves all your css codes.
create your css files in this assets/scss/imports path.
Go to nuxt.config.js and add this code in that file:
css: ['#/assets/scss/main.scss'],

CSS not added to /dist folder using Webpack 4 and MiniCssExtractPlugin

Issue
Would any Webpack config experts out there be able to tell me why I can't extract my css into the dist folder when running npm run build?
Repo is here: https://github.com/damodog/webpack4-boilerplate
Further info
To summarise, I've been working through the Webpack Guide docs and everything was going well. js and css was getting injected into my index.html file via <link> and <script> tags respectively. I've installed various loaders, plugins etc and split my configs out into common (shared), dev and prod files (as per the docs) and life was good.
I happened to make some tweaks which included looking at code splitting dynamic imports, adding aliases for paths, moving js into js folder etc and noticed when I ran a build npm run build all of a sudden my css wasn't getting added to the dist folder. I reverted my trial changes for the dynamic import stuff and tried reverting the other changes but am still getting the same issue. Annoyingly I hadn't added git at this point so didn't have a clear picture of the 'tweaks' I'd made to locate what I'd changed.
What happens
When I run my watch task npm start the styles.scss file (imported into the main index.js file) get's compiled into css and the resulting app.css file gets injected into the index.html page when viewed in my local host. All gravy.
<link href="css/app.css" rel="stylesheet">
When I run npm run build the css file should get copied over dist folder, a hash id should get added and the css should be minified. This was working (like I said above) and I could see the css file in the build steps (see first Asset below. Btw disregard the difference in js bundled files here compared to the next screenshot. This was when I was playing with code splitting).
Now when I run this the css isn't bundled up (see below).
I think it could be something to do with mini-css-extract-plugin but I've configured this as per the docs using the advanced configuration example (I've split their example out which is in one config file as I have separate config files for dev and prod).
I literally cannot see why this is happening.
Help me SO readers. You're my only help...
I cloned your repo and experimented with it. In your package.json, you've set: sideEffects: false. This causes the imported stylesheets to be lost in the process of tree shaking. This is described in the docs:
A "side effect" is defined as code that performs a special behavior
when imported, other than exposing one or more exports. An example of
this are polyfills, which affect the global scope and usually do not
provide an export.
and
Note that any imported file is subject to tree shaking. This means if
you use something like css-loader in your project and import a CSS
file, it needs to be added to the side effect list so it will not be
unintentionally dropped in production mode
So change your side effects in package.json to "sideEffects: ["./src/scss/styles.scss"] and it will be output to the destination folder when in production mode.

Webpack watch file changes and trigger loader for other files

I'm looking for a way to watch changes on files (sass files precisely) and execute a loader on other files (js files) with webpack.
The goal is to detect sass changes and recompiling all the javascript files with the babel-loader, because they might import it through the styled-jsx plugin.
I'm stuck in the "loader" concept and can't figure out how to get other files when testing for /.scss$/
You don't need to do anything by yourself if you using scss modules with webpack (more about module concept in the webpack docs.
What webpack does - it starts at entry point (you can specify one or multiple entrypoints, if you don't, default src/index.js would be used). And then builds dependency trees between modules (which can have any file extension as long as there's a specific loader that can turn file into module). Webpack then watches all files and rebuild all modules that have a dependency on changed file. So, if you import the .scss file in, let's say, your entrypoint
import './styles.scss';
// ...
It would rebuild automatically when styles.scss changes
You need to import your .scss file(s) under one of your .js files so that webpack actually picks up the changes.
Then, all loaders you have configured will be applied automatically based on which file type they should target.

Webpack loaders in layman terms

Am I correct in understanding that Webpack transforms everything you have into JS code only? So that even if you have CSS, it will be turn into JS (in a bundle) as long as you have the correct loader?
Loaders can transform files from a different language like
CoffeeScript to JavaScript, or inline images as data URLs. Loaders
even allow you to do things like require() css files right in your
JavaScript!”
Loaders won't convert CSS into JavaScript but it will allow you to import CSS files right from your JavaScript file. For e.g. you have components based application architecture and each component has it's own CSS, you can load css right from component's JS file.
Like this (in your app.js)
import styles from './app.css';
OR more generic
import './app.css';
From Official site
Loaders can transform files from a different language (like
TypeScript) to JavaScript, or inline images as data URLs. Loaders even
allow you to do things like import CSS files directly from your
JavaScript modules!
Example
For example, you can use loaders to tell webpack to load a CSS file or
to convert TypeScript to JavaScript. To do this, you would start by
installing the loaders you need:
npm install --save-dev css-loader
npm install --save-dev ts-loader
And then instruct webpack to use the css-loader for every .css file and the ts-loader for all .ts files:

Import less file in package

I've got a preamble.lessimport file with definitions of standard colors, sizes, mixins etc. that I import in all other .less files. So far, the file was placed in /client and I included it with
#import '/client/preamble.lessimport';
Worked as a charm.
Now, I'm moving all styles to a smart package to make them reusable. How do I include the preamble now?
I've tried putting it as preamble.lessimport in the main package dir and then including with both
#import '/preamble.lessimport';
and
#import 'preamble.lessimport';
Both result in the compile error:
While building package `theme`:
input: Less compiler error: '/preamble.lessimport' wasn't found
Placing the file in a subfolder didn't help. The file is added in package.js and I use less package in both client and server.
How can I properly import that file?
Edit:
I've worked around this issue by importing via relative path:
#import '../../../preamble.lessimport';
However I'm not happy with that solution as the package is on early stage and files inside tends to move a lot. Is there any absolute path I could use?
As of meteor 0.7 you no longer use the .lessimport extension. Your less files should have the .import.less extension.
Take a look at how the bootstrap3-less project imports bootstrap for best use examples.

Categories

Resources