tribe
tribe

Reputation: 321

Do ES6 modules only import what is used?

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)

Upvotes: 2

Views: 1900

Answers (2)

Estus Flask
Estus Flask

Reputation: 222474

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.

Upvotes: 1

Bamieh
Bamieh

Reputation: 10906

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.

Upvotes: 0

Related Questions