使用导入模块的命名别名不适用于导出名称的点符号?
Using a named alias of an imported module does not work for dot notation of exported names?
在 React 应用程序中,我有一个包含如下导入的文件:
import * as cArrayList from './ClassArrayList'
import * as mCalc1 from './moduleCalc1'
然后在同一个文件中,我有这样的导出:
export const cArrayList.ArrayList
export const mCalc1.doPreCalculationSetup
export const mCalc1.doTheCalculations
但是我得到一个解析错误:标识符 'cArrayList' 已经声明。
MDN 文档在此声明中说:
import * as myModule from '/modules/my-module.js'
模块对象的“myModule”别名可以用作引用导入时的一种命名空间,这样使用:
myModule.doAllTheAmazingThings().
那么为什么我的错误?
此文件中仅有的项目是 61 行导入行和 394 行导出行。这个文件的全部目的是只做一次所有必要的导入,创建一个命名空间来保存项目中所有可用的导出。然后通过引用为所有其他使用它们的模块提供单独的导出,而不是每个模块都进行另一个导入。这是一个避免循环引用(我认为)导致程序在启动阶段循环的实验。
已更新
在完成实现名称空间文件的破解想法的步骤时,我学到了一些让我觉得这整个练习没有必要的东西。我认为循环应用程序实际上是一个带有 gif 的停滞启动画面。甚至认为完成的黑客工作有效,对代码的许多小改动在提出问题之前运行良好。我最近的想法是尝试进行构建,运行 这是关键。该构建失败,但确定了错误代码以进行更正。然后完成了一系列小的代码更改。
所以感谢 GIT,我能够跳回到我第一次看到这个问题的时间点:一个干净的编译但是一个停滞的闪屏。现在我 运行 构建并得到了这个:
Failed to compile.
Failed to minify the code from this file:
./src/calculations/moduleMoneyPlanEntry.js:53:4
那个位置的代码很简单:
function moneyPlanEntry() {
try {
process.env.MONEYPLAN = 'development'
process.env.NODE_ENV = 'development' (A)
以前工作中标记为 (A) 的那一行是问题所在。删除该行,一切都很好。使用“yarn start”命令构建 运行s 和更正后的代码 运行s。所以现在我将放弃我的 nameSpace hack 并正常继续。关键教训? 运行 构建一次以检查潜在错误。
export const <someIdentifier>
会做 两件事:
- 在名为
someIdentifier
的模块范围内声明一个局部变量(作为 const
)
- 将其导出为命名导出
您收到的错误消息有点误导。变量是否事先声明,
export const someObject.someProperty
是无效语法,因为 someObject.someProperty
不是有效标识符。出于类似的原因,你不能这样做
const someObject.someProperty
对于你想要做的事情,我会在导出时解构导入对象的属性,如下所示:
export const {
doPreCalculationSetup,
doTheCalculations
// you can add more properties here
} = mCalc1;
演示:
<script type="module">
const obj = { foo: 'foo' };
export const { foo } = obj;
console.log(foo);
</script>
@CertainPerformance 已经说了语法错误的所有内容。
The whole purpose of this file is to do all the necessary imports just once, creating a namespace holding all the exports available in the project. And then make the individual exports avaiable by reference for all the other modules using them, instead of each module doing another import.
为此,您需要使用 export * from '…';
语法。或 export { name as alias } from '…';
以防发生冲突。
但这听起来像是一个非常糟糕的主意,将所有内容都放在一个全局命名空间中,这与模块化背道而驰。你的包的各个部分之间将不再有明确的依赖关系,而是一团糟。
This is an experiment to avoid a cyclic reference (I think) that causes the program to just loop in the startup phase.
循环依赖通常会导致 TDZ 异常,而不是无限循环。
在你的全局模块中使用 const
声明实际上会使这些变得更糟,你真的需要使用实际上为绑定别名的重新导出。
要解决循环依赖问题(不想重构但保持依赖结构),你通常需要决定哪个模块应该是你的循环的入口点,以及模块应该以什么顺序执行, 然后在任何模块导入列表中始终严格遵循该顺序。
在 React 应用程序中,我有一个包含如下导入的文件:
import * as cArrayList from './ClassArrayList'
import * as mCalc1 from './moduleCalc1'
然后在同一个文件中,我有这样的导出:
export const cArrayList.ArrayList
export const mCalc1.doPreCalculationSetup
export const mCalc1.doTheCalculations
但是我得到一个解析错误:标识符 'cArrayList' 已经声明。
MDN 文档在此声明中说:
import * as myModule from '/modules/my-module.js'
模块对象的“myModule”别名可以用作引用导入时的一种命名空间,这样使用:
myModule.doAllTheAmazingThings().
那么为什么我的错误?
此文件中仅有的项目是 61 行导入行和 394 行导出行。这个文件的全部目的是只做一次所有必要的导入,创建一个命名空间来保存项目中所有可用的导出。然后通过引用为所有其他使用它们的模块提供单独的导出,而不是每个模块都进行另一个导入。这是一个避免循环引用(我认为)导致程序在启动阶段循环的实验。
已更新
在完成实现名称空间文件的破解想法的步骤时,我学到了一些让我觉得这整个练习没有必要的东西。我认为循环应用程序实际上是一个带有 gif 的停滞启动画面。甚至认为完成的黑客工作有效,对代码的许多小改动在提出问题之前运行良好。我最近的想法是尝试进行构建,运行 这是关键。该构建失败,但确定了错误代码以进行更正。然后完成了一系列小的代码更改。
所以感谢 GIT,我能够跳回到我第一次看到这个问题的时间点:一个干净的编译但是一个停滞的闪屏。现在我 运行 构建并得到了这个:
Failed to compile.
Failed to minify the code from this file:
./src/calculations/moduleMoneyPlanEntry.js:53:4
那个位置的代码很简单:
function moneyPlanEntry() {
try {
process.env.MONEYPLAN = 'development'
process.env.NODE_ENV = 'development' (A)
以前工作中标记为 (A) 的那一行是问题所在。删除该行,一切都很好。使用“yarn start”命令构建 运行s 和更正后的代码 运行s。所以现在我将放弃我的 nameSpace hack 并正常继续。关键教训? 运行 构建一次以检查潜在错误。
export const <someIdentifier>
会做 两件事:
- 在名为
someIdentifier
的模块范围内声明一个局部变量(作为const
) - 将其导出为命名导出
您收到的错误消息有点误导。变量是否事先声明,
export const someObject.someProperty
是无效语法,因为 someObject.someProperty
不是有效标识符。出于类似的原因,你不能这样做
const someObject.someProperty
对于你想要做的事情,我会在导出时解构导入对象的属性,如下所示:
export const {
doPreCalculationSetup,
doTheCalculations
// you can add more properties here
} = mCalc1;
演示:
<script type="module">
const obj = { foo: 'foo' };
export const { foo } = obj;
console.log(foo);
</script>
@CertainPerformance 已经说了语法错误的所有内容。
The whole purpose of this file is to do all the necessary imports just once, creating a namespace holding all the exports available in the project. And then make the individual exports avaiable by reference for all the other modules using them, instead of each module doing another import.
为此,您需要使用 export * from '…';
语法。或 export { name as alias } from '…';
以防发生冲突。
但这听起来像是一个非常糟糕的主意,将所有内容都放在一个全局命名空间中,这与模块化背道而驰。你的包的各个部分之间将不再有明确的依赖关系,而是一团糟。
This is an experiment to avoid a cyclic reference (I think) that causes the program to just loop in the startup phase.
循环依赖通常会导致 TDZ 异常,而不是无限循环。
在你的全局模块中使用 const
声明实际上会使这些变得更糟,你真的需要使用实际上为绑定别名的重新导出。
要解决循环依赖问题(不想重构但保持依赖结构),你通常需要决定哪个模块应该是你的循环的入口点,以及模块应该以什么顺序执行, 然后在任何模块导入列表中始终严格遵循该顺序。