I'm in the process of writing a web app but I constantly see something that really wakes my OCD up. The "src" folder created by create-react-app just doesn't fit well with my idea of folder structure, I'd rather put my views inside a folder called "views". I tried to search for a solution but all I found was "create a symlink". Is there any way to make create-react-app to nominate "src" with some other names?
You can yarn run eject your CRA boilerplate to Tweak with webpack.config.js. yarn run eject reveals the entire preloaders and plugins used to compile your project.
sample script from webpack's wiki
{
context: __dirname + "/views",
entry: "./entry",
output: {
path: __dirname + "/dist",
filename: "bundle.js"
}
}
Important
yarn run eject is a one-way road and you cannot revert back. so be careful.
Related
Context
I have two projects, main and styles.
Main uses styles as an npm package, importing it as #companyname/styles.
I need to make changes to styles and want to link it locally to see these changes in main.
This is a react app, using Webpack and babel. Yarn is the favoured package manager.
Problem
Using npm link OR yarn link works in so far as I can go into the node_modules/#companyname/styles folder in main and see my changes in there.
However, no changes are reflected in the browser.
I only use one or the other (yarn/npm) at a time, but problem exists with either one
Things I've tried
Deleting node_modules, reinstalling and re-linking
Unlinking and re-linking
Rebuilding
Clearing npm cache, clearing yarn cache
Viewing site in incognito
Deleting dist folder in main and reinstalling
Adding CleanWebpackPlugin to my webpack config
Adding hot: true, to my devServer config in webpack config.
TL;DR
Yarn/npm link not showing my changes in browser, however will show changes in node_modules. Something causing browser to not read changes. Please help.
Have you tried deleting the lock file?
rm package-lock.json
npm clean-install
the cause is in webpack configuration. It took me days to find the perfect combination for symlink packages.
In my case, my project was a Vue app.
So here's a summary of my findings for people from the future (for Webpack 5):
const path = require('path');
module.exports = {
resolve: {
symlinks: false // Important so that symlink packages are resolved to their symlinked location
// If your package contains frontend framework components, prevent two instances of the framework (React for example), one from the app and the other one from the symlink package
// Kudos to https://stackoverflow.com/a/68497876/11840890
alias: {
react: path.resolve('./node_modules/react'),
'#': path.resolve(__dirname, './src') // Add this alias if you get a new issue after setting up the first one
}
},
snapshot: {
// Even though added changes on the symlink package may trigger rebuild, they might not be seen on the browser (using HMR or not)
// To prevent reloading dev server every time, add this (it will include only node_modules but your package in the cache):
managedPaths: [
/^(.+?[\\/]node_modules[\\/](?!(#author[\\/]your-package))(#.+?[\\/])?.+?)[\\/]/,
],
},
}
I have a Rails app that uses Webpack to bundle its assets. It doesn't currently use React.
In a separate repository, I have created a React app. This React app basically implements a complex custom UI element. The plan is that I can import this react component into my main application.
So far I have added the git repo to my package.json file and can see that the source code of my react app is being downloaded into the /node_modules folder.
I can get Webpack to bundle the app by adding:
To the React app package.json:
"prepare": "npm run build"
And in my main application webpack.config
module.exports = {
...
resolve: {
...
alias: {
MyReactApp: 'my-react-app/dist/bundle.js'
}
}
}
But it seems to be bundling all the libraries that my React app uses inside bundle.js and not adding them to the dependency tree.
It appears that the prepare command is basically bundling my React app into a /dist/bundle.js file and Webpack is simply including this file as-is. I need Webpack to manage the dependencies of my React app, such that I don't have unnecessary libraries duplicated in the final Webpack output.
Is there a better way to achieve what I am trying to achieve?
It is better to bundle them together. Basically, it is trying to bundle already bundled code.
This may work:
resolve: {
alias: {
MyReactApp: 'my-react-app/index.js'
}
}
index.js should be main jsx starting point.
Additionally, you need to add compile rules for jsx files, I never bundled Rail apps but React apps you should follow these steps;
Add rule to webpack.config.js
module: {
rules: [
{
// this is so that we can compile any React,
// ES6 and above into normal ES5 syntax
test: /\.(js|jsx)$/,
// we do not want anything from node_modules to be compiled
exclude: /node_modules/,
use: ["babel-loader"]
},
...
]
}
Install Babel modules:
npm install #babel/core #babel/node #babel/preset-env #babel/preset-react babel-loader
create a file called .babelrc and paste the following code
{
"presets": ["#babel/env", "#babel/react"],
"plugins": ["#babel/plugin-proposal-class-properties"]
}
Run webpack though babel-node like following script
"webpack": "babel-node ./node_modules/webpack/bin/webpack"
This would be my approach to solve this problem. It will still import react to your project. But instead of adding the compiled project, it will add jsx files and will compile them during the bundling process.
Note:
babel/core this is used to compile ES6 and above into ES5
babel/node this is used so that we can import our plugins and packages inside the webpack.config.js rather than require them
(it’s just something that I like, and maybe you’ll like it too)
babel/preset-env this will determinate which transformations or plugins to use and polyfills (i.e it provides modern
functionality on older browsers that do not natively support it)
based on the browser matrix you want to support
babel/preset-react this is going to compile the React code into ES5 code
babel-loader this is a Webpack helper that transforms your JavaScript dependencies with Babel (i.e. will transform the import
statements into require ones)
We are having a big environment where we have several applications under the same domain eg:
foo.org/a
foo.org/b
We have set up IIS to act in the same way on localhost, so we can type:
localhost/a
localhost/b
to reach the applications. The setup is done so to avoid CORS problems.
We are now trying to create a new application with "create-react-app" (https://github.com/facebook/create-react-app).
To add relative paths when you build for production is no problem, the problems occur when you try to run this with react-scripts start on localhost.
It seems it doesn't support relative paths so it always try to fetch build.js and other resources from /and there is not possible to set this without ejecting webpack.
So my question is, do you have any good ways of sorting this out? Ejecting webpack is not a good solution for us.
You can ejecting the config files by running: npm run eject
Then you'll find a config folder created in your project.
You will find your webpack config files init, where you should be able to change the "root" folder:
module.exports = {
...
resolve: {
modules: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, './'), // "root" folder
]
}
...
}
Edit: Oh sorry - didn't see that ejecting is no option for you... And unfortunately I don't know any other solution.
"homepage": "/subfolder/path", in package json file should help
I am fiddling around with the following local drf-react setup. I'm really new to react and javascript overall and got absolutely no idea why I cannot import axios or any other node module for that matter in my react components, except for the modules that already shipped with the cookiecutter project itself. Is this related to the react-dev-utils..? I would like to use webpack, but I fail to set it up properly. My frontend docker container won't compose, telling me to install webpack-cli. Help is much appreciated.
https://github.com/moritz91/drf-react-app
You should run the command npm install inside your frontend folder:
Open the terminal
Find the frontend folder
Inside of it run the command npm install
This command will install the dependencies related to your package.json file, which is inside the frontend folder.
Inside your React files you will put the whole path to the node_modules folder.
The idea of using node_modules is to make it easier to control your dependencies in your project. You should consider again using webpack to handle these files from node_modules.
Wepack has a module called resolve which you have to fill with a list of directories and inside React components you don't need to use the whole path anymore, because Webpack will understand where to look:
// ALIAS
resolve: {
extensions: ['.js', '.jsx', '.scss'],
modules: [
'YOUR SOURCE FOLDER',
'YOUR NODE MODULES FOLDER',
'ANY OTHER FOLDER'
]
}
From the docs:
Tell webpack what directories should be searched when resolving modules.
The documentation: https://webpack.js.org/configuration/resolve/
Also, I have an example using Webpack + Bootstrap 4.
You can use to build your own Webpack config for React and Redux.
https://github.com/italoborges/webpack-bootstrap4-es6
Here is a question.
I'm trying to merge some of my packages into a monorepo. I'm using yarn and it's workspaces-experimental feature. So the repository folder structure looks like:
.
node_modules
packages
myapp1
myapp2
myreactapp1
Now, one of the goals is to simplify testing. I want to run jest in the root dir so that it runs unit tests for all the packages. And it works for myapp1 and myapp2 above which are node.js apps. However, myreactapp1 is build with create-react-app (no eject) and uses ES6 features (like import) and also jsdom rendering. The tests work fine if I run them from myreactapp1 dir with yarn test which pipes the code through babel (if I understand well). But the root jest failes on the first import statement.
How can I do it ?
P.S. I tried to install babel-jest but seems that it cannot be lauched directly from the console (windows).
It seems that CRA does not yet work properly with Yarn Workspaces. A workaround is suggested in the comments.
Anyway, to make jest work, you need to have babel-jest (as you said) and also a .babelrc file in the root folder:
{
"presets": ["es2015", "react"]
}