React + webpack: 'process.env' is undefined - javascript

I'm trying to run the hot dev server on our site with webpack; the site uses ReactJS, which has this code in it:
if (\"production\" !== process.env.NODE_ENV) // etc
When not running hot-swap it's fine, but with the hot-swap, it gets run, resulting in the error:
TypeError: process.env is undefined
The code looks like this:
The project is modelled after https://github.com/webpack/react-starter which does work; so the question is; what error have I made in the config file and/or how do I go about looking for the error when the 'production' compilation works just fine?
I've posted the gist of the webpack config file.

In your webpack config, there are two options that can affect process.env:
When you specify config.target (see config.target)
When you define the process.env variable via DefinePlugin
Looking at your code, it looks like process.env might be undefined when both options.prerender and options.minimize are false.
You could fix this by always using an environment that defines process.env (ex: node), or by using DefinePlugin to assign a default value to the variable yourself.

This is the simplest way:
new webpack.EnvironmentPlugin( { ...process.env } )
Add that to your list of webpack plugins.

Related

Does webpack remove this type of code automatically?

This is a good helper for development mode, but does this code get removed from bundles or is a particular plugin needed to remove it? Seems like it would have to be removed since process is not available in the browser. What setting causes this to happen?
The webpack docs aren't really all that clear about what these options do, just giving vague references:
https://webpack.js.org/concepts/targets/
and
https://webpack.js.org/concepts/output/
if (process.env.NODE_ENV !== 'production') {
if (typeof nextValue === 'undefined') {
console.info(next);
throw new Error('React Table: A reducer hook ☝️ just returned undefined! This is not allowed.');
}
}
process.env.NODE_ENV is actually available in the browser because Webpack creates the process variable as a global in code that is output. It is controlled via the Webpack configuration mode.
You can set the mode in your config or the command line. If you use enivornment based Webpack configs (ie. webpack.dev.js, webpack.prod.js) they will automatically set the mode.
webpack --mode=production

Imported functions are not in scope within Firefox debugging console

I'm developing a project in React and I'm importing functions from lodash and Immutable.js.
import isEqual from 'lodash/isEqual
const {List, Set, Map, is} = require('immutable')
When I'm debugging my code these functions work in the script but if I stop at a breakpoint and attempt to use them in Firefox's debugging console, I get a ReferenceError telling me they are not defined.
Do I need to explicitly import them in the console? Or am I importing them incorrectly?
I would recommend you to use Webpack to build your source files.
Once you are development mode please set your NODE_ENV to development.
You can also add mode: 'development' into your webpack.config.js file.
After you can use debugger; in anywhere in your code and when you run your code in the browser you can debug from that line.
For further reading: https://webpack.js.org/guides/development/#using-source-maps
The variable names are not preserved during transpilation/minification/uglification process. Therefore you have to look for the changed variable name, to access them in the console.
You can find an in detail approach how to find out the real variable name here

What's the proper way of setting environment variable in Netlify functions?

What's the proper way of setting environment variables in netlify? I would like to be able to set different values for the variables depending on the environment.
Pseudo code:
let host;
if (process.env.GATSBY_CUSTOM_CONTEXT === 'production') {
host = process.env.PRODUCTION_HOST
} else if (process.env.GATSBY_CUSTOM_CONTEXT === 'development') {
host = process.env.DEVELOPMENT_HOST
}
I have tried passing env variable thru CLI, like GATSBY_CUSTOM_CONTEXT=production gatsby build and I also tried using same command with cross-env.
My other attempt used netlify.toml:
[build]
base = "/"
publish = "public"
command = "yarn build"
functions = "src/functions"
[context.production]
[context.production.environment]
GATSBY_CUSTOM_CONTEXT = "production"
All of these options worked with netlify dev locally, but in production GATSBY_CUSTOM_CONTEXT is always undefined.
The reason you can't resolve the environment variables in your Netlify functions is because as of the time of your question, Netlify does not transfer the environment variables from the netlify.toml file.
You must put them into the admin panel in your site settings in the app.netlify.com dashboard.
Unfortunately, what you're looking to doesn't seem to be currently supported. Though they provide an alternative approach.
I found this snippet on their docs:
CALLING ENVIRONMENT VARIABLES
Using environment variables directly as
values ($VARIABLENAME) in your netlify.toml file is not supported.
However, the following workflow can be used to substitute values in
the file with environment variable values, assuming you are only
trying to change headers or redirects. The rest of the file is read
BEFORE your build — but those sections are read AFTER the build
process.
Add a placeholder like HEADER_PLACEHOLDER somewhere in the netlify.toml redirects or headers sections.
Create an environment variable, for example PROD_API_LOCATION, with the desired value. You can create environment variables in the
toml file or in our UI. You might use the latter to keep sensitive
values out of your repository.
Prepend a replacement command to your build command. Here’s an example for a site using yarn build to build: sed -i
s/HEADER_PLACEHOLDER/${PROD_API_LOCATION}/g netlify.toml && yarn build
Taken from here: https://www.netlify.com/docs/netlify-toml-reference/

Using require with root path variable in VSCode

I am using global variable __root with path of my root app directory then I am using require to load code from other files.
const Parser = require(__root + '/parsers/Parser')
The issue is that vscode does not understand what is happening:
Intellisense does not work
Object type is shown as any (if path is correct vscode grabs right type)
What are the options to solve this? Can you share your practices to resolve this issue?
VS Code's intellisense cannot understand dynamic import paths like root + '/path'. There are no workarounds for this, nor are the plans to address this in the immediate future.
However, with static require import paths, you can configure how VS Code resolves the imports by configuring a jsconfig.json. The two options you probably want are baseUrl and paths
Setting up a jsconfig.json will not change the runtime behavior of your code, only how VS Code IntelliSense handles your project. You can use a jsconfig.json along with webpack aliases

Node.js: How to setup different variables for prod and staging

I'm using Express and I need to use different credentials for each server (staging and production).
I could setup the variables in the server.coffee file but then I'd need to access those variables in different files.
server.coffee:
app.configure 'production', () ->
app.use express.errorHandler()
What's the solution? Setup the variables and then export them?
./config.js
var development = {
appAddress : '127.0.0.1:3000',
socketPort : 4000,
socketHost : '127.0.0.1',
env : global.process.env.NODE_ENV || 'development'
};
var production = {
appAddress : 'someDomain.com',
socketPort : 4000,
socketHost : '8.8.8.8',
env : global.process.env.NODE_ENV || 'production'
};
exports.Config = global.process.env.NODE_ENV === 'production' ? production : development;
./app.js
var cfg = require('./config').Config;
if (cfg.something) { // switch on environment
// your logic
}
This might be a good place to use npm-config.
When running scripts (see npm-scripts(7)) the package.json "config" keys are overwritten in the environment if there is a config param of <name>[#<version>]:<key>
I would not use them for every type of variable configuration setting, but I think it's a good solution for simple cases like URLs and ports because:
You put them directly into package.json.
In addition, you can specify them on the command line or as ENV variables.
Anything run through npm can refer to them (e.g., scripts).
You can set them per-user with `npm config set foo:port 80
The one caveat is that the config parameter in your package.json is only automatically exported into the environment when you run your code through npm. So, if you just run it with node, like, node ./myapp.js, then you can't expect that process.env.npm_package_config_foo will contain your value. However, you can always var pkg = require('./package.json'); and access the values at pkg.config.
Because it might not be immediately obvious, I'd also add that the npm_package_config environment variables do not bubble up to apps that depend on your npm package. So, if your depended-on package refers to process.env.npm_package_config_foo, then the dependent package would have to define that in its own package.json. I guess since it's an "npm_package_config" it wouldn't make sense to push them all the way up the tree.
So, how would I use one npm config variable and have it work all the way up the tree, in both the base package and the packages that depend on it? It's actually a little confusing, and I had to figure this out through trial and error.
Let's say you have a package connector and package client. client depends on connector and you want to specify a config parameter for connector that can be used or overwritten in client. If you use process.env.npm_package_config.port in your connector module, then when it's depended on in client module, then that variable won't be exported and it will end up as undefined.
However, if you instead use process.env.npm_config_connector_port (notice the first one starts with npm_package_config and the other with npm_config_packagename), then you can at least set that in your .npmrc using npm config set connector:port 80 and it will be "namespaced" as process.env.npm__config_connector_port everywhere that you run npm, including scripts that you run in client that depend on connector, and you'll always be able to overwrite it on the command line, in your ENV, or in your .npmrc. You just have to keep in mind that, as with any environment variable, it may not always be set. So, I would use the default operator with the process.env.npm_config_connector_port as the first (preferred) value:
var port = process.env.npm_config_connector_port || sane_default
Here, sane_default could be populated from one of the other recommended methods. Personally, I like keeping configuration data like these in JSON files at the very least, and package.json seems like the best JSON file to put them in. Store them in data instead of code and then you can easily use the static JSON in-line, generate them dynamically, or pull them from the filesystem, URLs or databases.
I have uploaded an implementation into https://github.com/qiangyu/nodejsconfig. I believe it will satisfy your needs. Basically, you only need to provide one configuration file:
dev.appAddress = '127.0.0.1:3000';
prod.appAddress = 'someDomain.com';
Then, you use following code to read the appAddress in prod environments:
var xnconfig = require('nodejsconfig');
var fs = require('fs');
var data = fs.readFileSync(__dirname+"/config.properties", "UTF8");
// assume we will be using environment "prod"
var config = xnconfig.parse("prod", data);
// the output will be someDomain.com
console.log(config.getConfig("appAddress"));
If you don't want the logic for determining which config to use in each file (which would look pretty ugly), you'll have to export it somewhere.
What I would suggest: Have a config.json file containing the different configs. The main file requires it and does something like config.default = config.(condition ? 'production':'development'). In all other files, you can now just do require('./config').default.
I have an app which uses three different methods of declaring config variables (uris, api keys, credentials, etc.) depending upon the environment (production = environment variables; staging = command line args; local = config files.)
I wrote a little "config" module to handle merging all of these options into one object that I can use in my app and uploaded it as a gist: https://gist.github.com/1616583
It might not be the best implementation, but it's been working pretty well so far :).

Categories

Resources