require is called earlier as import statement - browserify

I've got a module m1 that needs to be initialized before I can import a module m2:
import * as m1 from 'm1';
m1.init(...)
import * as m2 from 'm2';
I updated browserify and switched from 6to5ify to babelify transformer. Afterwards, require calls in my bundle got moved to the top:
...
var _m1 = require('./m1');
var m1 = _interopRequireWildcard(_m1);
var _m2 = require('./m2');
var m2 = _interopRequireWildcard(_m2);
m1.init('init value');
...
Why are require calls moved to the top? Can I use ES6 module import syntax to import m2 after m1.init is called? I can use require directly
import * as m1 from 'm1';
m1.init(...)
const m2 = require('m2');
and I get
var _m1 = require('./m1');
var m1 = _interopRequireWildcard(_m1);
m1.init('init value');
var m2 = require('./m2');
but that seems like a hack to me.

Imports should be thought of as hoisted values in ES6. They are always at the top of the module. You are currently relying on an implicit dependency. If m2 relies on m1 not only being loaded, but also being initialized, then you should have a module that explicitly returns an initialized version of m1, then it should be depending on that explicitly or via import ordering if you can't directly modify m2, e.g.
init-m1.js
import * as m1 from 'm1';
m1.init(...)
export default m1;
init-m2.js
import m1 from './init-m1';
import * as m2 from 'm2';

Can I use ES6 module import syntax to import m2 after m1.init is called?
Irrespectively how Babel transpiles this code, the answer is: no. The spec dictates that all dependencies are evaluated before the module itself is evaluated (§15.2.1.16.5).
That means that import declarations are not evaluated when engine actually executes the code. They are statically analyzed and this information is somehow added to the module, so that the dependencies can be evaluated before the module itself is evaluated.
Even if you found a transpiler that would do what you want, it would not be spec compliant and your code could potentially break in the future.

Related

Background importing of slow python module

I have a python module (odoo.py) that creates a connection with an Odoo instance.
import odoorpc
from .env import ENV
ODOO = odoorpc.ODOO(ENV["ODOO_HOST"], port=ENV["ODOO_PORT"])
ODOO.login(db=ENV["ODOO_DB"], login=ENV["ODOO_USR"], password=ENV["ODOO_PWD"])
ODOO constant is imported by several modules containing Mongoengine classes to perform operations on the Odoo server. Here is an example:
from mongoengine import *
from .odoo import ODOO
class Category(DynamicDocument):
name = StringField(required=True)
odoo_id = StringField()
def publish(self):
_model = ODOO.env["product.category"]
self.odoo_id = _model.create({"name": self.name})
self.save()
Problem is that importing odoo.py takes about 10 seconds during application startup and it's REALLY annoying in development.
Let's consider this pseudo main.py:
import sys
from .category import Category
cat = Category(name=sys.argv[1])
if not 'test' in cat.name:
cat.publish()
In this example if sys.argv[1] contains the string 'test' then ODOO constant will never be used and waiting for its import would be totally useless.
Is there a way to "background" importing of odoo.py and wait for it only when ODOO constant is actually needed?

BigQueryCheckAsyncOperator in airflow does not exist

I am trying to use async operators for bigquery; however,
from airflow.providers.google.cloud.operators.bigquery import BigQueryCheckAsyncOperator
gives the error:
ImportError: cannot import name 'BigQueryCheckOperatorAsync' from 'airflow.providers.google.cloud.operators.bigquery'
The documentation in https://airflow.apache.org/docs/apache-airflow-providers-google/stable/operators/cloud/bigquery.html mentions that BigQueryCheckAsyncOperator exists.
I am using airflow 2.4.
How to import it?
The operator you are trying to import was never released.
It was added in PR and removed in PR both were part of Google provider 8.4.0 release thus overall the BigQueryCheckAsyncOperator class was never part of the release.
You can use defer mode in the existed class BigQueryCheckOperator by setting the deferrable parameter to True.

Javalin Migration from 3 to 4

We are migrating the Javalin from 3 to 4 in our current kotlin project. the dynamicGzip has been deprecated and replaced with compression strategy.
The pom.xml part will look like below.
<properties>
<javalin.version>4.1.1</javalin.version>
<jackson.version>2.13.0</jackson.version>
</properties>
The code part of kotlin is as follows
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.*
import io.javalin.http.BadRequestResponse
import io.javalin.http.NotFoundResponse
import io.javalin.http.staticfiles.Location
import io.javalin.plugin.json.JavalinJackson
import io.javalin.core.compression.*
val app = Javalin.create { config ->
config.defaultContentType = "application/json"
config.enableWebjars()
config.addStaticFiles("", Location.CLASSPATH)
config.enableCorsForAllgOrigins()
//it.dynamicGzip = true // deprecated method which was used in 3.12.0
config.compressionStrategy(Gzip(6))
}
We are using the migrating document from this link
https://javalin.io/migration-guide-javalin-3-to-4
When we try to build the project in intelij Idea with this change, ended with the below error.
D:\app\src\main\kotlin\app\app.kt:78:40
Kotlin: Unresolved reference: Gzip
What is that we are missing here?
Also it will be helpfull if config.addStaticFiles syntax is also added wrt javalin 4
Compression
The compressionStrategy method of the JavalinConfig class takes two parameters:
void compressionStrategy(Brotli brotli, Gzip gzip)
See the JavaDoc here.
The related classes are found in Javalin here:
import io.javalin.core.compression.Brotli;
import io.javalin.core.compression.Gzip;
So, you can do something like this in your set-up (my example is Java not Kotlin):
// my Java example:
config.compressionStrategy(new Brotli(6), new Gzip(6));
Static Files
You can use something like this (again, a Java example not Kotlin):
// my Java example:
config.addStaticFiles("/public", Location.CLASSPATH);
In this case, because I want my files to be on the runtime classpath, I have also created a public directory in my application's resources directory. Your specific implementation may differ.
You can also use Location.EXTERNAL if you prefer, to place the files somewhere else in your filesystem (outside the application).
Note also there is a small typo in config.enableCorsForAllgOrigins(). It should be:
config.enableCorsForAllOrigins()

Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle

I am receiving this warning message in my chrome console for my react-native project. Do you have any idea why I am getting this?
This is the complete message:
Require cycle: node_modules/react-native-radio-buttons/lib/index.js ->
node_modules/react-native-radio-buttons/lib/segmented-controls.js ->
node_modules/react-native-radio-buttons/lib/index.js
Require cycles are allowed, but can result in uninitialized values.
Consider refactoring to remove the need for a cycle.
I appreciate any suggestions.
Thanks
TL;DR: You import module A into module B and module B into module A resulting in a cycle A → B → A → B → A ..., which can result in errors. Resolve that by restructuring your modules, so that the cycle breaks.
Detailed Answer
In javascript if you import different modules into other modules all this importing generates a dependency tree:
root_module
┌───────────┴───────────┐
sub_module_A sub_module_B
┌────────┴────────┐
sub_module_C sub_module_D
When you run your code, all modules will be evaluated from bottom to top or from leaves to the trunk, so that for example if you import modules C and D into module B all exports of C and D are already evaluated and not undefined anymore. If module B would be evaluated before C and D, module B would be not working, because all exports from C and D would be undefined, since they have not been evaluated yet.
Still, it can be possible to form cycles in your dependency tree (this is what you got a warning for):
root_module
┌───────────┴───────────┐
sub_module_A sub_module_B
↑ ↓
sub_module_C
Problem: Let's say the evaluation starts now with module C. Since it imports something from module B and it has not been evaluated yet, module C is not working correctly. All imported stuff from B is undefined. This actually is not that bad, since in the end module C is evaluated once again when everything else has been evaluated, so that also C is working. The same goes if evaluation starts with module B.
BUT: If your code relies on a working module C from the very beginning, this will result in very hard to find errors. Therefore you get this error.
How to solve: In your case the warning also gives a detailed explanation, where the cycle emerges. You import native-radio-buttons/lib/segmented-controls.js in node_modules/react-native-radio-buttons/lib/index.js and node_modules/react-native-radio-buttons/lib/index.js in native-radio-buttons/lib/segmented-controls.js. It seems like the cycle is placed inside some of your node modules. In this case there is unfortunately no way you could solve that by yourself.
If the cycle is in your own code, you have to extract some exports into a third module / file, from which you import the code into both modules previously forming the cycle.
You are probably importing something from "file A" into "file B", then importing something again from "file B" into "file A" .
Examine all the imports from both the files and see if there's any such cycle.
To prevent from having to write multiple lines of
import SomeComponent from "../components"
import AnotherComponent from "../components"
import AndAnotherComponent from "../components"
import AndOneMoreComponent from "../components"
I created a comp.js file where I could import the components as they are created and export them as modules.
All components are then able to be reached from one place.
So you can then have something like this in some place...
import { SomeComponent, AnotherComponent, AndAnotherComponent, AndOneMoreComponent} from './comp'
Now what happens in the renderer for example when SomeComponent is rendered....
import * as React from "react";
import { AnotherComponent} from '../comps';
import { View, Text } from "react-native";
function SomeComponent() {
return (
<>
<AnotherComponent />
<View><Text>EXAMPLE OF SOMECOMPONENT</Text></View>
</>
)
}
export default SomeComponent;
In the example, SomeComponent could be called in the main App, and when it renders it also asks for a component from the comp.js
This is what triggers the Require cycle warning because a module that was imported from one place, is then rendering and asking to import another module from the same place it was rendered from.
What are your thoughts on this, should I revert back to using single import statements or do you think there is a danger in using the module export as it is currently setup?
I my case, I have sold the same problem in react-native navgiation.
What I did ?
Already I was using react-navigation like below
export const containerRef = createRef();
function App(){
return (
<NavigationContainer ref={containerRef}>
....
<NavigationContainer>
);
}
and then I was consuming it like:
import {containerRef} from 'filename';
onPress = ()=> containerRef.current.navigate('Chat');
But I updated like below and warning has gone.
function App(){
return (
<NavigationContainer> // removed ref
....
<NavigationContainer>
);
}
and then I was consuming it like:
import { useNavigation } from '#react-navigation/native';
onPress = ()=> useNavigation.navigate('Chat');
This occurs if your code contains cyclic dependencies. If these dependencies exist within your own libraries, you can easily fix them. But if this is happening in 3rd party libraries, you can't do much except waiting for the developers to fix these.
Another reason might be this: Some imports cause this warning if they're done through the require keyword. Replace these with import statements and you might be good to go. For example,
const abc = require("example"); // Don't use this syntax
import abc from "example" // Use this syntax instead
NOTE: This might vary from project to project. For a detailed understanding of require vs import, refer to this link.
In my case the warning was like this;
Require cycle: src\views\TeamVerification.js -> src\components\TeamVerificationListItem.js ->
src\views\TeamVerification.js Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
As it indicates, TeamVerification was importing TeamVerificationListItem and TeamVerificationListItem was also importing TeamVerification. It was an unused import but after I remove it the warning gone.
As others have already mentioned, for your own packages
Move things required within two modules by each other into a third module
Avoid imports from barrel-files (index.ts/js) or aliases (#mycompany/my-module) if you are within the same "my-module"
What others have not mentioned (and which seems to be the problem for OP), for packages not within your responsibility (eg node_modules from NPM), the only thing you can do is
Disable the warning. It will still show up in metro console, but no more yellow warning snackbar: import { LogBox } from 'react-native'; LogBox.ignoreLogs(['Require cycle: node_modules/']); You can place the code in App.tsx, for example.
Modify the package contents of the node_modules itself and patch the package contents after every npm install via patch-package => I think this is an overkill if the circular imports don't produce actual errors
You should use the Relation wrapper type in relation properties in ES Modules projects to avoid circular dependency issues, just click here: https://typeorm.io/#relations-in-esm-projects
In my case, i had the same warning after the installation of a 'package'
and in their documentation, it was import SomeFunc from 'package'
and instantly the warning showed up
Require cycles are allowed but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
but as soon as I destructure the SomeFunc there was no more warning
import {SomeFunc} from 'package'
please look at the destructuring
I used react-native-maps in my project and I got the same error.
Just upgraded from 0.27.1 -> 0.28.0.
I can confirm that this issue is fixed.
Thank you
if use NavigationContainer in #react-navigation/native
import {createRef} from 'react';
<NavigationContainer ref={createRef()}>
Please check whether you have imported same details within that file.
(i.e)
your file being as a actions/meals.js and you have added the line in the same file like
import { Something } from './actions/meals.js'

aurelia-cli error when using buffer.js - global undefined

Created a new project using the aurelia-cli - SystemJS bundler option.
installed htmlparser2 module from npm which has buffer.js as a dependency.
getting the following error when attempting to import htmlparser2:
bluebird.core.js:3434 Error: global is not defined
Evaluating http://localhost:9000/buffer/index
upon inspecting vendor-bundle -> this is the line that creates the error:
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
found a similar issue with angualar-cli where the solution was to manually turn on node global
Node global is turned off. It works fine if I manually turn it on again.
The question is how to do this using the aurelia-cli? Any suggestions?
larger code snippet from vendor-bundle
define('buffer/index',['require','exports','module','base64-js','ieee754','isarray'],function (require, exports, module) {/*!
* The buffer module from node.js, for the browser.
*
* #author Feross Aboukhadijeh <feross#feross.org> <http://feross.org>
* #license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
I believe you are using cli built-in bundler (I wrote it), not webpack.
Yes, nodejs global var global is currently not supported. Also nodejs global vars process and Buffer have similar issues.
The cli doc has a patch to support process and Buffer.
import process from 'process';
window.process = process;
import {Buffer} from 'buffer';
window.Buffer = Buffer;
You can try to add one more patch for global.
window.global = window;
Ok why cli has the issue
cli's tracing algorithm uses rjs (requirejs optimizer) parser, it's bit old, does not detect global vars (technically it does not do variable scope analysis).
I have another WIP bundler called dumber which solved the limitation with a new parser which detects global vars. It automatically patch nodejs global vars at module level based on need.
In long term, we will drop the code for cli built-in bundler, then wrap dumber and make it backward compatible.