Meteor index.js is implied, how? - javascript

I have a pretty basic question and I've read through the Meteor Application Structure but this is still a little confusing:
In meteor chef's understanding the imports directory, it says that:
The index.js file is implied by not specifying a filename on the end. This is also known as an "entry point" file.
When I ran meteor create testproject --full to create a new project, in /client/main.js it writes import '/imports/startup/client';
Why doesn't main.js include the index.js file directly?
Why does import '/imports/startup/client' automatically include the index.js file only?
In Meteor's official documentation, index.js is not a reserved word.
HTML template files are always loaded before everything else
Files beginning with main. are loaded last
Files inside any lib/ directory are loaded next
Files with deeper paths are loaded next
Files are then loaded in alphabetical order of the entire path
Quoted from another question.

As Styx's comment points to, importing the index.js file is a characteristic of the CommonJS module system, which Node uses a version of and Meteor uses under the hood on the client.
The scaffold elects to not specify the index.js file for brevity.
It's also worth noting that the load order you've quoted does not apply when using the imports directory and ES6 imports. Files will be loaded in the order that they are referenced by the code.

Related

Importing js modules by directory name

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.

Importing old library which imports its modules

In our company we have a library, that is divided into modules. These modules are in separate files and each of this modules have it's dependencies on other modules. Each module has a definition function, which registers it for other modules to use it later and also it can require other modules in its definition function. The require is similar to angular:
modules.require(['authentication', 'data', 'http'], module => console.log('Here is my module: ', module).
The library has a Synchronizer class, which based on this require in each module, handles importing and providing of the required modules. When a module has not yet been required, it creates a <script> tag, set it's src to the required module file and appends it to the body.
Here is the problem, because if I just import the main file of my library and try to require some module, it appends a <script> tag but the path to the file is not correct, because it is all bundled together by webpack.
Is there a way in webpack, to state, that this folder (folder with the plugin) should remain as is, so that I can then make requests to the individual files in this folder?
I have tried using "import" statement, "require" and also I tried to change the library into npm package, but I am not really allowed to change the library, because it has been tested in this format. So keeping the library as is, would be the best.
For example if I put this library into:
./static/js/mylibrary
then our library can produce for modules.require(['data'], onSuccess) a <script> tag with src like:
./static/js/mylibrary/data.js
Can I setup webpack so that the file stays there? In development? In production?
I am using a project created by vue-cli
As I mentioned in the comment simply putting it to the "public" directory in webpack did the trick for both, development and production. Don't know why I didn't try this before.

How can I configure Webpack 4 to automatically import split chunks when a bundle is requested via script tag?

I have been pulling my hair out for 3 weeks trying to get this to work, and I can't figure out where the gap in my understanding is.
I am building a library of components for an authorable CMS. My vision is to have a set of n thin entrypoints, all of which will have statically imported dependencies that are requested when the entrypoint is run via script tag.
Per my understanding, webpack can chunk shared dependencies together via splitChunks plugin, and those dependencies can be automatically loaded via the bundle-loader plugin.
However, when I call an entrypoint bundle via script tag, the automatic dependency import does not occur - only when I use dynamic import() syntax within my source files does dynamic import occur - but that's because import() itself is dynamic.
How can I configure webpack to pull in statically dependent chunks?
Check out Paragons (see section: Code Splitting). Then take a look at CodeSplitPage which is wrapped in a Loadable using a dynamic import.
The HtmlWebpackPlugin is what you're looking for. You can configure it to generate entry.html output files in your dist folder, which you can then use in an Express application, or import into your non-Node server rendering to get the full list of <script> tag.

How can I use Gulp and Browserify for my javascript app?

I am finally trying to bring a modern build system to my app, and I'm hoping someone can help. I think I need a few paradigm shifts.
So this is how my app is structured:
/src
/components
/Base
/App.jsx
/Pages.jsx
/...
/Page1
/Page1Component1.jsx
/Page1Component2.jsx
/...
/Page2
/Page2Component1.jsx
/Page2Component2.jsx
/...
/...
/libs
/bootstrap.js
/jquery.js
/react.js
/...
/scripts
/index.js
/utils.js
/styles
/main.css
/html
/index.html
Right now I have gulp set up to do this:
Make a new folder /dest to put everything
Combine everything in /scripts, name it main.js, put it in dest
Combine everything in /libs, name it libs.js, put it in dest
Combine everything in /components, run it through babel, name it comps.js, put it in dest
Copy the one /html file and one /styles file into dest
Then here is how the app runs:
Open index.html
That page requests main.js
main.js requests libs.js and comps.js
Everything works
But here is the issue I'm running into: A lot of stuff here relies on other stuff being global. index.js waits for comps.js and libs.js to load, then calls ReactDOM.render(<App />...), which means both ReactDOM and App need to be global.
Now I'm trying to add something that needs require(), and I try to use Browserify for it. But Browserify takes the code that needs the require and wraps it up in a way that, I believe, makes nothing global.
I realize that I need to turn my app into actual modules, instead of just a bunch of files that concatenate and call each other. And I know that avoiding global variables will be a good thing in the long run. But I'm having a really hard time figuring out how.
For example, I have >50 React modules. It seems wrong to add module.exports to every single one of those, and then import them all to the main file. Further, some of the things in /lib are libraries that don't export as modules, they're made to be run in the <head> tag, like Google Charts.
So I guess my questions are:
Where should my module exports be, and how do they fit into my gulp tasks? Do I concatenate then export?
How do I deal with libraries that aren't modules?
Is my app really poorly laid out, and I just need to restructure from scratch?
Thanks, and sorry about the rambley question.
First, there's nothing wrong with your file structure.
Second, the best thing you can do is follow the "one module, one file" rule. That does mean adding module.exports or export default to every single file. That's just good JavaScript. But it doesn't mean importing them all into your main file, which brings us to:
Third, think in modularity. Files should require or import precisely what they need and nothing they don't. For example, if your App uses Page1 and Page1 uses Page1Component1, then that's how your imports should work:
App -> Page1 -> Page1Component1
-> Page1Component2
-> Page2 -> Page2Component1
-> ...
This ensure separation of concerns and protects your code from easy-to-trigger errors later on (like those from nested dependency changes). And your build system should generate one file (but you can tackle performance later if needed with chunking and so forth).
And you're correct that in this kind of structure, using Browserify or Webpack will ensure that nothing is global - and that's a good thing (though I will note that you can tell them explicitly to expose components, which is sometimes necessary for libraries).
And that leaves libraries that you don't control that you can't import. This does not apply to Bootstrap, jQuery, or React, which all have require-able modules from NPM. But assuming that you have a library you didn't mention that is not available through NPM, you can still include it globally in your HTML with a script tag and tell Browserify or Webpack to expose it for requiring.

Requring all the files in a directory nodejs

The topic may seem to be duplicate. Read it completely
I know there are multiple packages available in nodejs to require all the files in a directory.
But I am in a research to require all the files in a folder and use the variables and functions which are exported in each js file. Need to perform this just by requiring the directory name.
For example,
var files = require("./folder");
The folder may contain some files like
File1.js, File2.js, File3.js
I want to use all the variables and functions which are exported in all the js files.
I think there might be some way in the "Package.json" file.
But I am not expert in "Package.json".
Can anyone help me to figure out the senario?
Could you just make an index.js file with the modules and just require that.
From the docs http://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to require() as an argument.
The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:
{ "name" : "some-library",
"main" : "./lib/some-library.js" }
If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.
This is the extent of Node's awareness of package.json files.
If there is no package.json file present in the directory, then node will attempt to load an index.js or index.node file out of that directory. For example, if there was no package.json file in the above example, then require('./some-library') would attempt to load:
./some-library/index.js
./some-library/index.node

Categories