Is there any good solution for this example?
Seems like if I have a lot of modules like photo.module.ts I need to import DatabaseModule in every feature module.
Tried to put it in app.module.ts but it doesn't help. Maybe there are some solutions with forRoot static import?
As it says in the docs:
In this article, you'll learn how to create a DatabaseModule based on
the TypeORM package from scratch using custom providers mechanism. As
a consequence, this solution contains a lot of overhead that you can
omit using ready to use and available out-of-the-box dedicated
#nestjs/typeorm package.
So better use the #nestjs/typeorm package, see docs.
When you use the #nestjs/typeorm package, you have to import TypeOrmModule.forFeature([PhotoEntity]) for each feature module. In each feature module, you only want to register the entities that belong to that feature. This improves the encapsulation.
You tried to register a module in the AppModule and wondered why its providers weren't available in the feature modules. Note that a module always has to import a module itself so that it can access its exported providers. The only exception to this are global modules. When you annotate a module with the decorator #Global() then it will automatically be imported in all modules as long as it is imported at least once (e.g. in your AppModule).
Related
why not simply use folders instead of modules if the only purpose is to make the structure more organized?
It is weird because it does not seem necessary since every file is a separate module in node js and if i need anything i have to import it using the import statement anyways so what is the point of specifying the imports and exports in a module? does it affect the dependency injection if i just import what i need without using modules(#Module decorator) or something similar?
NestJs has opted to design their framework with dependency injection as one of its core principals. Ie, you write your code just using the name/type of the services you want to use, and then a different piece of code is responsible for finding that service, knowing how to construct it, and then passing it in to you.
Native import/export doesn't have a system for dependency injection, so the main thing that the #Module decorator does is organize the metadata needed for the injector system.
I’m trying to import whole modules in a javascript file.
This file pertains to the Home Assistant environment where the frontend is written in javascript, usually using LitElements and modules (cf. documentation).
For instance, the doc uses a fancy wired-card by writing:
import "https://unpkg.com/wired-card#0.8.1/wired-card.js?module";.
I've read a lot about the import call but resources are usually about local elements and it seems that I need them to be distant.
In fact, I know the plain old JS quite well but I am a bit clueless regarding importing modules (and LitElements for that matter).
For instance, I'm looking for an accordion (expansion panel), like the one of JQueryUI. I found several resources (e.g. here, here, or here) but I couldn't find how to import them easily.
What makes a module importable? Are those not or am I doing it wrong?
In standard ECMAscript, a JS file is importable if it defines a module in the new system. Kinda circular.
Basically, it should export some resources from the module file. For example, if I have a test-module.js, I can export some class using the export keyword:
class Fubar {}
export { Fubar }
// or, more concisely
export class Fubar {}
The export keyword tells the module system that the resource defined should be made available to importers.
On the flip side, if you want to import a module, you must also do so from a module! This is because module imports are async and processed before the execution (excluding the dynamic import() function).
So, if I want to import my Fubar class from another module, I can do this:
import { Fubar } from './test-module.js`
However, if I load this script as a non-module, I will get an error. Instead, I must tell the browser that the script is a module:
<script type="module" src="test-module.js"></script>
So, in short, something is "importable" if it is itself a module.
More reading:
Mozilla Dev Network article on the modules system: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
MDN article on the import keyword: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
EDIT: something I missed - to make web resources a little nicer, the import URLs can be any URL, not just a relative path. This allows importing 3rd party scripts as modules. But, those 3rd party scripts need to be modules themselves.
I understand that import and require both can work if I want to use a class/module from another file. But I don't really know why
if I use require ('./config.json') will work,
but use import config from './config.json' would not work.
Does this because import only accept class/module, can't work with JSON?
I also know import is working when compile, but require is working on run time.
But really confused.
These are two totally different module systems and thus don't work the same way.
import is part of what referred to as "ES modules" i.e the native javascript implementation of modules brought by ES6.
require, on the other hand, is the import keyword of the commonjs module system. It is still used widely today, because Node.js uses it (there was no native module system in the JavaScript spec at the time of its creation).
Have a look at both the import/export docs on the MDN and the require docs on the node.js website.
Is there is a performance or behavioural difference between importing from an index file or importing individual modules?
For example, with an index file (#/modules/user) of...
import routes from './routes'
import controller from './controller'
const user = {
routes,
controller
}
export default user
If I import just the routes from that file...
import user from '#/modules/user'
const routes = Router()
routes.use('/user', user.routes)
Is this any different to just importing the routes individually from their own file (#/modules/user/routes)? Does the controller get imported as it's in the user object?
import userRoutes from '#/modules/user/routes'
const routes = Router()
routes.use('/user', userRoutes)
There are currently no native ES modules in Node.js. The actual difference depends on the toolchain. When the application is built with Webpack/Rollup (a minifier is potentially needed too) and configured to use ES modules internally, tree-shaking can be applied. This is best case scenario.
This would be a case for tree-shaking if there were a reexporting module:
import routes from './routes'
import controller from './controller'
export {
routes,
controller
}
And it was imported like
import { routes } from '#/modules/user'
However, the cases in the original post are different. In one case, once user constant is imported, it's impossible to remove unused controllers property from it with tree-shaking. In another case, #/modules/user/controller module remains unused and doesn't need tree-shaking. It will be ignored even if the application is configured to use CommonJS modules.
So yes, it's possible for ES modules to import only modules that are in use, and this heavily depends on actual code and project configuration.
Client-side applications primarily benefit from tree-shaking because it affects bundle size. This concern shouldn't be taken into account in server-side Node.js application - unless unused module imports massive amount of third-party modules that aren't used anywhere else.
Currently you can only use the import syntax using transpilers(converters from one syntax to another) as it is not yet natively supported by engines. Lets take babel for example.
Babel converts the import to CommonJS style code that can work within Node.js. While the syntax is conformant to ES6, the implementation is not.
Babel converts the syntax into CommonJS, evaluating the imported code before determining what is being imported. With ES6, the imports and exports are determined before the code is evaluated.
With future support of es6 imports inside node, importing a specific function inside the code will only return that exported function, without evaluating the whole script in the targeted file.
Currently they work the same since transpilers convert them to traditional node require syntax.
However, you can use webpack Treeshaking to remove unused code from the output file, this way they are almost identical in behavior.
The # syntax
The # syntax depends on the module loader or module bundler. The module loader is not part of the ECMAScript spec. You most likely have something like babel-plugin-root-import in your webpack/babel config.
Basically it means from the root of the project.. it avoids having to write things like import Component from '../../../../components/component'. in this case, it has nothing to do with partial imports.
What benefits to use componentjs (https://github.com/component/component) instead of requirejs?
Both project has the same idea, hard to make choice between them.
RequireJS is just a JavaScript file and module loader.
Component is a whole system which allows you to package HTML+JS+CSS+Images+Fonts in a one module, component. Component also provides package registry(vs npm), dependency handling(vs requirejs), build and task system(vs grunt/gulp).
There's good document where component is compared to other build/package handling tools:
https://github.com/component/guide/blob/master/component/vs.md
This blog post helped me to understand component: http://blog.benmcmahen.com/post/55280740882/using-component-js