Craco build fails, taking aliased folder as external package - reactjs

I'm using craco and craco-alias to implement aliases for imports in my Create React App project.
Followed instructions in https://github.com/gsoft-inc/craco/blob/master/packages/craco/README.md#installation and https://github.com/risenforces/craco-alias#readme
I configured package.json to use craco instead of react-scripts for starting dev server, tests and production build
...
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"lint:css": "stylelint './src/**/*.css'",
"lint:js": "eslint 'src/**/*.js'",
"test:w": "craco test --watch",
"postinstall": "patch-package"
},
...
Then I created jsconfig.json file w aliases paths
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#components": ["components/*", "components"],
"#constants": ["constants/*", "constants"],
"#assets": ["assets/*", "assets"],
"#store": ["store/*", "store"],
"#utils": ["utils/*", "utils"]
},
"include": ["src"],
"exclude": ["node_modules", "build", "coverage"]
}
And craco.config.js file, which uses craco-alias plugin
/* craco.config.js */
const CracoAlias = require('craco-alias');
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
baseUrl: './src',
source: 'jsconfig',
}
}
]
}
Now I'm using aliases for imports in my app like this
// root index.js file
...
import Layout from '#components/Layout';
import store from '#store'; // this line causes error on CI build
function App() {
return (
<Layout>
/* inner components */
</Layout>
);
}
Everything works fine (aliased imports works on dev-server, in jest tests and even if I serve locally built project) until I push it to github repo. That repo has configured github actions to build and test project on remote server and it fails with error on build step, after installing all packages.
Run yarn build
yarn run v1.22.4
$ craco build
Creating an optimized production build...
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
Failed to compile.
./src/index.js
Cannot find module: '#store'. Make sure this package is installed.
You can install this package by running: npm install #store.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
##[error]Process completed with exit code 1.
Could somebody help me understand what wrong with my code? Why craco or webpack expect '#store' to be external package instead of aliased import of internal module?

In my case problem wasn't in craco or webpack, but in my previous actions and OS filesystem differences. I'm using Windows 10 and WSL in VS Code terminal. So before I use '#' symbol for aliases I tried to use CamelCase for my folders and renamed it via windows explorer (because for me it was simpler to close VSCode and rename files via explorer than to open new bash terminal in new VSCode window after closing opened files).
Then I prefer to use '#' symbol and rename folders back to lowercase. I configured aliases and pushed changes to remote github repo, where CI actions were run. When CI was running actions it can't find 'store' folder (because previously I renamed it to 'Store' and it was last saved path to folder in git), so it tried to find external package named 'store'.
To fix this I change git config to stop ignoring namecasing for my folder by running command git config core.ignorecase false. Git history was updated, I push it to remote repo and CI actions succeeded.

Related

How to tell `import` to always read files from the `src/` directory for a reactjs project

I inherited a react project that was working on my last computer. But now it can't build on my new computer. Specifically, I forgot how to get the npm start command to know where the project directory is.
For example, let's say I have the following two files:
// src/template/Page.js
import LoginComponent from 'component/Login.js'
// src/component/Login.js
export default function Gallery() { return <div></div>;}
Then when I run npm start, I get the error:
Module not found: Can't resolve 'component/Login.js' in 'src/template/Page.js'
I vaguely remember that on my last computer, I used some hidden file, or possibly the .env file to tell npm to look for all react components under the src/ directory, such that the term src/ can be omitted from all the import statements in the code.
Does anyone know how to tell react or npm to always import components without always spelling out the src/ prefix?
NOTE:
I also see a .vscode directory with these files:
// .vscode/settings.json
{
"editor.snippetSuggestions": "top",
"files.associations": {
"*.js": "javascriptreact"
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": false
},
"compilerOptions": {
"baseUrl": "src"
}
}
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Chrome",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceRoot}/src"
}
]
}
I think these files might be related to my solution last time I got this working
In my package.json, I see these lines:
...
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
...
Also, my package.json says I'm using "react": "^16.6.1" and my npm -v shows 5.5.1. I don't remember what npm version I was using on my last computer. So not sure if that would matter.
You need a jsconfig.json to configure absolute imports (if you were using TypeScript, you would instead use tsconfig.json). This file is vital to your project working correctly, so you should commit this to source control so you don't have to remake it on each machine:
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
I did not know Create React App supported this, I learned something today from your question. Thanks!
Finally got it work. I added this line to my .env file:
NODE_PATH=src
And then everything worked. Taken from documentation here: https://nodejs.org/api/modules.html
If the NODE_PATH environment variable is set to a colon-delimited list
of absolute paths, then Node.js will search those paths for modules if
they are not found elsewhere.
On Windows, NODE_PATH is delimited by semicolons (;) instead of
colons.
NODE_PATH was originally created to support loading modules from
varying paths before the current module resolution algorithm was
defined.
NODE_PATH is still supported, but is less necessary now that the
Node.js ecosystem has settled on a convention for locating dependent
modules. Sometimes deployments that rely on NODE_PATH show surprising
behavior when people are unaware that NODE_PATH must be set. Sometimes
a module's dependencies change, causing a different version (or even a
different module) to be loaded as the NODE_PATH is searched.
Additionally, Node.js will search in the following list of
GLOBAL_FOLDERS:
1: $HOME/.node_modules
2: $HOME/.node_libraries
3: $PREFIX/lib/node
Where $HOME is the user's home directory, and $PREFIX is the Node.js
configured node_prefix.
These are mostly for historic reasons.
It is strongly encouraged to place dependencies in the local
node_modules folder. These will be loaded faster, and more reliably.

error serving react app using react-app-wired

I have a react application created with create-react-app using react-data-grid#7. Since canary17 they started to use es2020 modules, to using the more recent builds I have to add support to optional-chaining and nullish-coalescing-operator to the app, otherwise I have errors starting the app.
After a few searchs, I installed customize-cra and react-app-rewired, changed the scripts commands to
"start": "react-app-rewired start"
"build": "react-app-rewired build"
and added this config-overrides.js
const {
override,
addBabelPlugin
} = require("customize-cra");
module.exports = override(
addBabelPlugin("#babel/plugin-proposal-optional-chaining"),
addBabelPlugin("#babel/plugin-proposal-nullish-coalescing-operator"),
);
Trying to run the app I obtain a strange behavior.
using the start command I obtaing the same error, but if I build and the deploy the app works correctly.
If I add something wrong in the config-overrides.js and try to start run start I received an error message, so I think the file is loaded.
Am I missing something?
After a few tests I found the solution changing from
addBabelPlugin("#babel/plugin-proposal-optional-chaining"),
addBabelPlugin("#babel/plugin-proposal-nullish-coalescing-operator"),
to
addExternalBabelPlugin(["#babel/plugin-proposal-optional-chaining", { "loose": false }]),
addExternalBabelPlugin(["#babel/plugin-proposal-nullish-coalescing-operator", { "loose": false }]),
I added the loose parameter too, but it was not the problem. now looks like works both in serve and build

How to run a different build command for staging environment when publishing a react amplify application

I have an amplify react application with two environments so far: prod and staging.
Then I have my .env.staging and .env.production files with different values for an API URL.
Therefore, in my package.json I have the following scripts ready for the deployment:
"build": "react-scripts build",
"build:staging": "env-cmd -f .env.staging react-scripts build",
Now the problem comes as I don't know how to make amplify publish command to run one or the other depending on the environment.
No matter which amplify env checkout I choose, the configuration used on the 'publish' command is shared in the 'project-config.json', and it looks like the following:
{
"projectName": "whatever",
"version": "3.0",
"frontend": "javascript",
"javascript": {
"framework": "react",
"config": {
"SourceDir": "src",
"DistributionDir": "build",
"BuildCommand": "npm.cmd run-script build",
"StartCommand": "npm.cmd run-script start"
}
},
"providers": [
"awscloudformation"
]
}
Is there any way to achieve what I'm looking for?
Thanks for your help in advance.
I understand this question was asked almost 1 year ago now, but i encountered this same problem this morning and would like to offer my solution to the problem.
Currently (asof 04/03/22) there is still no official solution to the problem and as such, you will be required to edit your build script to build your content based on the environment dynamically.
The way we have currently implemented this is by creating a build JS script in our root (named build-env.script.js) containing the following code:
#! /usr/bin/env node
(function() {
// bring in child_process to use spawn command
const cp = require('child_process');
// bring in the amplify local-env-info.json to see current environment
const buildInfo = require('./amplify/.config/local-env-info.json');
// spawn the build command based on the env name:
// npm run build-production on prod or npm run build-staging on staging
const cmd = cp.spawn(`npm run build-${buildInfo.envName}`, { shell: true });
// echo output of the commands to the console
cmd.on('spawn', () => console.log('Running build command for:', buildInfo.envName));
cmd.stdout.on('data', (d) => console.log(d.toString()));
cmd.stderr.on('data', (d) => console.log(d.toString()));
cmd.on('exit', () => console.log('Build Completed'));
})();
As a sidenote, the JSON file in question is created by amplify and therefore can be determined as a source of truth when it comes to looking for the current environment name, my file for example looks like this:
{
"projectPath": "path/to/project/frontent",
"defaultEditor": "vscode",
"envName": "production"
}
Whilst my package.json looks like this:
{
...
"scripts": {
...
"build": "node ./build-env.script.js",
"build-staging": "ng build --configuration staging",
"build-production": "ng build --configuration production"
}
}
However you will need to modify the env names and scripts accordingly (as our project is an angular project.

How to add flowtype to an ejected create-react-app?

We are working on a previously ejected create-react-app and now want to add flowtype.
We have followed the guide at: https://flow.org/en/docs/tools/create-react-app/
Should that work for an ejected app?
This has unfortunately caused the webpack-dev server launched with yarn start to stop automatically reloading on file updates.
Additionally, after adding // #flow to some files there is no output or indication of flow enforcing type checking.
Will we need to manually update the webpack configs?
Heres the package.json scripts
"scripts": {
"start": "node scripts/start.js",
"build": "yarn build-client && yarn build-server",
"build-client": "node scripts/build.js",
"build-server": "./node_modules/.bin/webpack --config ./config/webpack.server.config.js",
"test": "node scripts/test.js --env=jsdom",
},
The output for running yarn start is:
Compiled successfully!
You can now view cra in the browser.
Local: http://localhost:3000/
On Your Network: http://192.168.1.65:3000/
Note that the development build is not optimized.
To create a production build, use yarn build.
The doc you linked tells you how to install the flow-bin and to make a configuration file but don`t tells how to launch it.
Flow is separated tool that should be launch by own command (depends on how you wanna run it):
if you want to check types check manually, you need to add npm command on the "scripts" section of your package.js: "example-comand-flow": "flow". Then call it by npm run example-comand-flow and you`ll get errors directly on a terminal you running the script.
if you wanna have continuing type checking, you should find a manual how to configure it in your IDE. For example, in WebStorm you should go Preferences -> Languages & Frameworks -> JavaScript and set JavaScript language version to Flow and specify flow executable.

React tutorial - how do I start the node server for a reactJs application?

I'm just starting the react.js tutorial, I've downloaded the files and then it mentions:
"Follow your progress by opening http://localhost:3000 in your browser (after starting the server). "
I know this may sound stupid, (bear with me since I'm a beginner with React) but how do I start the server in this instance?
Thanks.
Marc
Pretty solid chance it's npm start from the project root.
Properly packaged modules will have some node scripts configured in package.json. It's customary to use start as the script to run the dev environment, though some might use build, dev, or other names.
Here's official installation process: link, and officially recommended tutorials
# install react cli
npm install -g create-react-app
# create app
create-react-app my-react-app-name
# go to project folder
cd my-react-app-name
# install dependencies
npm install
# start live server
npm start
output:
$ You can now view my-react-app-name in the browser.
$ Local: http://localhost:3000/
$ On Your Network: http://192.168.0.105:3000/
$ Note that the development build is not optimized.
$ To create a production build, use npm build.
You can run any one of the below mentioned commands to start the node server for your ReactJS application:
npm run-script start
npm run start
npm start
All the above commands are equivalent but people prefer the third one as it is the shortest to type on keyboard.
The start parameter in these commands maps to the start key present under scripts configuration present in package.json file of any ReactJS application. Here is a sample package.json file of my hello-world application:
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^15.4.2",
"react-dom": "^15.4.2"
},
"devDependencies": {
"react-scripts": "0.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
You can see that react-scripts start is written in front of start key. So react-scripts start command will get fired when we run any of the three commands which I had enlisted in the beginning e.g. npm start.
I used Node to run the server. The steps I followed are:
I downloaded the zip package from the Running a server section
here
I had the link open: http://localhost:3000/
I opened up Node.js Command Prompt and navigated to the downloaded
zip project. From Node example here:
Just type the commands in the example:
First npm install and then
node server.js.
See the screen shot below:
When I refresh the localhost web page I see the following:
Sounds like you're following the official React tutorial, in which case the instructions to start the various included server implementations are here.

Resources