How to set a webpack 2 alias for a folder? - reactjs

I have a react project that looks like the following:
app
|_ components
|_ containers
|_ actions
|_ reducers
|_ themes
|_ theme1
|_ index.jsx
|_ theme2
|_ index.jsx
package.json
webpack.config.js
My question is:
Is there any way to set an alias that allows me to call any file inside the themes folder?
I'm using webpack 2 and I found somethings like this:
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes$: path.resolve(__dirname, 'src/themes/')
}
},
I would also like to import these files in the following way:
import * as Themes from 'Themes';
When I run my project, I get the following error:
4:1 error 'Themes' should be listed in the project's dependencies.
Run 'npm i -S Themes' to add it import/no-extraneous-dependencies
4:8 error 'Template' is defined but never used
no-unused-vars 4:23 error Multiple spaces found before ''Themes''
no-multi-spaces 4:23 error Absolute imports should come before
relative imports import/first
4:23 error Unable to resolve path to module 'Themes'
import/no-unresolved 4:23 error Missing file extension for
"Themes"
I found some examples in this documentation, but I am not able to figure out the right way to implement it. Can anyone show me how I can set my webpack config in the correct way?
Below is my webpack.config.js:
var path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: ['babel-polyfill', './src/js/index.jsx'],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
enforce: "pre",
test: /\.jsx$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.jsx?$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'react', 'stage-0'] }
}]
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader'}
]
},
{
test: /\.less$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader'},
{ loader: 'less-loader' },
]
},
{
test: /\.(jpg|jpeg|png|gif|svg)$/i,
use: {
loader: 'url?limit=10000!img?progressive=true'
}
},
{ test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' }
]
},
resolveLoader: { moduleExtensions: ["-loader"] },
devtool: 'source-map',
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes$: path.resolve(__dirname, 'src/themes/')
}
},
plugins: [
new CopyWebpackPlugin([
{ from: './src/html' },
{ from: './src/img/favicon.ico', to: './img'}
])
],
devServer: {
inline: true,
hot: true,
contentBase: path.join(__dirname, 'dist'),
port: 5000
}
}

Try to change configuration to variant with alias look like here:
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
Themes: path.resolve(__dirname, 'src/themes/')
}
},
Then add to themes directory index.js (path: app/themes/index.js):
import * as theme1 from './theme1';
import * as theme2 from './theme2';
export default {
theme1,
theme2
}
File: app/themes/theme1/index.jsx should export object of all staff inside theme1 directory.
import Someting from './Someting';
import Anything from './Anything';
export default {
Someting,
Anything
}
Now you can try:
import * as MyThemes from 'Themes';
console.log(MyThemes.theme1.Someting);
console.log(MyThemes.theme1.Anything);
or
import MyFirstTheme from 'Themes/theme1';
console.log(MyFirstTheme.Someting);
console.log(MyFirstTheme.Anything);
all the same for theme2 directory.

Related

importing katex.min.css into my React file and webpack.config.js just doesn't work

After an epic fight with my webpack, I need to go to bed. I honestly don't know wtf the issue is.
I tried now for hours and copied some webpack configs from the web together.
This is my webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('css-minimizer-webpack-plugin');
const nodeModulesPath = path.resolve(__dirname, 'node_modules');
module.exports = {
entry: './src/index.tsx',
module: {
rules: [
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(js)x?$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(ts)x?$/,
exclude: /node_modules|\.d\.ts$/,
use: {
loader: 'ts-loader',
options: {
compilerOptions: {
noEmit: false,
},
},
},
},
{
test: /\.(scss|css)$/,
// exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'style-loader' },
{ loader: 'css-loader' },
// This is needed to help find the KaTeX fonts.
// https://github.com/bholloway/resolve-url-loader/issues/107
// https://github.com/bholloway/resolve-url-loader/issues/212
// https://stackoverflow.com/questions/54042335/webpack-and-fonts-with-relative-paths
// https://stackoverflow.com/questions/68366936/how-to-bundle-katex-css-from-node-modules-to-a-single-output-css-from-a-sass-us
'resolve-url-loader',
{
loader: "sass-loader",
options: {
// This is needed for resolve-url-loader to work!
// https://github.com/bholloway/resolve-url-loader/issues/212#issuecomment-1011630220
sourceMap: true,
sassOptions: {
includePaths: [nodeModulesPath],
},
},
},
],
},
],
},
plugins : [new MiniCssExtractPlugin()],
resolve : {
extensions: ['.css', '.tsx', '.ts', '.js'],
},
output : {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
}
};
I get the error message:
["..." | object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use? }, ...]
-> A rule.
Details:
* configuration.module.rules[3].use[0] should be one of these:
object { ident?, loader?, options? } | function | non-empty string
-> A description of an applied loader.
Details:
* configuration.module.rules[3].use[0] should be an object:
object { ident?, loader?, options? }
* configuration.module.rules[3].use[0] should be an instance of function.
* configuration.module.rules[3].use[0] should be a non-empty string.
-> A loader request.
* configuration.module.rules[3].use[0] should be one of these:
object { ident?, loader?, options? } | function | non-empty string
-> An use item.
Error: Process completed with exit code 2.
However, what I want is simply to import Katex, like
import 'katex/dist/katex.min.css'
into my table component.
Maybe someone has an idea?
Ok, I found it. And just because it was so hard for me to find the right answer online (that might be just me) - here is my solution.
I wanted to use katex in typescript React - to show a nice table here
https://0xpolygonmiden.github.io/examples/.
For that I imported into my table component
import { Fragment } from 'react';
import ReactMarkdown from 'react-markdown';
import gfm from 'remark-gfm';
import math from 'remark-math';
import katex from 'rehype-katex'
import { assemblerInstructions } from '../data/instructions';
import 'katex/dist/katex.min.css'
So katex comes with its own CSS file. Locally it runs fine and renders beautifully. However, when I tried to deploy on GitHub pages, webpack compliant that there is a loader missing for that import.
Ok. So I tried to find the right loader for that import for webpack 5.
It is simply the sass-loader and by default node-modules are excluded so I had to remove that exclude: /node_modules/, when I defined the sass-loader for CSS files. Easy, ha?
const path = require('path');
module.exports = {
entry: './src/index.tsx',
module: {
rules: [
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(js)x?$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(ts)x?$/,
exclude: /node_modules|\.d\.ts$/, // this line as well
use: {
loader: 'ts-loader',
options: {
compilerOptions: {
noEmit: false, // this option will solve the issue
},
},
},
},
{
test: /\.css$/,
use:['style-loader', 'css-loader', 'sass-loader'],
},
],
},
resolve: {
extensions: ['.css', '.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
Here is the full code for those who are interested.
https://github.com/0xPolygonMiden/examples/tree/main/playground

Multiple Webpack in React for SSR

I have a React app that I wrote with Webpack (without using CRA), and I am trying to implement server-side rendering to it. I wrote two webpack config files (one for server and one for client), in my original webpack config I had loaders for most of the types im going to use (ts, js, css, image formats and ttf), so my new config files had the same loaders but each one had a different output path (server under dist and client under dist/public).
However, with this I was having the same font in both output path, so I removed from one of them and then from both config files, the font loader, and still I was getting the fonts on both directories. Below are my webpack configurations.
To note that I downloaded a font and placed it under my src folder and using it in my index.css which is imported in App.tsx (which is used in both client.tsx and server.tsx).
webpack.config.server.ts:
import path from 'path';
import webpack from 'webpack';
import nodeExternals from 'webpack-node-externals';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
const config: webpack.Configuration = {
mode: 'development',
entry: path.resolve(__dirname, '..', 'src', 'server.tsx'),
output: {
path: path.join(__dirname, '..', 'dist'),
filename: 'server.js',
clean: true
},
target: 'node',
externals: [ nodeExternals() ],
resolve: {
extensions: [ '.ts', '.tsx', '.js', '.jsx', '.json' ]
},
module: {
rules: [
{
test: /\.jsx?$/i,
exclude: /node_modules/i,
use: 'babel-loader'
},
{
test: /\.tsx?$/i,
exclude: /node_modules/i,
use: 'ts-loader'
},
{
test: /\.css$/,
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
}/*,
{
test: /\.ttf$/i,
type: 'asset/resource'
}*/
]
},
plugins: [
new MiniCssExtractPlugin()
]
};
export default config;
webpack.config.client.ts:
import path from 'path';
import webpack from 'webpack';
const config: webpack.Configuration = {
mode: 'development',
entry: path.resolve(__dirname, '..', 'src', 'client.tsx'),
output: {
path: path.join(__dirname, '..', 'dist', 'public'),
filename: 'bundle.js',
clean: true
},
target: 'web',
resolve: {
extensions: [ '.ts', '.tsx', '.js', '.jsx', '.json' ]
},
module: {
rules: [
{
test: /\.jsx?$/i,
exclude: /node_modules/i,
use: 'babel-loader'
},
{
test: /\.tsx?$/i,
exclude: /node_modules/i,
use: 'ts-loader'
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
}/*,
{
test: /\.ttf$/i,
type: 'asset/resource'
}*/
]
}
};
export default config;
This is the build directory (with font commented and uncommented).
I find it a bit redundant for both configs to generate the same font, is there something missing in my configuration I should add? I am still trying to figure out how to properly implement server-side rendering so my configuration files may not be the best configurations.

Resolve Relative Path from node_modules to Dist folder with Webpack

I'm using React component as an NPM Package. in the component, I have SCSS file
with url(../iamges/img..) path, but actually, the images folder located in the Dist folder, how can I point Webpack to take the relative path from node_modules and serve it from images folder located in the Dist?
located in node_modules =>
background: url('../images/some-icon.svg') no-repeat center center;
Webpack config:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'resolve-url-loader',
// options: {
// debug: true,
// root: path.join(__dirname, './dist/images'),
// includeRoot: true,
// absolute: true,
// },
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
babel.config.js
module.exports = {
// presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-export-default-from',
'#babel/transform-runtime',
],
sourceType: 'unambiguous',
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
'#babel/preset-react',
],
};
dist
-- images
-- index.html
ERROR:
ERROR in ./node_modules/comp/src/styles/details.scss (./node_modules/css-loader!./node_modules/resolve-url-loader!./node_modules/sass-loader/lib/loader.js??ref--5-3!./node_modules/compdetails/src/styles/details.scss)
Module not found: Error: Can't resolve '../images/icon.svg'
Anything referred through url('...') in css will be computed with reference to the path of deployed application (scss will not compute the path unless variable or function is not being used):
For example:
If your referred component SCSS module is having background: url('../images/some-icon.svg') no-repeat center center;
The final CSS compilation will be same (it is also because the component is not using any SCSS variables or functions to compute the final path).
So your application will always try to find that image as:
Example: http://localhost:3000/../images/some-icon.svg which is a problem.
(.. is referred as parent directory)
If you try to run your app with some sub-url (also known as sub context) as http://localhost:3000/sub-url/ and you keep your images parallel to sub-url folder it will automatically work.
-- /
|
|-- sub-url
|
|-- index.html
|-- images
|
|-- some-icon.svg
Another option can be override the component SCSS with yours.
You already found the solution to use resolve-url-loader, but in this case you need to import the component's scss file into you scss.
so your webpack config should look like:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
// CHANGE HERE
{
loader: 'resolve-url-loader',
options: {
root: '/images', // considering all your images are placed in specified folder. Note: this is just a string that will get as prefix to image path
includeRoot: true,
absolute: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
I hope it helps.

css modules object import returns empty

I am trying to use css modules inside react, but it is not working.
The log of this code:
import React from 'react'
import styles from '../../css/test.css'
class Test extends React.Component {
render() {
console.log(styles)
return (
<div className={styles.app}>
<p>This text will be blue</p>
</div>
);
}
}
export default Test
returns Object {}
and the rendered code are tags with no class:
<div><p>This text will be blue</p></div>
The css code is available at site, here is my test.css:
.test p {
color: blue;
}
If I changed the div to have class='test', the color of p changes to blue
Here is my webpack.config.js
var path = require('path')
var webpack = require('webpack')
var HappyPack = require('happypack')
var BundleTracker = require('webpack-bundle-tracker')
var path = require('path')
var ExtractTextPlugin = require("extract-text-webpack-plugin")
function _path(p) {
return path.join(__dirname, p);
}
module.exports = {
context: __dirname,
entry: [
'./assets/js/index'
],
output: {
path: path.resolve('./assets/bundles/'),
filename: '[name].js'
},
devtool: 'inline-eval-cheap-source-map',
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new HappyPack({
id: 'jsx',
threads: 4,
loaders: ["babel-loader"]
}),
new ExtractTextPlugin("[name].css", { allChunks: true })
],
module: {
loaders: [
{
test: /\.css$/,
include: path.resolve(__dirname, './assets/css/'),
loader: ExtractTextPlugin.extract("style-loader", "css-loader!resolve-url-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]")
},
{
test: /\.scss$/,
include: path.resolve(__dirname, './assets/css/'),
loader: ExtractTextPlugin.extract("style-loader", "css-loader!resolve-url-loader!sass-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]")
},
{
test: /\.jsx?$/,
include: path.resolve(__dirname, './assets/js/'),
exclude: /node_modules/,
loaders: ["happypack/loader?id=jsx"]
},
{
test: /\.png$/,
loader: 'file-loader',
query: {
name: '/static/img/[name].[ext]'
}
}
]
},
resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx'],
alias: {
'inputmask' : _path('node_modules/jquery-mask-plugin/dist/jquery.mask')
},
}
}
Can anyone help me?
Thanks in advance.
Looks like your passing the css-loader params to the resolve-url-loader:
"css-loader!resolve-url-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]"
Should be:
"css-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]&importLoaders=1!resolve-url-loader"
A lot of time passed since this question, so my webpack was update many times with another technologies.
This webpack config is working:
...
module.exports = {
entry,
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
devtool:
process.env.NODE_ENV === 'production' ? 'source-map' : 'inline-source-map',
module: {
rules: [
{
test: /\.jsx?$/,
include: path.resolve(__dirname, './app/view/'),
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.pcss$/,
include: path.resolve(__dirname, './app/view/'),
use: [
{
loader: 'style-loader'
},
{
loader:
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
},
{
loader: 'postcss-loader',
options: {
plugins: function() {
return [
require('postcss-import'),
require('postcss-mixins'),
require('postcss-cssnext')({
browsers: ['last 2 versions']
}),
require('postcss-nested'),
require('postcss-brand-colors')
];
}
}
}
],
exclude: /node_modules/
},
{
test: /\.(png|svg|jpg|webp)$/,
use: {
loader: 'file-loader'
}
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [path.resolve(__dirname, 'node_modules')]
},
plugins
};
I guess that there is an issue with older versions at webpack with this line:
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
Try importLoaders and importLoader
You can see my repo too.
In my specific case, I'm using official utility facebook/create-react-app. You have to run the following command to get access to the webpack configuration:
npm run eject
You will then need to edit config/webpack.config.js and set the css-loader modules option to true.
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules:true <-----
}),

Using react-infinite-calendar with css-modules

I'd like to use react-infinite-calendar component for a personal project. It's not picking up the css. I think my webpack configuration is the problem as I'm using react-css-modules.
Could someone show me what I'd need to do to get it working?
My webpack configuration is:
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
module.exports = {
entry: './index.js',
context: path.join(__dirname, 'client'),
devtool: 'source-map',
output: {
path: './dist/client/',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
// https://github.com/gajus/react-css-modules
test: /\.css$/,
loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
}
]
},
resolve: {
extensions: ['', '.js', '.json']
},
plugins: [
new CopyWebpackPlugin([
{from: 'static/index.html'}
])
]
};
My date selector component is:
import React from 'react';
import InfiniteCalendar from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css'; // only needs to be imported once
import {TODAY} from '../../server/constants/date';
export default class DateSelector extends React.Component {
render() {
return (
<div>
<InfiniteCalendar
width={400}
height={600}
selectedDate={TODAY}
maxDate={TODAY}
/>
</div>
);
}
}
Another option is to exclude react-infinite-calendar from your CSS module loader and include it in the standard CSS loader.
That way you don't have to rename all of your CSS files.
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
exclude: /react-infinite-calendar/,
loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
},
{
test: /\.css$/,
include: /react-infinite-calendar/,
loader: 'style-loader!css-loader',
},
]
I worked around this by having to separate webpack loaders for locally scoped css-modules and globally scoped ones. My webpack configuration is below and so for css modules I've had to name the files so they end with .module.css.
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
module.exports = {
entry: './index.js',
context: path.join(__dirname, 'client'),
devtool: 'source-map',
output: {
path: './dist/client/',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
// https://github.com/gajus/react-css-modules
test: /\.module.css$/,
loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
},
{
test: /^((?!\.module).)*css$/,
loader: 'style-loader!css-loader'
},
]
},
resolve: {
extensions: ['', '.js', '.json']
},
plugins: [
new CopyWebpackPlugin([
{from: 'static/index.html'}
])
]
};

Resources