Is there any way to fail the yarn build step in case any environment variable is missing. In the bitbucket pipeline script the build process is executing even if no env variable is set under the repository variables.
Yes, this can be possible using an approach in the React app. In the root directory create a JS file named as validate-env.js and add the below content in it (I'm using only these env variables in my app - change them according to yours)
require('dotenv').config();
if (!process.env.REACT_APP_WEB_SOCKET_URL) {
throw 'REACT_APP_WEB_SOCKET_URL undefined';
} else if (!process.env.REACT_APP_API_URL_PROD) {
throw 'REACT_APP_API_URL_PROD undefined';
} else if (!process.env.REACT_APP_NODE_ENV) {
throw 'REACT_APP_NODE_ENV undefined';
} else if (!process.env.REACT_APP_CATE_APP) {
throw 'REACT_APP_CATERING_APP undefined';
} else if (!process.env.REACT_APP_FRESH_CHAT_TOKEN) {
throw 'REACT_APP_FRESH_CHAT_TOKEN undefined';
} else if (!process.env.REACT_APP_SENTRY_DSN_KEY) {
throw 'REACT_APP_SENTRY_DSN_KEY undefined';
} else {
console.log('required env set');
}
Make sure to install a dev dependency as yarn add dotenv -D
Now under the package.json file > script section add this line
"validate-env": "node ./validate-env",
and update the build script as (if you are using craco)
"build": "yarn validate-env && craco build",
So, whenever you will run yarn build. It will first check if all the env are present. IF anyone is missing it will fail the build process.
In our project, we are using monorepo and we had to use react-app-rewired to customize some of the webpack configs without ejecting.
Now I am getting 3 deprecation warnings and I can't find anything related to them in the code. I assume that these are baried somewhere in CRA internal.
Also inspected the config object in config-overload.js. Didn't find anything even remotely related to these deprecations.
module.exports = function override(config, env) {
// Remove the ModuleScopePlugin which throws when we try to import something
// outside of src/.
config.resolve.plugins.pop();
// Let Babel compile outside of src/.
// console.error('tsRule ', config);
// exit();
const tsRule = config.module.rules[1].oneOf[3];
tsRule.include = undefined;
tsRule.exclude = /node_modules/;
return config;
}
How can I resolve these?
Another note: we also upgraded node to the latest (17). Not sure is that related.
I have a basic create-react-app TypeScript project (client). Just directory up, I have a server and a shared folder. Inside the shared folder I have a number of interfaces and enums that I share between the server and the client.
I wish to link this shared folder to both the client and server packages.
First, I went to shared and ran $ yarn link and then ran $ yarn link shared from both the client and the server folders.
The server is as happy as can be, and for the most part the client is too. However, as soon as I use one of the enums from the shared directory in the client, I get an error:
../shared/src/models/Roles.ts 4:0
Module parse failed: The keyword 'enum' is reserved (4:0)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
You may need an additional loader to handle the result of these loaders.
| $RefreshSetup$(module.id);
|
> enum Roles {
| RW_ORG = "rw_org", // can modifiy organization and it's users, nothing else
I'm importing it like so:
import {Roles} from "shared";
but have tried numerous other ways as well.
I'm exporting it from the shared index.ts like so
import Roles from "./models/Roles";
export type {
// all of my interfaces
};
export { Roles }
All of my interfaces are usable, so I don't understand. What the hell is going on here?
Well, it turns out that these errors are all cause by create-react-app's default webpack.config.js. If you navigate to code node_modules/react-scripts/config/webpack.config.js you fill find a line include: paths.appSrc which basically limits Babel to the src/ folder of the react app itself.
That means, if you've yarn linked a folder outside of it, Babel will not transpile it to normal JS, and thus React cannot use it.
There are two hacky solutions, but I would like a better one.
Manually (or via a build script) delete the include: paths.appSrc line from react-scripts every time you install a node module
Make a script that copies the external directory into your React src directory every time the external directory is modified.
I really wish there were an official way around this...
Based on #foxtrotuniform6969's answer, i created a #cracro/craco configuration that gets rid of the misbehaving setting by itself.
module.exports = {
webpack: {
configure: (webpackConfig) => ({
...webpackConfig,
module: {
...webpackConfig.module,
rules: webpackConfig.module.rules.map((rule) => {
if (!rule.oneOf) return rule;
return {
...rule,
oneOf: rule.oneOf.map((ruleObject) => {
if (
!new RegExp(ruleObject.test).test('.ts') ||
!ruleObject.include
)
return ruleObject;
return { ...ruleObject, include: undefined };
}),
};
}),
},
}),
},
};
https://gist.github.com/PhilippMolitor/00f427d12a9c5bca84309058d88846b7
It is possible to automatically remove the include path setting mentioned in the other answer using react-app-rewired.
The following config-overrides.js works for react-scripts:4.0.3 and causes babel to also transpile files in node-modules.
// config-overrides.js
module.exports = function override(config, env) {
// This line might break with other react-script versions
delete config.module.rules[1].oneOf[2].include
return config
}
The other answers to this question suggest removing the include in react-scripts' webpack.config (either with craco or react-app-rewired). I found this worked with yarn start, but when I made a production build with yarn build I got the error Uncaught ReferenceError: exports is not defined at runtime.
Instead of removing the include, I had to add the other project's src in addition to the existing src directory.
Here's my config-overrides.js to be used with react-app-rewired.
For react-scripts 4:
const path = require("path");
module.exports = function override(config) {
// See https://stackoverflow.com/questions/65893787/create-react-app-with-typescript-and-npm-link-enums-causing-module-parse-failed.
config.module.rules[1].oneOf[2].include = [
path.join(__dirname, './src'),
path.join(__dirname, '../backend/src')
];
return config
}
For react-scripts 5:
const path = require("path");
module.exports = function override(config) {
// See https://stackoverflow.com/questions/65893787/create-react-app-with-typescript-and-npm-link-enums-causing-module-parse-failed.
config.module.rules[1].oneOf[3].include = [
path.join(__dirname, './src'),
path.join(__dirname, '../backend/src')
];
return config
}
My craco config, does the same thing as Phil Mo's version as far as I can tell but is easier to understand
module.exports = {
webpack: {
configure: (webpackConfig) => {
webpackConfig.module.rules[0].oneOf.find(
({ test: t }) =>
t != null &&
!Array.isArray(t) &&
t.toString().includes('ts')
).include = undefined
return webpackConfig
}
}
}
I am having some trouble getting process.env.NODE_ENV set in webpack production build.
I am setting this via
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
In my app code this is working fine I have:
console.log(process.env.NODE_ENV);
which gets converted to
console.log("production");
in the compiled output from the build.
However I am getting errors from redux that this has not been set.
in the output I have this code
if (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
(0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
}
and process.env is an empty object. So it looks as though webpack is not injecting this correctly. The function that contains the redux check starts like this:
/* 152 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {
I'm not sure what I'm missing here but looks like I'm not getting the optimised build version of redux and maybe some other dependencies inn my build because of this error.
I am usually splitting vendor code and app code into separate files during production build and uglifing but I have run this test outputting to a single file and without the minification just to test this issue
I have the following gulp task in my gulpfile.js:
gulp.task('build-scripts', function () {
var b = browserify({ debug: false });
b.transform(reactify);
b.transform(envify({
_: 'purge',
NODE_ENV: 'production'
}));
b.add('./src/scripts/index.js');
return b.bundle()
.pipe(source('./www/scripts/dist/bundle.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('.'))
});
The task completes with status 0 and the React transform happens, but in bundle.js I still see:
if (process.env.NODE_ENV !== 'production') {
Wasn't this supposed to go away with the envify transform?
Am I doing something wrong here?
I have done some digging, but all the solutions I can find are os x / linux specific (I'm on a windows machine).
EDIT: I am running the gulp build from within visual studio's Task Runner Explorer.
The doc says:
By default, environment variables that are not defined will be left untouched.
https://github.com/hughsk/envify#purging-processenv
Have you tried defining it before running that? i.e.
process.env.NODE_ENV = 'production';