We have a Laravel 8 application with Laravel Mix 6.0.49 and a React frontend. The application runs inside a docker container in production and development. Up until now, the frontend was compiled outside the docker container for some reason, but since we are moving to a fully dockerized environment, we are required to call the frontend scripts from inside the container. This all works fine, except for an environment variable we are setting in package.json, which allows us to pass the version of the app as a mix variable. Here is the current setup:
// package.json
"version": "0.1.1",
"scripts": {
...
"watch": "cross-env APP_VERSION=$(node -pe 'require(\"./package.json\").version') mix watch",
...
// .env
...
MIX_APP_VERSION="${APP_VERSION}"
...
// MyComponent.jsx
...
<div>version {process.env.MIX_APP_VERSION}</div>
...
The environment variable worked fine when the watch script was called outside the docker container.
Has anyone any idea of why it suddenly does not work anymore? I'm open to other ways of approaching this too.
I fixed this issue in the end by removing the variable related stuff from package.json including the cross-env dependency and setting the environment variable through the webpack config instead (webpack.mix.js)
...
.webpackConfig({
plugins: [
new webpack.DefinePlugin({
'process.env.APP_VERSION': JSON.stringify(
process.env.npm_package_version,
),
}),
],
})
Related
Is it possible to set environment variables in the manifest.json file of a Chrome Extension?
Like wOxxOm said, I used webpack to proccess manifest.json.
In my case, I needed to set version automatically on manifest file.
I added to webpack script:
plugins: [
new CopyWebpackPlugin([
{
from: "public/manifest.json",
to: "manifest.json",
transform(content, path) {
return modify(content)
}
}
]),
]
And the modify function replaces version on file for the parameter:
function modify(buffer) {
var manifest = JSON.parse(buffer.toString());
let argv = process.argv[2];
if (argv) manifest.version = argv.split("=")[1];
let manifest_JSON = JSON.stringify(manifest, null, 2);
return manifest_JSON;
}
So, I build like "yarn build --version=x.x" and webpack do what I need.
PS: if you're going to use this, remember to change:
the manifest.json directory, if necessary;
the value in the modify function, in my case it was version
As the OP has mentioned in her answer, using the copy-webpack-plugin in the webpack.config.js file is the way to go if you're building your Chrome Extension with React. However, if your React app is based on create-react-app, directly editing the webpack.config.js file (which is located in node_modules/react-scripts/config) is not recommended.
In such a case, use craco, which is an npm package that can be used to customize an app based on create-react-app. Here's how you do it:
Install craco into your project using npm i #craco/craco.
Install copy-webpack-plugin as a dev-dependency in your project using npm i --save-dev copy-webpack-plugin.
Let's suppose we're creating a development and a production build of our Chrome Extension. Let's also suppose we've already assigned "version": "0.1.0" in our Chrome Extension's manifest.json. Depending on the build type, we'd like to assign accordingly the version_name field in our Chrome Extension's manifest.json, e.g., "version_name": "0.1.0 dev" for development and "version_name": "0.1.0" for production. In your React app's package.json, introduce two fields (the script names can be whatever you wish) as follows:
"scripts": {
...
"build-dev": "CRX_ENV=dev craco build", // or "set CRX_ENV=dev&& craco build" in the case of Windows
"build-prod": "CRX_ENV=prod craco build", // or "set CRX_ENV=prod&& craco build" in the case of Windows
...
}
Create a new file called craco.config.js in the root of your project. As per your need, do something similar to the following in the craco.config.js file:
const CopyPlugin = require("copy-webpack-plugin")
module.exports = {
webpack: {
plugins: [
new CopyPlugin({
patterns: [
{
from: "public/manifest.json",
to: "manifest.json",
transform(content, path) {
return modifyManifest(content)
},
},
],
}),
],
},
}
function modifyManifest(buffer) {
const manifest = JSON.parse(buffer.toString())
if (process.env.CRX_ENV === "dev") {
manifest.version_name = `${manifest.version} dev`
} else if (process.env.CRX_ENV === "prod") {
manifest.version_name = `${manifest.version}`
}
const manifestJson = JSON.stringify(manifest, null, 2)
return manifestJson
}
Run npm run build-dev. It will create a folder called build in your project root. This build folder is your unpacked Chrome Extension, which you can load into Chrome using the "Load unpacked" button on the chrome://extensions page. Once loaded, you should be able to see 0.1.0 dev as the version name of your Chrome Extension.
Delete the build folder created from the previous step and run npm run build-prod, and repeat the same steps. You should be able to see 0.1.0 as the version name of your Chrome Extension on the chrome://extensions page.
I have finished building a simple resume/portfolio website using GatsbyJS in development.
I am using three environment variables (env var) to store my social media links (email/mobile/linkedin), as I will be displaying them in my React frontend.
I am storing all my env var(s) inside .env.development file in the root.
I am using the env-cmd package for accessing the env var(s).
In my package.json file, I modified the develop script to the following:
"develop": "env-cmd -f .env.development gatsby develop",
^ With that, I am able to access the environmental variables in my front end.
e.g.
<div>{process.env.EMAIL}</div>
I am using Netlify for deployment, and I tried putting env vars within Netlify after building it, but it didn't work.
So I think the problem is stems from the env vars being only accessible during development, so my question is, how do I make sure they are accessible after deploying the website (in production)?
Thank you!
Your variables are available on build/compile. In order to use them on the client you should create a .env.production (I was using dotenv) when building, you can place it for instance on top of gatsby-config.js
Example:
const fs = require('fs')
const VARS = [
'TEST'
]
function createProdEnv () {
var content = ''
VARS.map(varName => {
content += varName + '=' + process.env[varName] + '\n'
})
fs.writeFileSync('./.env.production', content)
}
module.exports = createProdEnv
And call it from gatsby-config.js
createProdEnv()
So after reading the docs again: https://www.gatsbyjs.org/docs/environment-variables/
I simply prefixed all my env var with GATSBY_ in my .env file, just like REACT_ in create-react-app. I didn't use .env.development nor .env.production files, simply just a .env file.
Then in Netlify I input the same env var, and it worked!
I am not sure if this is the optimal solution, so if there is a better way to do this, please share!
I need to proxy requests from a Create React App to a separate API server, and set that server dynamically or with environment variables. I followed configuring proxy manually, however I am using TypeScript. react-scripts-ts does not seem to load src/setupProxy.js even after updating to latest version (v3.1.0). I got it working with vanilla javascript, but am unable to get it to work with TypeScript. Has anyone gotten setupProxy to work with React TypeScript?
After code diving, it appears the typescript create-react-app has not yet incorporated custom proxy functionality. I had to update two files:
https://github.com/samuelstevens9/create-react-app/blob/next/packages/react-scripts/config/paths.js
Added proxySetup: resolveApp('src/setupProxy.js'), to each module.exports, the last (3rd) being proxySetup: resolveOwn('template/src/setupProxy.js'),
https://github.com/samuelstevens9/create-react-app/blob/next/packages/react-scripts/config/webpackDevServer.config.js
Added const fs = require('fs'); below line 15 const paths = require('./paths'); and added
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
inside the before(app) { ... } function towards the end of the file.
I am working on creating a pull request to the main repo, but it looks like the v3.1.0 files are different from the most up to date ones on the next branch. For now I use a patch script I made since we are using a lerna monorepo that updates all necessary packages:
#!/bin/bash
CONFIG_PATHS_URL="https://raw.githubusercontent.com/samuelstevens9/create-react-app/next/packages/react-scripts/config/paths.js"
CONFIG_WEBPACKDEVSERVER_URL="https://raw.githubusercontent.com/samuelstevens9/create-react-app/next/packages/react-scripts/config/webpackDevServer.config.js"
SETUPPROXY_URL="https://gist.githubusercontent.com/samuelstevens9/5872e72ac915dfc1a8ae2fdcef323899/raw/7f2c76d42bc0915026379dfc7884cb1bd97f56bb/setupProxy.js"
for f in packages/*; do
if [ -d ${f} ]; then
echo $f
# Will not run if no directories are available
NODE_MODULES_CONFIG_DIR=$f/node_modules/react-scripts-ts/config
if [ -d "$NODE_MODULES_CONFIG_DIR" ]; then
# Control will enter here if $DIRECTORY exists.
echo $NODE_MODULES_CONFIG_DIR
curl -o $NODE_MODULES_CONFIG_DIR/paths.js $CONFIG_PATHS_URL
curl -o $NODE_MODULES_CONFIG_DIR/webpackDevServer.config.js $CONFIG_WEBPACKDEVSERVER_URL
curl -o $f/src/setupProxy.js $SETUPPROXY_URL
fi
fi
done
And updates the setupProxy.js file in each package as well. Hope this helps.
Now CRA supports Typescript but I couldn't make setupProxy.js to work.
My mistake was super dumb. setupProxy was outside src/ folder.
So, make sure that you create setupProxy inside the folder src
src/setupProxy.js
My code looks like this:
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: process.env.REACT_APP_API_URI,
changeOrigin: true,
})
)
}
Also, make sure that your env configuration is working.
You need to install the package env-cmd and replace
"start": "react-scripts start",
for
"start": "env-cmd -f .env.development.local react-scripts start",
i want to add custom environment variables when using react-boilerplate.
In my DEV environment i will point the API to my localhost backend, but in PROD environment i will point it to the PROD backend.
I have tried using dotenv-webpack and react-scripts but still won't work.
for the dotenv-webpack i have add the plugins code below dllPlugin.
dllPlugin: {
...
},
plugins: [
new Dotenv({
path: './.env', // Path to .env file (this is the default)
systemvars: true,
safe: true // load .env.example (defaults to "false" which does not use dotenv-safe)
})
]
...
anyone have succeed applying this feature ? please throw some enlightment..
I have successfully implement the dotenv-webpack to the react-boilerplate. Before I misplaced the config at /config.js. Now i put in webpack/webpack.base.babel.js.
I have a Angular application that uses Webpack as module bundler. In my package.json, I have the following scripts:
"scripts": {
"start": "webpack",
"start-in-war": "??????"
}
Also, this is the output portion of my webpack.config.js
output: {
path: __dirname + "/dist/",
filename: "app.js"
}
Since I also want this application to be packaged into a WAR file with my backend service, I need to pass that path field as parameter, so I will mantain both configurations: the default that is more development-friendly (I don't have to deploy the application anytime I make a client change) and the one I will ultimately use (that would be the "start-in-war" parameter).
How can I achieve that?
Note: The start-in-war script is not gonna be used just for production, also development.