Webpack CSS Modules Not Loading New Code - javascript

I'm having a very weird issue where any new CSS files I create and import in my JS code do not get added to the output file. My webpack config is set up to bundle all CSS files required in my React components into one output file called styles.css. Here are the relevant parts of my config:
module.exports = {
...
module: {
rules: [
...
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader?modules=true&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'],
})
},
...
],
},
...
plugins: [
...
new ExtractTextPlugin('css/styles.css'),
...
],
};
This config creates a file called styles.css and puts it in a directory called css in my output directory.
Heres the weird part: It currently generates the hashed class names for all of the files that are imported in my code, but it ignores the class definitions of some files (on a consistent basis).
I was using these versions of the packages:
"css-loader": "^0.28.4",
"postcss-loader": "^2.0.6",
"style-loader": "^0.18.2",
"webpack": "^2.6.1",
I even tried updating all of the packages, but the problem persisted.
I tried running webpack on three different machines, in both production and development mode, and always get the same results.
Any ideas? Am I missing anything here?

I actually found an answer: I was using chunks as separate entry points in my webpack, but was (quite carelessly) rewriting the same CSS file without regard to the different needs of the different entry points. Until now, I had mostly the same CSS rules for all of my entry chunks, which is why I didn't see this before.
D'oh!

Related

Integrating webpack into my WordPress workflow - Separate but related questions

This may be a bit of a long-winded one, but I am looking to use webpack going forward and can definitely see some advantages. However, some of the concepts are a little different to what I have been used to coming from a PHP-based environment and using Gulp.
There are a few things I am trying to get my head around so to help those interested with the post, I have highlighted my questions or what I am looking to achieve.
Background
I am building a boilerplate theme that has the usual WP files.
style.css
functions.php
sass
js
...
Amongst those files I have a directory called gutenberg. In this directory, I have a number of custom blocks (made using the #create-block package and ES5 syntax) that I am looking to package up similar to a React component. Each custom block folder contains:
{blockName}.php
index.js
style.scss
editor.scss
utils-{blockName}.module.js
What I am looking to do is generate a bundle.js file, but create separate files for each block so they can be imported on-demand in an attempt to reduce the initial bundle size. Ideally, this would be separate JS functions and CSS files.
What I have achieved so far
Working through the Webpack documentation I have managed to get a basic implementation going, but everything seems to compile into one and I am looking for a bit more control/chunking, and obviously my current output does not take advantage of Webpack. I can then import the required scripts (hopefully using an Intersection Observer) when a block starts to come into view. However, I'm not even sure this is possible. This is just my mind thinking what might be possible.
My deps are:
"dependencies": {
"#splidejs/splide": "^4.0.6"
},
"devDependencies": {
"#babel/core": "^7.18.2",
"#babel/preset-env": "^7.18.2",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"mini-css-extract-plugin": "^2.6.0",
"sass": "^1.52.2",
"sass-loader": "^13.0.0",
"style-loader": "^3.3.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.9.2"
},
My webpack config currently looks like this:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const entryPoints = {
app: "/js/app.js",
style: "/sass/main.scss",
editorStyle: "/sass/editor-styles.scss",
};
module.exports = {
entry: entryPoints,
devtool: "inline-source-map",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
clean: true,
},
mode: "development",
devtool: "inline-source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"],
},
},
},
{
test: /\.s?[c]ss$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
};
and creates a dist similar or identical to this:
app.css
app.js
editorStyle.css
editorStyle.js
style.css
style.js
Now, the files that I am actually loading in are app.js, for my bundle. editorStyle.css for the styles in the editor, and style.css for the front-end styles. So am I right in saying I don't need app.css, editorStyle.js, and style.js? If so, how can I removed these from the build?
An attempt at code splitting
I did have a go at code splitting and got a result, but wasn't sure how I then use that chunk. I'm very new to ESM and have come from the standard one-long-js-file.js way of doing things
I have two blocks that use the same library, SplideJS. In those blocks utils-{blockName}.module.js I import Splide using the following method:
import Splide from '#splidejs/splide';
import '#splidejs/splide/css/core';
...exported functions...
In my webpack config I included the following:
optimization: {
splitChunks: {
chunks: 'all',
},
},
Which created a chunk file along the lines of vendor_splide-....-...-...{hash}.js. When I have a chunk like this, can I conditionally import it? The naming convention is obviously a standard method, can I have any control over how these chunks are named?
Bundling
One thing I did come across was the size of the bundle once Splide was imported. Jumping from 8kb to around 70kb in development, and over 80kb in production. Splide claims their package is around the 30-40kb size so I wondered was I importing it multiple times. I read that including source maps is expensive and removed devtool: "inline-source-map" from my config but it actually increased the bundle size, only slightly. Is it common for there to be discrepancies in claimed dist sizes of packages, or am I importing the library incorrectly (based on my above import statements)?
Any help with integrating or answering some of my early questions would be greatly appreciated.

ESLint not able to detect certain modules while using `webpack` as `import/resolver`

I'm using Webpack in my project as well as ESLint. I've installed eslint-plugin-import and eslint-import-resolver-webpack to help ESLint understand some resolve.aliases used in the project (As is alluded to here). I'm also using react-hook-form as well as react.
The issue is when I try to import react-hook-form, ESLint tells me it's Unable to resolve path to module 'react-hook-form'. eslint(import/no-unresolved). This doesn't happen with react. Here's a minimum, reproducible example (https://github.com/nishnat-rishi/min-repro).
In my actual project, the problematic node_modules are:
react-hook-form
#headlessui/react
and the working ones are:
#heroicons/react
react
react-dom
react-router-dom
I've already tried:
Adding {... resolve: { modules: ["node_modules"] } ... } in webpack.config.js. Nothing changes with this, same error. I've also tried the following variants:
... modules: [path.resolve(__dirname, "node_modules")]
... modules: [path.resolve(__dirname)]
Adding {... resolve: { mainFields: ["browser", "module", "main"] } ... } in webpack.config.js. Nothing changes with this, same error. I also shifted around the three mainFields entries to no avail.
What am I missing / getting wrong?
EDIT: I needed to use both resolvers in my .eslintrc:
"import/resolver": {
"node": {},
"webpack": {}
}

Json file was not found by webpack

I am developing a small personal project,
i need to import json files with webpack but impossible
package.json contain:
"webpack": "^4.17.1"
"json-loader": "^0.5.7",
webpack.config.js contain
{ test: /\.json$/, use: 'json-loader' },
I dont know what vs code tell me this issue
import * as data from './loading.json';
- Cannot resolve module 'json' -
a question "Load static JSON file in Webpack" do not solve my problem and with json-loader or not this issue still present
As mentioned, you no longer need json-loader for .json since webpack 2.0.0.
However, if you are using json-loader because you don't want to bundle the json file, then I would recommend using one of the following solutions:
Use Copy Webpack Plugin to copy the json file into the build directory.
Use type = 'javascript/auto'
For example(note that this example uses file-loader instead of json-loader):
{
type: 'javascript/auto',
test: /\.json$/,
use: [
{
loader: 'file-loader',
include: [path.resolve(__dirname, 'src')],
options: {
name: '[name].[ext]'
}
}
]
}
Updated: Added include. Remember to place the json file in the src folder.
For more information, please check out this page:
Webpack 4.0 file-loader json issue

Error with webpack 4 and babel 7

I have a project with React and Webpack as build system. My devDependencies
devDependencies
"webpack": "^4.5.0",
webpack.config.js
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
...
And I get this error:
ERROR in ./node_modules/project/components/InfiniteScroller.jsx
Module parse failed: Unexpected token (9:8) You may need an
appropriate loader to handle this file type.
What I am doing wrong?
It looks like you're including uncompiled code from node_modules, your loader specifically excludes compiling node_modules code (exclude: /node_modules/) for efficiency reasons. Usually modules expose a compiled version of the library (usually in /dist, usually pointed to by "main" property in the package.json of the module).
If you want to parse code in node_modules, I recommend you just do it for node_modules/project, rather than all modules for efficiency. Modify your exclude statement accordingly, something like: exclude: /node_modules(?!\/project)/
You'll also need to make sure you use the necessary presets to handle the files (e.g. babel-preset-env, babel-preset-react) and any plugins the file might need (e.g. transform-object-rest-spread etc).
Since I don't have enough points to comment, I'll post as an answer -
I see you're importing a .jsx module - You should try adding
query: {
presets: ['es2015','react']
}
to your rule after use

.eslintignore file not working

I'm using a Vue template project that uses ESLint. I'd like to turn it off, so I followed these instructions and made a file with
**/*.js
called .eslintignore inside of my project root. However, I'm still getting the same eslint error messages. What am I doing wrong?
If you're using the vscode-eslint plugin, the .eslintignore file may need to be placed at the root of the workspace folder, in order to be recognized by the vscode plugin.
For my configuration - I needed to add the "ignorePatterns" property in .eslintrc:
"ignorePatterns": "**/*.d.ts"
You should use **/* instead of **/*.js as the first will ignore both .js and .vue files.
Alternatively you can comment this whole block in your build/webpack.base.conf.js
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: "pre",
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
}
I love ESLint but sometimes you want it to completely ignore a whole file. Add this to the top of your file:
/* eslint-disable */
It needs to be in /* this kind */ of comment, not // this kind.
And ESLint won't complain about your file any more!

Categories

Resources