Source of a style tag inserted by style-loader from Webpack? - css

I'm using the css-loader and style-loader with Webpack. As expected, style tags get added to the head of the document, but there doesn't seem to be any way to determine which import led to a given style tag. My understanding is that the css-loader is responsible for reading the actual css files from the import, so it seems like something that should be configured with that loader. I can't find anything that would make that possible based on these docs though: https://webpack.js.org/loaders/css-loader/

I imagine there's existing plugins and loaders to handle the need I mentioned, but I couldn't find any. I was able to get this custom loader working:
In projectRoot/web_loaders/css-module-path-includer.js:
module.exports = function (content) {
return [
`/* resource: ${this.resource} */`,
content
].join('\n')
}
Updates to webpack.config.js:
module.exports = {
...
resolveLoader: {
modules: [ 'node_modules', path.resolve(__dirname, "./web_loaders") ],
},
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
'css-module-path-includer'
],
}
]
}
which gives you:
and then you can use something like this to track down which module in your source ultimately led to the import:
run
npx webpack --profile --json > stats.json
there was output before and after the actual json in the output that I had to edit. There's probably an argument that results in just the json being printed.
in find_dependency_root.py
import json
import sys
stats = json.loads(open('stats.json').read())
dependency = sys.argv[1]
visited = {}
dependency_chain = [dependency]
while True:
module = next(module for module in stats['modules']
if dependency in str(module['id']))
# try to account for circular dependencies
if module['issuerId'] != 0 and dependency not in visited:
visited[dependency] = True
dependency = module['issuerId']
dependency_chain.insert(0, dependency)
else:
print('\n'.join(dependency_chain))
break
python3 find_dependency_root.py antd/lib/popover/style/index.css
./src/main/resources/static/js/Root.tsx
...
./node_modules/antd/lib/popconfirm/style/css.js
./node_modules/antd/lib/popover/style/css.js
antd/lib/popover/style/index.css

Related

Next JS Babel can't resolve 'module'

I've started to develop a multi-language web application with Next JS and Lingui.js
Lingui.js is using babel so I had to install it aswell.
I've followed this tutorial https://blog.logrocket.com/complete-guide-internationalization-nextjs/
After facing some issues i've also followed the official documentation of Lingui.js https://lingui.js.org/tutorials/setup-react.html
I faced a lot of issues with babel and typescript.
But now I struggle with following error, which I could not find any help with:
wait - compiling / (client and server)...
error - ./node_modules/resolve-from/index.js:3:0
Module not found: Can't resolve 'module'
Import trace for requested module:
./node_modules/import-fresh/index.js
./node_modules/cosmiconfig/dist/loaders.js
./node_modules/cosmiconfig/dist/index.js
./node_modules/babel-plugin-macros/dist/index.js
./node_modules/#lingui/macro/index.js
./src/pages/index.tsx
https://nextjs.org/docs/messages/module-not-found
false
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at Home (webpack-internal:///./src/pages/index.tsx:36:51)
at I18nProvider (C:\Project\app\node_modules\#lingui\react\cjs\react.development.js:46:19)
at MyApp (webpack-internal:///./src/pages/_app.tsx:48:24)
at StyleRegistry (C:\Project\app\node_modules\styled-jsx\dist\index\index.js:671:34)
at AppContainer (C:\Project\app\node_modules\next\dist\server\render.js:394:29)
at AppContainerWithIsomorphicFiberStructure (C:\Project\app\node_modules\next\dist\server\render.js:424:57)
at div
at Body (C:\Project\app\node_modules\next\dist\server\render.js:701:21)
error - Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in,
or you might have mixed up default and named imports.
here is my babel.config.js
module.exports = {
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript"
],
plugins: [
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
],
[
"#babel/plugin-transform-react-jsx",
{
"runtime": "automatic"
}
],
[
'#babel/plugin-transform-runtime',
{
absoluteRuntime: false,
corejs: false,
helpers: true,
regenerator: true,
version: '7.0.0-beta.0',
},
'react-native-reanimated/plugin',
],
]
}
and my webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: ['babel-loader', 'ts-loader']
}
]
}
};
The part with React.jsx: type is invalid is because of getStaticProps in index.tsx.
So this might be an separate issue
Have you already tried the solution mentioned here ?
webpack.config.js
node: {
module: "empty",
}
I ended up deleting everything I had from Babel and lingui and copied all imports from another project which was running.
Cannot name the difference between them, but it worked afterwards.

Rails (6.0.3.4) Webpacker (5.2.1) package import error: `Can't import the named export from non EcmaScript module`

I'm trying to import a package into my Rails 6 project – I'm on Rails 6.0.3.4 and webpacker 5.2.1 gem.
The package is installed yarn add #shopify/react-form
It's imported into the file import {useForm, useField} from '#shopify/react-form';
Now after running ./bin/webpack-dev-server
I get this:
ERROR in ./node_modules/#shopify/react-form/build/esm/validation/validator.mjs 35:25-32
Can't import the named export 'isEmpty' from non EcmaScript module (only default export is available)
And few more of the same error but different file names.
I read on another issue that adding a new rule to webpack would fix the issue, so I followed the instructions on the webpacker README:
The thing is I don't have /config/webpack/base.js, I created on anyway and created a rules directory in side the /config/webpack/ directory, so my base.js looks like this:
// /config/webpack/base.js
const { webpackConfig, merge } = require('#rails/webpacker')
const fixConfig = require('./rules/fix')
module.exports = merge(webpackConfig, fixConfig)
and the fix looks like this:
// /config/webpack/rules/fix.js
module.exports = {
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
}
]
}
}
I need help/guidance to figure out hot to solve this. TIA!
I managed to fix the error, this article guided me to figure out how to merge a new rule into webpack config.
Here is what environment.js looks right now:
// /config/webpack/environment.js
const { environment } = require('#rails/webpacker')
environment.config.merge({
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
}
]
}
})
module.exports = environment
Before it was:
const { environment } = require('#rails/webpacker')
module.exports = environment
I ended up deleting base.js and fix.js.

CSS loader error with webpack v3 after editing a webpack watched file in a server-side app

I am working on a node express api which is building a view via react and CSS modules (one CSS file within each component imported directly into the component). The react output is serialised with renderToStaticMarkup() which will be sent back to the requester in the JSON response. I also intend to send the compiled CSS in this response too.
I have a working build process via webpack which bundles my server app to one file. I am also currently bundling my CSS (modules) into one file (with the intention of reading this in later).
I am using webpack with its watch facility as follows (can't use webpack-dev-server as the api requires POST and there is no 'page' to update anyway):
cross-env NODE_ENV=development webpack -w --colors
My issue however is that whilst this all works fine on first compile, as soon as I change any file, I get a webpack error stating that I need an appropriate loader for the imported CSS file.
ERROR in ./src/app/components/Suggestions/Suggestions.css
Module parse failed: /home/me/myproject/src/app/components/Suggestions/Suggestions.css Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| .suggestions {
| background: blue;
| color: orange;
# ./src/app/components/Suggestions/Suggestions.js 11:19-47
# ./src/app/components/Suggestions/index.js
# ./src/server/middleware/buildSuggestions.js
# ./src/server/routes/index.js
# ./src/server/server.js
# multi babel-polyfill ./src/server/server.js
I have simplified my webpack config as much as possible and still get the issue. My simplified config (not extracting css to file and no PostCSS) is as follows:
webpack.config.babel.js
import path from 'path';
import nodeExternals from 'webpack-node-externals';
import PATHS from './config/paths';
// Host and port settings to spawn the dev server on
const HOST = 'localhost';
const PORT = 3000;
const LOCAL = `http://${HOST}:${PORT}`;
const DEV = process.env.NODE_ENV === 'development';
let serverConfig = {
entry: [
"babel-polyfill",
path.resolve(PATHS.src, 'server/server.js'),
],
output: {
filename: 'server.js',
path: PATHS.dist,
publicPath: '/'
},
module: {
rules: [
{
test: /\.jsx?$/,
include: PATHS.src,
use: {
loader: 'babel-loader',
options: {
// babelrc at project root only for compiling this webpack
babelrc: false,
presets: [
'env',
'react'
],
plugins: [
'transform-object-rest-spread',
'syntax-dynamic-import',
'transform-class-properties',
]
}
}
},
{
test: /\.css$/,
use: [
{
loader : 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[local]-[hash:base64]',
sourceMap: DEV
},
}
]
}
],
},
plugins: [
],
target: 'node',
externals: [nodeExternals()]
};
export default serverConfig;
So my question is, why does this work okay on first compile but not on a recompile after a change?
Stranger than fiction!
So I realised that if I run my build without the watcher...
cross-env NODE_ENV=development webpack --colors
and that process had ended, if I edited a file I still saw the error!!! Even though there was supposedly no watcher running. I left that terminal window alone with no running process, opened another terminal and edited a file within my src directory using vi (closed WebStorm in case it had some odd watcher running). Incredibly, the error popped up again in the original terminal window!!!
So it seems my issue was caused by a rogue webpack watch process that hadn't been killed properly. Couldn't find the process to manually kill it so had to do reboot. Literally hours lost on this bizzare issue. At least my whole build process is working again.

“You may need an appropriate loader to handle this file type” with Webpack and CSS

I an new to webpack, and I have been able to get it to packup my javascript, but the CSS eludes me. I keep getting a:
“You may need an appropriate loader to handle this file type”
One the first line of my css file. The CSS file is simple:
body {
color:red
}
The webpack.config.js looks like this:
module.exports = {
debug: true,
entry: [ './sdocs.js' ],
output: {
filename: './[name].bundle.js'
},
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
],
}
sdocs.js is also simple and looks like this:
require('./sdocs.css');
Finally the result of running webpack look like this:
ERROR in ./sdocs.css
Module parse failed: C:\Users\Tim\PhpstormProjects\xxx\sdocs.css
Unexpected token (1:5)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (1:5)
at Parser.pp.raise (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:923:13)
at Parser.pp.unexpected (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1490:8)
at Parser.pp.semicolon (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1469:73)
at Parser.pp.parseExpressionStatement (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1994:8)
at Parser.pp.parseStatement (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1772:188)
at Parser.pp.parseTopLevel (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1666:21)
at Parser.parse (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:1632:17)
at Object.parse (C:\Users\Tim\PhpstormProjects\xxx\node_modules\acorn\dist\acorn.js:885:44)
at Parser.parse (C:\Users\Tim\PhpstormProjects\xxx\node_modules\webpack\lib\Parser.js:902:15)
at DependenciesBlock.<anonymous> (C:\Users\Tim\PhpstormProjects\xxx\node_modules\webpack\lib\NormalModule.js:104:16)
at DependenciesBlock.onModuleBuild (C:\Users\Tim\PhpstormProjects\xxx\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)
at nextLoader (C:\Users\Tim\PhpstormProjects\xxx\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)
at C:\Users\Tim\PhpstormProjects\xxx\node_modules\webpack-core\lib\NormalModuleMixin.js:259:5
at Storage.finished (C:\Users\Tim\PhpstormProjects\xxx\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:38:16)
at C:\Users\Tim\PhpstormProjects\xxx\node_modules\graceful-fs\graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:439:3) # ./sdocs.js 1:0-22
I have triple checked, css-loader and style-loader are loaded at the local level. I had them installed globally at first, but i removed them globally and reinstalled them locally. BTW, the debug flag did nothing extra, no change in output, which i thought was weird.
I am running on a windows platform is that matters
Ok,
This is what fixed it for me if anyone runs across this. The issue was in the webpack.config.js. The one the finally worked looked like this:
module.exports = {
debug: true,
entry: [ './sdocs.js' ],
output: {
filename: './[name].bundle.js'
},
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
],
}
}
The piece that was missing was moving the loaders key under a modules key.
I tried specifying 'loaders' in 'module' key. But, it didn't work for me. I think for webpack versions above 2.5.1, adding a rule in 'module' works perfectly.
Add this in your webpack.config.js
module: {
rules:[
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
]
}
When you add it as a rule you wouldn't have to provide tha loaders key separately!
I was facing this problem for about 10 days. so here's the solution i found to fix this problem. After using create-react-app you created a react app, first run the script npm run eject.
Then, go to the following link https://webpack.js.org/loaders/, click on the val-loader and install it as described there, then install the url-loader file.
It has to work now.
I had met the same issue you meet. Maybe you were in dev environment (hot reload), just press ctrl+c to kill the process on terminal, and reopen dev env (npm run dev).

How to import lesshat into every compiled .less file

In grunt-contrib-stylus there is a import option:
import
Type: Array
Import given stylus packages into every compiled .styl file, as if you wrote '#import '...' in every single one of said files.
options: {
compress: false,
use: [ require('kouto-swiss') ],
import: [ 'kouto-swiss' ]
},
How can I do the same thing with lesshat in grunt-contrib-less ?
Thanks
Since release 2 you can create plugins for Less easily. Thanks to Implementing preprocessing plugins you can create preprocess plugins too.
The preprocess plugin enable you to inject Less code before processing:
LesshatProcessor.prototype = {
process : function (src, extra) {
var injected = '#import "' + path.resolve(__dirname, '../') + '/node_modules/lesshat/build/lesshat.less";\n';
var ignored = extra.imports.contentsIgnoredChars;
var fileInfo = extra.fileInfo;
ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
ignored[fileInfo.filename] += injected.length;
return injected + src;
}
};
I have created a Lesshat plugin already: https://github.com/bassjobsen/less-plugin-lesshat. After installing this plugin by running npm install less-plugin-lesshat and then your are able to run: lessc file.less --lesshat.
You can also use this plugin together with grunt-contrib-less:
grunt.initConfig({
less: {
options: {
plugins: [
new (require('less-plugin-lesshat'))()
]
},
files: {'css/test.css' : 'less/test.less'}
}
)};
Notice that you should install the latest version of Less with grunt-contrib-less until Less has updated the version number (and grunt-contrib-less uses that version).
To use the plugin now:
run npm install grunt-contrib-less
Navigate to node_modules/grunt-contrib-less/
Remove node_modules/less
Download and unzip the latest version of Less at https://github.com/less/less.js/archive/master.zip
run npm install ./less.js

Resources