当前位置: 首页>编程语言>正文

pod库引用swift库报module not found错误 import库报错

说来惭愧,es6写了这么久,连最基本的export和import都没搞明白,直到最近写了一段神代码:

var name = ''; 
  
... 
  
export { 
  
 myName: name 
  
}

编译竟然报错了,(黑人问号脸??),这不就是个正常的对象吗?莫非是编译器认为我的“{}”是代码块的语句?那我就尝试在外面包了一个"()",就变成了这样:

export ({ 
  
 myName: name 
  
});

果然,还是报错。

赶紧回头去翻了一下阮老师的入门书,似乎确实export出来的{}并不是个对象,但是好像说的也不是十分清楚,真正的技术流还是要有点刨根问底的精神,还是要回归es6规范。因此在这里也跟大家分享一下。

https://tc39.github.io/ecma262/#sec-ecmascript-language-scripts-and-modulestc39.github.io

由于篇幅问题我们这里重点从export的角度侃侃,import基本是对应的就暂时略过。

es6的规范都是总分式的结构,我们先来看看总的。



ExportDeclaration:
  export * FromClause;
  export ExportClause FromClause;
  export ExportClause; 
  export VariableStatement[~Yield, ~Await]
  export Declaration[~Yield, ~Await]
  export default HoistableDeclaration[~Yield, ~Await, +Default]
  export default ClassDeclaration[~Yield, ~Await, +Default]
  export default[lookahead ∉ { function, async [no LineTerminator here] function, class }]AssignmentExpression[+In, ~Yield, ~Await];
ExportClause:
    {}
    {ExportsList}
    {ExportsList,}
ExportsList:
    ExportSpecifier
    ExportsList,ExportSpecifier
ExportSpecifier:
    IdentifierName
    IdentifierNameasIdentifierName



其实上面的总概,也是同样以总分的方式,上半部分是总的,下半部分是对上半部分一些关键词的解释。接下来我们来详细看看其中每一个的差别。在这之前,我们先来理清3个概念,分别是boundNames,exportedBinds以及exportedNames。

Module's ExportedNames.
NOTE ExportedNames are the externally visible names that a Module

简单地说,ExportedBindings就是当前模块的内部引用,ExportedNames就是导出外部使用的变量,两者一内一外,还有一个boundName,也就是bound name了,呃,这个词就还是大家各自理解吧,想不出一个合适的词来翻译了。那么我们这里既然看的是export的规范,那么我们这里重点必然是围绕ExportedNames,我们一条一条来看。

首先,我们来给这些导出语句分个类,方便理解。

第一类,导出列表类,导出的是一个簇,而不是单独一个class、function或者一个变量,分为以下几种:

  1. 导入模块的命名空间导出

export * from './testImportModule';

2. 从导入模块导出其中部分importedName

;

3. 导出一个列表

export { test1, test2 ,...}

第二类,导出var变量申明语句

export var test = 1, test1 = 2, test3 = function() {}

这里需要注意,如下的写法是不对的,



var testVar = 1000;
export testVar;



看着似乎跟第二类没什么区别,但是这种用法不存在,究其原因就在于,规范中不包含这种方式,规范是严格的存在,所以不仔细研究规范的细节,就会十分不解,上面两种方式怎么会不一样呢?包括阮老师的es6入门,对于这一原因的解释也是含糊不清,




pod库引用swift库报module not found错误 import库报错,pod库引用swift库报module not found错误 import库报错_github,第1张


截图来自阮老师的《ECMAScript 6 入门》

这简直是太令人费解了,何为“没有提供对外的接口”??我猜测阮老师想说的是ExportedBinding了,但是最恰当的解释应该还是规范为定义而已,不支持这种导出方式,多费口舌的解释,反而更加有碍于正常理解。(所以说技术文档翻译是真的难做,有时候你看着英文就是那个意思,一翻译出来就变味了,真要走强强路线,建议大家还是多翻翻一手的原味文档)。

第三类,诸如函数,类的声明等等,如下部分栗子:

export class hah{}
export function myFun(){}
export async () => {}
export let mm = 123;export const hh = 666;

当然了,以上所有声明类型都可以改写成第二类的var变量定义语句。

第四类,export default xxx:

export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression

平时我们最常用的可能就是default了,不过也不会太去关注default后面内容的一些具体区别,我们最常用的可能就是这么几种:


// 1.class
export default class MyComp{}
// 2.function
export default function myFun(){}
// 3.object
export default {

}


class自不必说了,就是ClassDeclaration,那么HoistableDeclaration,我很想说大家可以自己去翻文档,不过我在这里也贴出来了,


HoistableDeclaration[Yield, Await, Default]:
  FunctionDeclaration[?Yield, ?Await, ?Default]
  GeneratorDeclaration[?Yield, ?Await, ?Default]
  AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
  AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]


是不是一目了然,就是函数相关的包括async,generator函数的那一堆声明了。

剩下还有个AssignmentExpression, 那么这个又是什么呢?顾名思义,就是一些条件表达式,赋值表达式,箭头函数的定义等等的东西了,如果要深入理解细节,建议还是去翻翻文档。这里就不再贴规范的定义了,大家有兴趣去看看,就是那几味材料。

至于这里的export default具体的规则是怎么样的,因为exportedName引用的还是ExportedBindings,我们回过头看看ExportedBindings它在规范中的定义:

ExportDeclaration.

所以,还是回到了BoundNames的定义了,BoundNames对于default规范的定义就比较详细了,其中AssignmentExpression与前两个还不太一样,总结一下就是如果是AssignmentExpression,返回的就是default前两种是如果当前导出变量没有default属性,那么就新增该属性,然后对该default属性进行赋值返回。这里的区别很显然,前两者default是作为变量属性返回,后者是直接返回。因此export default AssignmentExpression在这里是最特别的,除了它直接返回了default,其他方式返回的都是boundName,只是是否使用了default的属性。这种特殊性有些时候对我们也是有用的,作为非引用类型可以有机会脱离模块的控制,下面我们还是通过举栗来说明。


// exportTest.js
export function myFun(){}
export var test = 100;
var count = 100;
export default count++;
myFun = test = count = 1;

// exportClass.js
export default class myClass{}
myClass = 1;

//importTest.js
import ET, { myFun, test } from './exportTest';
import EC from './exportClass';
console.log(ET.myFun, ET.test, ET, EC);

//output
1 1 100 1


这里我们看到除了export default count++,其他的导出变量在模块中的更新,都会影响到外部引用的值,因此可以认为export default AssignmentExpression导出的是数值而非引用。但是如果说这是绝对的,那也不是,这就涉及到我们import的规范了,我们可以使用如下namespaceImport的方式,将导出的AssignmentExpression变成引用类型,因为这时候default也是作为对象属性存在。


import * as ET from './exportTest';


其实仔细想想,export default AssignmentExpression规范传递的是值而非引用也是很巧妙的,可以让我们的导出类型在引用和值传递之间有个选择。

export规范定义的基本上就是以上这四个大类。好像说了很多,又好像似乎什么都没讲到。(手动苦笑一个)再感慨一下,从英文到中文,真是明白了何为只可意会不可言传了,就好像一味灿烂的鲜花,经历了蒸煮晒干入药之后,即使最后泡开了,也是很难领略到原花的灿烂了。如果真正需要弄清楚细节,还是需要大家回头看看原汁原味的英文文档。

尤其其中用词可能会有谬误,如有不妥,烦请拍砖。感谢大家!


https://www.xamrdz.com/lan/5s41963191.html

相关文章: