If there's a zero-dependencies function zdfun, but in a module/file foo.js that imports further dependencies, and I'm solely interested in zdfun, is it possible to import it without Node trying to load all the other dependencies in foo.js?
Obviously one should normally just pull zdfun out, place it in its own module, and import that in foo.js. Sadly this is not feasible in this case for various reasons.
if zdfun is declared in its own file where no other depencies are imported you can do :
import { zdfun } from '<module_name>';
And this will not import useless depencies.
I hope this answer your question
Related
I'm upgrading a React application and have found that I need to modify the import statements to get them to work.
For example, in the old version, the following import works without errors:
import { User } from '../System'
Note that System is a directory on my file system that contains User, a js file that ends with export default User.
In my upgraded version of the app, the System directory still exists, but the above import gives me Can't resolve '../System' in 'C:\my app\.
It turns out that to get the import working properly now, I need to change it to the following:
import User from '../System/User';
If I understand correctly, this relates to js module system changes made with ES6.
My question, though, is regarding the specification of a directory in the import statement (System above). Why would it be that I was previously able to name a file directory in the import statement instead of the actual js script/module itself? Is that approach of using a directory in the import statement still possible? And if so, is it ever advisable?
Update: based on AKX's comment, I noticed the System directory does indeed contain an index.js, which apparently is what makes the import from the directory itself possible.
When an import points to a directory, and only a file, Webpack (which most React setups use) follows Node's's conventions and will attempt to import index.js from that directory if it exists. That's the only condition under which importing from a path that points to a directory works - your previous build probably had /System/index.js (which would allow importing with from '../System'). If you rename the file you're importing to anything else - such as to User.js - importing using only the directory path will fail.
And if so, is it ever advisable?
Sure, if you want. It's a style choice but is commonly done.
(Code below is a simple example, real scenario is bigger)
I have two modules, mod1.js and mod2.js, which are bundled together (using esbuild). They share a common dependency, util.js.
Problem is: when code in mod2.js imports util.js (using same alias), there's a conflict with names.
util.js:
export class Util {
...
}
mod1.js:
import Util from "./util.js";
...
mod2.js:
/* this raises an error of variable already declared */
import Util from "./util.js";
...
If I change alias in mod2.js, error goes away, as expected. But changing aliases every time I import util.js is a bit clumsy, and makes me think there has to be another way.
Is there a better approach to point to a common dependency from multiple modules which are bundled together?
Thanks in advance!
With help from #Bergi's comment, I figured out that I was not using esbuild to bundle my files, but rather using Hugo to concatenate them, and passing this to esbuild.
This leads to mentioned error because there are multiple imports in the same file, which esbuild correctly doesn't recognize as valid. Instead, using esbuild to bundle my files gives me correct results.
I'm still using Hugo, but I have a single entry point which it consumes, that imports all my scripts. From example, I have another file, say master.js:
master.js:
import mod1 from "./mod1.js";
import mod2 from "./mod2.js";
And I then pass this master.js to Hugo, using its js.Build function, which internally uses esbuild. This way I can import util.js using same alias, because these imports are in separate files, using ES6 linking from esbuild.
Suppose I have the following file.
file.js
import Package from 'package';
Package.method();
main.js
When I import file.js into main.js in the following manner...
import './file';
Package.someOtherMethod();
Is it the equivalent to having the below in main.js?
import Package from 'package';
Package.method();
Package.someOtherMethod();
That is, can I think of importing a JS file using import './file'; as just inserting code into main.js?
Is it the equivalent to having the below in main.js?
Not really. Importing from "./file" does mean that any of "./file"'s dependencies are loaded, which (in this case) means "package" is loaded, which means that its top-level code will be run (Package.method()). And that will happen before main.js's top-level code is run (barring cyclical relationships). But it's not as though the source had been lifted out of "./file" and pasted into main.js. In particular, if another file also imports from "./file", its top-level module code is not run a second time.
Lin Clark has a good article about module loading here, including a discussion of the three phases of module loading (Parsing, Instantiation, and Evaluation) and how cyclical relationships are handled.
I've around 20 jsx files with the few repeated imports like :
import React from 'react';
import { Form } from 'formsy-react';
import AppActions from '../../utils/actions/app-actions';
import store, {formStore} from '../../utils/stores/stores';
import AppConstants from '../../utils/constants/app-constants';
which cause my bundle.js weight more than 1.7 Mb even after minification.
Is there any possiblity to import these modules from any where else so that I don't need to import these again and again.
I think there is a misunderstanding here between Webpack, ES6 and a module.
Webpack is going to analyse your javascript code and detect the dependencies, based on that it will include the modules you need in your bundle, there is no duplicate there, every module is added only once in the proper order to resolve the dependencies while avoiding duplicates of code.
ES6 import export syntax convention requires to define the imports you need in every file that requires them, so browsers or tools like Webpack can properly detect dependencies and only use files they need.
1.7 Mb can be considered as a big file for a web page, but with a proper caching/minification it can be loaded instantly
How can I import a static url using webpack:
index.js
import 'http://google.com/myscript.js'
It's really unclear what you're trying to do, but in general you have a few options.
Pre-download the script or install it via NPM. This probably is the preferred way to deal with external dependencies. Once it is local you can easily import or require it like any other module.
If it absolutely must be loaded dynamically you will need a 3rd party module such as https://www.npmjs.com/package/scriptjs which can easily download 3rd party modules at runtime and block the execution of the rest of the script until it has been parsed.
Use a <script> tag and include it on your page. This only works if it's a general dependency that can be loaded before everything else (maybe for a polyfill or a library you depend on everywhere like jquery.)
I hope that helps!
This webpack issue says you can use this comment to allow the import to just work. Though this is only dynamic import not static.
import(/* webpackIgnore: true */ "https://example.com");
First seen here https://stackoverflow.com/a/69951351/4619267
import is es6. With es5 and webpack, use require, or better wrap your JS files with AMD/UMD.