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

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

例如,使用索引文件( @/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 )单独导入@/modules/user/routes ? 控制器是否被导入,因为它在用户对象中?

 import userRoutes from '@/modules/user/routes' const routes = Router() routes.use('/user', userRoutes) 

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

如果有重新导出模块,这将是一个树木摇晃的情况:

 import routes from './routes' import controller from './controller' export { routes, controller } 

它像import一样

 import { routes } from '@/modules/user' 

但是原帖中的情况是不一样的。 在一种情况下,一旦导入了user常量,就不可能从树中删除未使用的controllers属性。 在另一种情况下, @/modules/user/controller模块保持不被使用,不需要树状结构。 即使应用程序configuration为使用CommonJS模块,它也将被忽略。

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

客户端应用程序主要受益于树状结构,因为它会影响包的大小。 在服务器端的Node.js应用程序中不应该考虑这个问题 – 除非未使用的模块导入大量没有在其他地方使用的第三方模块。

目前,您只能使用转换程序的import语法(从一种语法到另一种语法的转换程序),因为它尚未由引擎本机支持。 让我们以babel为例。

Babel将import转换为可在Node.js中工作的CommonJS样式代码。 虽然语法符合ES6,但实现不是。

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

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

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

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

@语法

@语法依赖于模块加载器模块捆绑器 。 模块加载器不是ECMAScript规范的一部分。 你最有可能在你的webpack / babelconfiguration中有像babel-plugin-root-import这样的东西。

基本上,这意味着从项目的根源 。它避免了必须import Component from '../../../../components/component'写入import Component from '../../../../components/component'东西。 在这种情况下,它与部分import无关。