I have the following version of those libraries:
{
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
"#babel/cli": "^7.20.7",
"#babel/core": "^7.20.12",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.2"
}
This is my routes that are configured inside this file:
export default function Routes() {
return useRoutes([
{
path: "auth",
children: [
{
path: "login",
element: (
<GuestGuard>
<Login />
</GuestGuard>
),
},
],
},
//Dashboard Routes
{
path: "dashboard",
element: (
<AuthGuard>
<Dashboard />
</AuthGuard>
),
},
{
path: "/",
element: (
<AuthGuard>
<Dashboard />
</AuthGuard>
),
},
{ path: "*", element: <Navigate to="/404" replace /> },
]);
}
And I am using Routes() inside the Main component:
const Main = () => {
return (
<React.Fragment>
<Router>
<Routes />
</Router>
</React.Fragment>
);
}
According to my Routes components, I am expecting to have 3 available URLs in my project:
"/auth/login"
"/dashboard"
"/"
I can see that I am having a conflict between babel/webpack and react-router-dom.
While trying to go to one of the URLs above(not '/') I am receiving this error:
Cannot GET /dashboard
I've never encountered such an error, and this is the first time I have manually set webpack and babel to my project, so I guess the issue is coming from there.
this is my webpack.config.js:
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const dotenv = require('dotenv')
// this will update the process.env with environment variables in .env file
dotenv.config();
module.exports = {
entry: './index.js',
mode: 'development',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js',
},
target: 'web',
devServer: {
port: '3000',
static: {
directory: path.join(__dirname, 'public')
},
open: true,
hot: true,
liveReload: true,
historyApiFallback: true,
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
process: "process/browser"
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'public', 'index.html')
}),
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env)
})
]
};
What am I missing here?
Related
I am using webpack and typescript in my SPA along with the oidc-client npm package.
which has a structure like this:
oidc-client.d.ts
oidc-client.js
oidc-client.rsa256.js
When I import the oidc-client in my typescript file as below:
import oidc from 'oidc-client';
I want to import the rsa256 version and not the standard version, but I am unsure how to do this.
in my webpack config I have tried to use the resolve function but not I am not sure how to use this properly:
const path = require('path');
const ForkTsChecker = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const FileManagerPlugin = require('filemanager-webpack-plugin');
const shell = require('shelljs');
const outputFolder = 'dist';
const destinationFolder = '../SPA/content';
if (shell.test('-d', outputFolder)) {
shell.rm('-rf', `${outputFolder}`);
}
if (shell.test('-d', destinationFolder)) {
shell.rm('-rf', `${destinationFolder}`);
}
module.exports = (env, options) => {
//////////////////////////////////////
/////////// HELP /////////////////////
/////////////////////////////////////
resolve: {
oidc = path.resolve(__dirname, 'node_modules\\oidc-client\\dist\\oidc- client.rsa256.slim.min.js')
};
const legacy = GenerateConfig(options.mode, "legacy", { "browsers": "> 0.5%, IE 11" });
return [legacy];
}
function GenerateConfig(mode, name, targets) {
return {
entry: `./src/typescript/main.${name}.ts`,
output: {
filename: `main.${name}.js`,
path: path.resolve(__dirname, `${outputFolder}`),
publicPath: '/'
},
resolve: {
extensions: ['.js', '.ts']
},
stats: {
children: false
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts\.html?$/i,
loader: 'vue-template-loader',
},
{
test: /\.vue$/i,
loader: 'vue-loader'
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'#babel/env',
{
"useBuiltIns": "usage",
"corejs": { version: 3, proposals: true },
"targets": targets
}
],
"#babel/typescript"
],
plugins: [
"#babel/transform-typescript",
[
"#babel/proposal-decorators",
{
"legacy": true
}
],
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/proposal-class-properties",
"#babel/proposal-numeric-separator",
"babel-plugin-lodash",
]
}
}
}
]
},
devServer: {
contentBase: path.join(__dirname, outputFolder),
compress: true,
hot: true,
index: `index.${name}.html`,
open: 'chrome'
},
plugins: [
new ForkTsChecker({
vue: true
}),
new HtmlWebpackPlugin({
filename: `index.${name}.html`,
template: 'src/index.html',
title: 'Project Name'
}),
new MiniCssExtractPlugin({ filename: 'app.css', hot: true }),
new VueLoaderPlugin()
]
};
}
Please add an alias to specify the exact .js module you'd like to import, like this for example:
resolve: {
extensions: ['.ts','.js'],
modules: ['node_modules'],
alias: {
'oidc-client': 'oidc-client-js/dist/oidc-client.rsa256.slim'
}
}
If you don't specify an alias, webpack/ will follow node module resolution and we'll eventually find your module by going to
library oidc-client-js in node_modules and follow package.json main property which is "lib/oidc-client.min.js" and that's not what you want.
I had a different thread here: React Build Tool and Dev Server
to setup React with Webpack. Seems like it is working but I have an issue with having the html page show the code from entry point app.js . I can see the code is in bundle.js. If I modify anything in app.js till the render method e.g enter a typo or something I see an error on console but nothing happens with the render() method. Not matter what I do there is no error and nothing shows but a blank page.
app.js
import React from 'react';
import ReactDOM from 'react-dom';
export default class App extends React.Component {
render() {
return (
ReactDOM.render(<h1>Render me!</h1>,
document.getElementById('app'))
);
}
}
Index.html
<!DOCTYPE html>
<html>
<head>
<!-- Bootstrap, latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src='bundle.js'></script>
</body>
</html>
So if I view page source it just shows just
and not the expected Render me!
And just in case below is my webpack.config
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
bundle: './src/app.js'
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-1']
}
}]
},
resolve: {
extensions: ['*', '.js', '.jsx']
}
};
Also this is from my package.json. I believe my bundle.js is being served from memory right now.
"scripts": {
"start": "webpack-dev-server --port 3000 --hot --inline",
"build": "webpack --progress --colors"
}
I run npm start to compile and start the server. I was expecting npm build will build to dist folder but it doesn't . For now I just want this working one way or the other so I can start coding.
And .babelrc
{
"presets":[
"es2017", "react"
]
}
You are using WebPack 3.x?
Try this config:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const autoprefixer = require('autoprefixer');
const staticSourcePath = path.join(__dirname, 'static');
const sourcePath = path.join(__dirname);
const buildPath = path.join(__dirname, 'dist');
module.exports = {
devtool: 'source-map',
devServer: {
historyApiFallback: true,
contentBase: './'
},
entry: {
"index" :path.resolve(sourcePath, 'index.js')
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[chunkhash].js',
publicPath: '/'
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
modules: [
sourcePath,
path.resolve(__dirname, 'node_modules')
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[chunkhash].js',
minChunks: Infinity
}),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer({
browsers: [
'last 3 version',
'ie >= 10'
]
})
],
context: staticSourcePath
}
}),
new webpack.HashedModuleIdsPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
path: buildPath,
excludeChunks: ['base'],
filename: 'index.html',
minify: {
collapseWhitespace: true,
collapseInlineTagWhitespace: true,
removeComments: true,
removeRedundantAttributes: true
}
}),
new PreloadWebpackPlugin({
rel: 'preload',
as: 'script',
include: 'all',
fileBlacklist: [/\.(css|map)$/, /base?.+/]
}),
new webpack.NoEmitOnErrorsPlugin()
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react'],
}
},
include: sourcePath
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: { minimize: true } },
'postcss-loader',
'sass-loader'
]
})
},
{
test: /\.(eot?.+|svg?.+|ttf?.+|otf?.+|woff?.+|woff2?.+)$/,
use: 'file-loader?name=assets/[name]-[hash].[ext]'
},
{
test: /\.(png|gif|jpg|svg)$/,
use: [
'url-loader?limit=20480&name=assets/[name]-[hash].[ext]'
],
include: staticSourcePath
}
]
}
};
I have setup hot reloading with react-hot-loader. In the console it looks like it works, but browser does not actually reload. Why is this?
Ignore the errors, I think they come from a plugin. It correctly detects I change App.jsx but the browser does not update unless I do a full refresh.
My webpack.config.js below:
const path = require("path")
const webpack = require("webpack")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const context = path.resolve(__dirname, "src")
const {dependencies} = require("./package.json")
module.exports = {
context,
entry: {
vendor: Object.keys(dependencies),
app: [
"react-hot-loader/patch",
"./js/index.js"
]
},
output: {
path: path.resolve(__dirname, "build"),
filename: "[name]-[hash].js"
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
plugins: [
[
"react-css-modules",
{
context
}
]
]
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: "[path]___[name]__[local]___[hash:base64:5]",
sourceMap: true
}
},
'postcss-loader'
]
})
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor"
}),
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html"
}),
new webpack.NamedModulesPlugin(),
new ExtractTextPlugin("css/[name].css")
],
devServer: {
contentBase: path.resolve(__dirname, "src"),
historyApiFallback: true
},
devtool: "eval"
}
index.js
import ReactDOM from "react-dom"
import React from "react"
import {AppContainer} from "react-hot-loader"
import App from "./App.jsx"
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById("app")
)
}
render(App)
if (module.hot) {
module.hot.accept("./App.jsx", () => render(App))
}
My Spooky/Casper/Phantom project was working just fine. Then I tried to involve Webpack.
When I run the program, I get:
CasperError: Can't find module node_modules/spooky/lib/bootstrap/emit
[ { file: 'phantomjs://code/bootstrap.js',
line: 297,
function: 'patchedRequire' } ]
My file structure is as follows:
dist/
index.js
webpack.config.js
...
node_modules/
In my index.js:
import Spooky from 'spooky';
const spooky = new Spooky({
child: {
transport: 'http',
spooky_lib: 'node_modules/spooky/',
},
casper: {
logLevel: 'debug',
verbose: false
}
}, ...);
My webpack.config.js:
const path = require('path');
module.exports = {
context: __dirname,
entry: './index.js',
target: 'node',
output: {
path: path.join(__dirname, 'dist'),
filename: 'index.js',
publicPath: path.join(__dirname, 'dist')
},
devtool: 'source-maps',
node: {
__dirname: true
},
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
}
]
},
resolve: {
extensions: ['.js']
}
};
I am using react-hot-loader and webpack-hot-middleware with express for live reload but it is not working. webpack listens for the changes but is not shown on the browser. Have i missed something?
webpack-config.js
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = 'development'
}
const isDevelopment = process.env.NODE_ENV === 'development';
const VENDOR_LIBS = [
'react', 'react-dom', 'redux', 'react-redux',
'react-router', 'react-router-redux', 'lodash',
'express'
];
const entryPath = path.join(__dirname, 'src/index.js');
const config = {
entry: {
bundle: isDevelopment ? [
'webpack-hot-middleware/client?reload=true',
'react-hot-loader/patch',
entryPath
] : entryPath,
vendor: isDevelopment ? [
'react-hot-loader/patch',
VENDOR_LIBS
] : VENDOR_LIBS,
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: isDevelopment ? '[name].[hash].js' : '[name].[chunkhash].js',
},
devtool: 'source-map',
module: {
rules: [
{
loader: ExtractTextPlugin.extract({
loader: 'css-loader'
}),
test: /\.css$/,
},
{
use: ['babel-loader'],
test: /\.js$/,
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production')
}
}),
new HtmlWebpackPlugin({
inject: true,
template: 'src/index.html',
minify: {
removeComments: false,
collapseWhitespace: false,
}
}),
new ExtractTextPlugin('style.css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
],
};
isDevelopment && config.plugins.push(new webpack.HotModuleReplacementPlugin());
!isDevelopment && config.plugins.push(
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false,
screw_ie8: true
},
})
);
module.exports = config;
package.json
"scripts": {
"pre-start": "webpack",
"start-dev": "node server.js --development",
"start-prod": "rimraf dist && webpack && node server.js --production"
},
server.js
if (process.env.NODE_ENV !== 'production') {
console.log('DEVOLOPMENT ENVIRONMENT: Turning on WebPack Middleware...');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
hot: true,
historyApiFallback: true,
publicPath: webpackConfig.output.publicPath,
contentBase: './dist/',
stats: {
colors: true,
'errors-only': true
}
}));
app.use(require('webpack-hot-middleware')(compiler));
} else {
app.use(express.static(__dirname + '/dist'));
}
app.get('*', function (request, response) {
response.sendFile(__dirname + '/dist/index.html');
});
app.listen(port);
console.log(`server started on port: ${port}`);
I am not sure, but, is it problem due to chunkhash?
UPDATE
index.js
ReactDOM.render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>
, document.querySelector('#app'));
if (module.hot) {
module.hot.accept('./components/root', () => {
ReactDOM.render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>
, document.querySelector('#app'));
});
}