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
Related
In a React app I have a file with imports like this:
import * as cArrayList from './ClassArrayList'
import * as mCalc1 from './moduleCalc1'
Then in the same file, I have exports like this:
export const cArrayList.ArrayList
export const mCalc1.doPreCalculationSetup
export const mCalc1.doTheCalculations
But I get a parsing error: Identifier 'cArrayList' has already been declared.
The MDN docs say in this statement:
import * as myModule from '/modules/my-module.js'
the "myModule" alias of the module object can be used as a kind of namespace when referring to the imports, to be used as so:
myModule.doAllTheAmazingThings().
So why my error?
The only items in this file are 61 import lines and 394 export lines. The whole purpose of this file is to do all the necessary imports just once, creating a namespace holding all the exports available in the project. And then make the individual exports avaiable by reference for all the other modules using them, instead of each module doing another import. This is an experment to avoid a cyclic reference (I think) that causes the program to just loop in the startup phase.
UPDATED
While going through the steps to implement this hack idea of a nameSpace file, I learned some things that made me think that this whole exercise was unnecessary. What I thought was a looping app was really a stalled splash screen with a gif. And even thought the finished hack worked, the many small changes to code that had worked fine before raised questions. And my late idea to try doing a build and run that was key. That build failed, but identified the failing code for correction. Then there was a series of small code changes to finish up.
So thanks to GIT, I was able to jump back to the point in time where I first saw this problem: a clean compile but a stalled splash screen. Now I ran a build and got this:
Failed to compile.
Failed to minify the code from this file:
./src/calculations/moduleMoneyPlanEntry.js:53:4
The code at that location was simple:
function moneyPlanEntry() {
try {
process.env.MONEYPLAN = 'development'
process.env.NODE_ENV = 'development' (A)
The left over line from previous work marked (A) was the problem. Delete that line and all is well. The build runs, and the corrected code runs with the "yarn start" command. So now I will discard my nameSpace hack and continue normally. The key lesson? Run the build once in awhile to check for lurking errors.
#CertainPerformance already said everything about what's wrong with the syntax.
The whole purpose of this file is to do all the necessary imports just once, creating a namespace holding all the exports available in the project. And then make the individual exports avaiable by reference for all the other modules using them, instead of each module doing another import.
For that, you'll want to use export * from '…'; syntax. Or export { name as alias } from '…'; in case of conflicts.
But it sounds like a really bad idea, going contrary to modularisation by putting everything in a single global namespace. You will no longer have clear dependencies between the parts of your package, but just one big mess.
This is an experiment to avoid a cyclic reference (I think) that causes the program to just loop in the startup phase.
Circular dependencies usually cause TDZ exceptions, not infinite loops.
Using const declarations in your global module will actually make these worse, you really need to use re-exports that actually alias the bindings.
To solve circular dependency issues (and don't want to refactor but keep the dependency structure), you generally need to decide which module should be the entry point to your circle, and in which order the modules should be executed, and then always strictly follow that order in any module import list.
export const <someIdentifier> will do two things:
Declare a local variable in the module scope named someIdentifier (as a const)
Export that as a named export
The error message you're getting is a bit misleading. Whether the variable is declared beforehand or not,
export const someObject.someProperty
is invalid syntax, because someObject.someProperty is not a valid identifier. For similar reasons, you can't do
const someObject.someProperty
For what you're trying to do, I'd destructure the properties from the imported object when exporting, like so:
export const {
doPreCalculationSetup,
doTheCalculations
// you can add more properties here
} = mCalc1;
Demo:
<script type="module">
const obj = { foo: 'foo' };
export const { foo } = obj;
console.log(foo);
</script>
This is just something I thought today and I didn't see a lot of information so I'm going to share this weird cases and how I personally solved them (if there's a better way please comment, but meanwhile this might help others ^^)
In a webpack bundle, every import/require you do, is managed by webpack using their internal require function. That means you cannot use anymore the original NodeJS global require if you are inside a webpack bundle.
See also: Exporting from outside webpack bundle
There's a workaround provided by webpack actually:
A variable called __non_webpack_require__ which is the original require so, in your code, you can do this:
const internalModule = require('internal/module');
// or import internalModule from 'internal/module'; in the ES6 way
const externalModule = __non_webpack_require__('external/module');
If you are using TypeScript, you can add this line in your global.d.ts file to avoid syntax errors:
declare const __non_webpack_require__: NodeRequireFunction;
Fact 1: Actually after the build, you can see how your commonly used require (webpack's) has been renamed to __webpack_require__, and that __non_webpack_require__ has been preserved as the original require.
Fact 2: Webpack also use the original require to import modules from the system (not bundled with the code), such as net, events, fs, etc.
I am working on converting a large application from JavaScript (Backbone and Angular 1) to TypeScript. When we convert a file that is used by other files we understand that we have to update the import statements in those other JavaScript files so that it imports the new TypeScript file correctly. Our syntax update in fake-file.js is as follows.
Before:
import OurService from 'our.service';
After:
import { OurService } from 'our.service';
I understand that this is an easy change but TypeScript is new to many developers and there have been problems with people missing some of these import statements or forgetting to change them all together resulting in some issues during runtime. I have looked into compiler options but I do not see any that would fix this issue but I could be misinterpreting them.
Question: Is there a way to configure the compiler (or a Visual Studio Code plugin) to throw a warning or an error to prevent this from happening?
I assume that I understood your requirement and possibly you need to adapt a linting process and consequently I would suggest the following tools (which I also use in my project):
Airbnb Javascript style guide (your import statement concern-https://github.com/airbnb/javascript#modules). These are a well-defined set of standards defined for any JS application (including ES).
ESLint. You can run ESLint from the terminal and configure it for your project that highlights warning/errors in your code. If this looks complicated, you can generate the tslint document for your entire project in the website itself. Click on rules configuration and configure the ES rules for your project. There are some import related rules too.
PS: Feel free to add your comments.
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.
I found that the source code is full of comparisons if ("production" !== "development").
For example (from https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js, line 6240):
if ("production" !== "development") {
this._checkPropTypes(
contextTypes,
maskedContext,
ReactPropTypeLocations.context
);
}
But why? The result of such checks is always the same.
They use browserify with envify.
envify will replace your environment variable checks with ordinary
strings - only the variables you use will be included, so you don't
have to worry about, say, AWS_SECRET_KEY leaking through either. [...]
By running this through a good minifier (e.g. UglifyJS2), the above
code would be stripped out completely.
This is done to enable development-only checks and logging.
If you look through the React source, you'll see if (__DEV__) checks, which get replaced with if ("production" !== process.env.NODE_ENV) by React's build process.
envify is then used to replace references to process.env.NODE_ENV in the source with its current value at the time the build process is run.
For the uncompressed development build of React (and when using the npm version, by default) process.env.NODE_ENV is set to "development", so you get the benefit of these extra checks, such as validating props passed to component against its propTypes, warning if controlled components are potentially read-only due to misconfiguration, warnings about lists of items without a key prop and all the other development-mode logging React provides for common problems such as misspelt lifecycle method and HTML attribute prop names.
For the compressed production build, process.env.NODE_ENV is set to "production", so when the build is compressed with UglifyJS, these blocks of code are detected by Ugilify's dead code elimination process as code which will never get run and are completely removed from the source.
A nice side-effect of this is that you can take advantage of if ("production" !== process.env.NODE_ENV) checks to add development-only checks and logging to your own React components and libraries, since people bundling React from npm currently (with v0.12.2 the current version at the time of writing) have to deal with this as part of their build process.