ES6模块只导入使用的内容吗?

时间:2017-08-25 09:42:42

标签: javascript node.js ecmascript-6

从索引文件导入或导入单个模块之间是否存在性能或行为差异?

例如,索引文件(@/modules/user)为...

import routes from './routes'
import controller from './controller'

const user = {
  routes,
  controller
}

export default user

如果我只导入该文件中的路线......

import user from '@/modules/user'

const routes = Router()

routes.use('/user', user.routes)

这与从他们自己的文件(@/modules/user/routes)单独导入路由有什么不同?控制器是否在用户对象中导入?

import userRoutes from '@/modules/user/routes'

const routes = Router()

routes.use('/user', userRoutes)

2 个答案:

答案 0 :(得分:1)

Node.js目前没有本机ES模块。实际差异取决于工具链。当使用Webpack / Rollup构建应用程序(也可能需要缩小器)并将其配置为在内部使用ES模块时,可以应用树形抖动。这是最好的情况。

如果有再出口模块,这将是树木震动的情况:

DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
    OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')

导入如

import routes from './routes'
import controller from './controller'

export {
  routes,
  controller
}

但是,原帖中的案例不同。在一种情况下,导入import { routes } from '@/modules/user' 常量后,无法通过树抖动从中移除未使用的user属性。在另一种情况下,controllers模块仍然未使用,并且不需要树抖动。即使应用程序配置为使用CommonJS模块,它也将被忽略。

所以,是的,ES模块只能导入正在使用的模块,这在很大程度上取决于实际的代码和项目配置。

客户端应用程序主要受益于树木抖动,因为它会影响捆绑包大小。在服务器端Node.js应用程序中不应考虑这种担忧 - 除非未使用的模块导入大量未在其他地方使用的第三方模块。

答案 1 :(得分:0)

目前,您只能使用转发器(从一种语法到另一种语言的转换器)使用import语法,因为它尚未被引擎本机支持。让我们以巴贝尔为例。

Babel将import转换为可在Node.js中运行的CommonJS样式代码。虽然语法符合ES6,但实现并非如此。

  

Babel将语法转换为CommonJS,在确定导入的内容之前评估导入的代码。使用ES6,在评估代码之前确定导入和导出。

随着对节点内es6导入的未来支持,在代码中导入特定函数将仅返回该导出函数,而不评估目标文件中的整个脚本。

目前它们的工作原理相同,因为转换器将它们转换为传统的节点require语法。

但是,您可以使用webpack Treeshaking从输出文件中删除未使用的代码,这样他们几乎的行为相同。

@语法

@语法取决于模块加载程序模块bundler 。模块加载器不是ECMAScript规范的一部分。您的webpack / babel配置中很可能有babel-plugin-root-import之类的内容。

基本上它意味着来自项目根目录的 ..它避免了编写import Component from '../../../../components/component'之类的东西。在这种情况下,它与部分导入无关。