babel-plugin-react-css-modules
babel-plugin-react-css-modules copied to clipboard
This plugin should not take over webpack's native module resolve
one of my webpack property looks like this
resolve: {
modulesDirectories: [
"app",
"app/test",
"app/component",
"app/css"
"app/css/custom"
]
},
I set up webpack config like that, so I can do this
import React from 'react'
import 'normalize.scss' // locates app/css folder
import 'flexboxgrid.scss' // locates app/css folder
import 'ui.scss' // locates app/css/custom folder
export default class Page extends React.Component {
render() {
return (
<div className="page">
{React.cloneElement(this.props.children, {...this.props})}
</div>
)
}
}
It was perfect for my need. Until I installed babel-plugin-react-css-modules to my project.
Now When I do this
import React from 'react'
import a from 'normalize.scss' // locates app/css folder
import b from 'flexboxgrid.scss' // locates app/css folder
import d from 'ui.scss' // locates app/css/custom folder
export default class Page extends React.Component {
render() {
return (
<div className="page">
{React.cloneElement(this.props.children, {...this.props})}
</div>
)
}
}
I got a bunch of errors like below
./app/component/Page.js
Module build failed: Error: /Users/craigcosmo/Desktop/clean 2/app/component/Page.js: ENOENT: no such file or directory, open '/Users/craigcosmo/Desktop/clean 2/app/component/normalize.scss'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at fs.readFileSync (fs.js:508:33)
at getTokens (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-plugin-react-css-modules/src/requireCssModule.js:34:14)
at exports.default (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-plugin-react-css-modules/src/requireCssModule.js:77:10)
at PluginPass.ImportDeclaration (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-plugin-react-css-modules/src/index.js:86:71)
at newFn (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/visitors.js:276:21)
at NodePath._call (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitMultiple (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:103:17)
at TraversalContext.visit (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:190:19)
at Function.traverse.node (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/index.js:114:17)
at NodePath.visit (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/path/context.js:115:19)
at TraversalContext.visitQueue (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/index.js:114:17)
at traverse (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-traverse/lib/index.js:79:12)
at File.transform (/Users/craigcosmo/Desktop/clean 2/node_modules/babel-core/lib/transformation/file/index.js:558:35)
at /Users/craigcosmo/Desktop/clean 2/node_modules/babel-core/lib/transformation/pipeline.js:50:19
@ ./app/component/MainContainer.js 15:12-27
As you can see now, webpack doesn't know where my modules are.
Can you please fork the demo and reproduce the issue?
https://github.com/gajus/babel-plugin-react-css-modules/tree/master/demo
This plugin does not rewrite the imports and it is not aware of webpack at all. Something else is breaking.
I am closing this until there is a fork reproducing the issue.
I can't get the demo to work. Can you check out the error below?
This issue appears to be caused by this line. Specifically, require.resolve(path.node.source.value) results in a call such as require.resolve('home.css'), which has no knowledge of webpack.
I'm not sure this can be fixed by the plugin unless there's a new configuration option.
You should be able to set NODE_PATH to fix this, but I'm not sure how robust of a solution it is: NODE_PATH=src:src/components:src/sass webpack-dev-server (or, if I recall correctly, NODE_PATH=src;src/components;src/sass webpack-dev-server on Windows).
I'm not sure this can be fixed by the plugin unless there's a new configuration option.
It can. It should simply lookup the resolve.modulesDirectories configuration and respect it when attempting to resolve the paths.
Is it possible for a Babel plugin to read the webpack config without the user explicitly passing it in?
Oh, sorry – I got lost between projects. I thought I am looking at an issue of https://github.com/gajus/isomorphic-webpack. Please ignore me.
No problem. 😹 On the bright side, that project looks like exactly what I was looking for.
There is this babel plugin which mimics that resolve feature of webpack.
https://github.com/tleunen/babel-plugin-module-resolver
If this css modules can take advantage of that, it could be a solution.
@gajus,
First of all thanks for an amazing plugin.
We have decided to use this plugin in our app but this issue is a blocker for us. We defined some aliases in our webpack configuration and it doesn't respect them and throws error as shown below.
I tried using babel-plugin-module-resolver as suggested by @craigcosmo but that also didn't work.
Let me know if you need any further information from our end.
Error :
ERROR in ./src/app/containers/Header/UserProfileModal/UserProfileModal.js Module build failed: Error: /home/bhavya/Documents/applications/src/app/containers/Header/UserProfileModal/UserProfileModal.js: Cannot find module 'components/Row/Row.scss' at Function.Module._resolveFilename (module.js:469:15) at Function.resolve (internal/module.js:27:19) at getTargetResourcePath (/home/bhavya/Documents/applications/node_modules/babel-plugin-react-css-modules/dist/index.js:105:20) at notForPlugin (/home/bhavya/Documents/applications/node_modules/babel-plugin-react-css-modules/dist/index.js:117:31) at PluginPass.ImportDeclaration (/home/bhavya/Documents/applications/node_modules/babel-plugin-react-css-modules/dist/index.js:128:13) at newFn (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/visitors.js:276:21) at NodePath._call (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/path/context.js:76:18) at NodePath.call (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/path/context.js:48:17) at NodePath.visit (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/path/context.js:105:12) at TraversalContext.visitQueue (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:150:16) at TraversalContext.visitMultiple (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:103:17) at TraversalContext.visit (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:190:19) at Function.traverse.node (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/index.js:114:17) at NodePath.visit (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/path/context.js:115:19) at TraversalContext.visitQueue (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:150:16) at TraversalContext.visitSingle (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:108:19) at TraversalContext.visit (/home/bhavya/Documents/applications/node_modules/babel-traverse/lib/context.js:192:19) @ ./src/app/containers/Header/UserProfileModal/index.js 8:24-53 @ ./src/app/containers/Header/HeaderSection.js @ ./src/app/containers/Header/index.js @ ./src/app/reducer.js @ ./src/app/store/configureStore.development.js @ ./src/app/store/configureStore.js @ ./src/app/index.js @ ./src/development.js @ multi webpack-hot-middleware/client react-hot-loader/patch development
Webpack Resolve configuration :
resolve: {
modules: [
//path.join(__dirname, "../src/client/assets"),
path.join(__dirname, "../src"),
"node_modules"
],
mainFiles: ["index"], // for resolving directories mentioned in import paths to index.js files
alias: {
components: path.resolve(__dirname, "../src/app/components"),
containers: path.resolve(__dirname, "../src/app/containers"),
sass: path.resolve(__dirname, "../src/sass"),
assets: path.resolve(__dirname, "../src/assets"),
utils: path.resolve(__dirname, "../src/app/utils"),
constants: path.resolve(__dirname, "../src/app/constants"),
pace: "pace-progress"
},
extensions: [".js", ".jsx", ".json", ".scss", ".css"]
},
babelrc configuration :
{
"presets": ["es2015", "react", "stage-2"],
"plugins": [
"transform-runtime",
"react-hot-loader/babel",
["react-css-modules", {
"generateScopedName": "[name]__[local]___[hash:base64:5]",
"filetypes": {
".scss": {
"syntax": "postcss-scss"
}
},
"exclude": "/node_modules/",
"webpackHotModuleReloading": true
}]
],
"env": {
"production": {
"plugins": [
"transform-react-remove-prop-types",
"transform-react-constant-elements"
]
}
}
}
Well, if you import inside CSS and not in JS, you will get Webpack aliases working as css-loader etc is already in webpack scope. So feel free to use ICSS imports or SCSS imports inside your SCSS as needed.
We are using less so for us it is as simple as @import (reference) "~settings/colors.less"; inside my Page.less which is imported to Page.jsx as the only less file.
Yes I am aware it could be done more ICSS way for less code transferred, but we are OK with that for now.
Bump. Blocker for me too.
Does anybody have any workaround for this? I'm okay with even most uglier ones.
I ran into a similar issue on Windows (only in some situations) and just used yarn with success
Ran into similar issue (import '@/styles/index.pcss'; with configured webpack's resolve.alias didn't work, though import './styles/index.pcss did). I've fixed it by adding babel-plugin-module-resolver. Here's my config.
My webpack config is in ./directory, and all CSS modules are in ./client directory.
./.babelrc
{
"plugins": [
["module-resolver", {
"alias": {
"@": "./client",
}
}],
["react-css-modules", {
"webpackHotModuleReloading": true,
"filetypes": {
".pcss": {
"syntax": ""
}
}
}]
]
}
./webpack.config.js
module.exports = {
// ...
resolve: {
alias: {
'@': path.resolve(__dirname, 'client'),
},
},
}
Now I can use aliased CSS imports in my ./client directory:
./client/index.tsx
import '@/styles/index.pcss'; // is properly imported as ./client/styles/index.pcss