鉴于ES2015,依赖注入和库抽象,2016年我的理想模块应该是什么样子?

Dan*_*Dan 38 javascript dependency-injection module ecmascript-6

如果没有,首先,我会全力以赴编写我的所有模块

import A from './a.js';

var B = function(){
  //use A
};

export default B;
Run Code Online (Sandbox Code Playgroud)

然后使用编译器将其构建为某种浏览器或服务器格式.

然而,我的一个问题与上面的明确规范./a.jsimport.

我理解为什么规范这样做1,赞成静态分析.但是有两个非常实际的原因可以解释为什么在模块的文件名路径中烘焙都很麻烦.

  1. 正如此处已经提到的那样,当从项目到项目频繁地回收模块时,您很可能无法在项目树中维护到该资源的一致路径.将一个导入调用粘贴import myModule from './../../vendor/lib/dist/mod.js'到模块的代码中并不能完全让我感到前瞻性.
  2. 除了路径本身,指定文件名也会让你失望.像这样的东西似乎是无辜的:

    import $ from 'vendor/jquery.js'

    但是,当我想使用Zepto而不是jQuery时呢?我发现抽象,尤其是供应商库的抽象,在处理大型代码库,自以为是的开发人员和不断变化的JavaScript生态系统时非常有用.我今天可能想要将React导入我的组件库,但明天呢?如果我要在客户端和服务器上使用相同的模块,但是我需要不同版本的依赖库,该怎么办?

我在团队中坚持强大(但清晰且一致)的抽象.通常,抽象采取某种命名空间的形式.我幻想一下这个:

//BAD: Bakes React into my component modules
import ComponentLib from './React.js';

//GOOD: Leaves me free to use any React-like library
import ComponentLib from 'vendor.lib.component';
Run Code Online (Sandbox Code Playgroud)

其中vendor.lib.component,在Java类似的方式,先前已注册的地方.

请注意,与此问题不同,我的目标不是动态控制我的导入.我不想要运行时灵活性,我喜欢构建时灵活性.我应该能够为另一个,或者模拟,或者在某个特定环境中工作的东西提出一个依赖框架,而不必担心我的模块正在调用哪些依赖项,或者尝试复制一些疯狂的目录我追求的每一个构建产品的树.

类似的问题导致了一个利用系统规范的库的建议,比如SystemJS.然后,您可以使用类似jspm的内容来引入模块映射以获取抽象.但是,在我这样做的那一刻,我正以不同的方式编写所有模块:

System.import('a', function(A){
  //use 'A'
});
Run Code Online (Sandbox Code Playgroud)

这突然是未来吗?如果是这样,为什么我不继续使用AMD?如果我要回到使用异步外观的加载器API,为什么还要烦扰ES2015模块和运行转换器呢?

令人瞩目的是,我没有看到在ES2017规范中解决模块加载器API标准的问题.

(编辑:修订问题以符合非意见答案的标准)

考虑到上述所有情况,我问社区 - 如何编写一个JavaScript模块,(i)遵守ES2015标准,(ii)不通过文件名或路径引用依赖模块,以及(iii)不依赖于广泛的中间工具/配置,这将使得与多个团队共享模块的程度令人望而却步.

-

注1正如评论中提到的@zeroflagL,规范没有明确规定模块应该被指定为路径,只是一个字符串(参见ModuleSpecifier - http://www.ecma-international.org/ecma-262/ 6.0 /#table-41).然而,还有一个明确的指示来解释循环引用,暗示某种静态分析(http://www.ecma-international.org/ecma-262/6.0/#sec-imports),文件路径似乎正在此时选择的参考上下文.因此,我们不能责怪这里的僵化,反之亦然.然后,我们可能有责任开发更强大的import/ ModuleSpecifier实现,从而实现二级标准.

Paw*_*wel -1

如果您想遵循最佳实践,请遵循 AirBnb JavaScript 样式指南。在我看来,这是最好、最完整的 JavaScript 样式指南

https://github.com/airbnb/javascript#classes--构造函数

进口

这对于重用模块来说看起来很糟糕:import myModule from './../../vendor/lib/dist/mod.js'

在 NPM(也可以是私有或自托管 NPM)上发布您的模块并像这样导入import myModule from 'my-module';

最终将 NODE_PATH 设置为根文件夹,并从根相对引用模块。

在 package.json 中

'start': 'NODE_PATH=. node index.js'

// in Windows
'start': 'NODE_PATH=. && node index.js'
Run Code Online (Sandbox Code Playgroud)

现在像这样导入:

import myModule from 'vendor/lib/dist/mod.js'
Run Code Online (Sandbox Code Playgroud)

变量

var不是 ES6 的一部分。使用:

  • constant- 当变量的值不会改变时,对象和导入也不会改变。即使对象的参数发生变化,它仍然是一个常量。

  • let- 当变量的值改变时,即for(let = i; i < 100; i++)

  • 根据我自己的经验,始终设置为默认值,并且只有在抱怨时才const更改(顺便说一句。使用 ESLint http://eslint.org/letESLint

课程

现在有一种在 JavaScript 中定义类的正确方法

class B {
  constructor() {
  }
  doSomething() {
  }
}
Run Code Online (Sandbox Code Playgroud)

您的示例已更新:

import A from './a';

Class B {
  constructor() {
  }
  doSomething() {
  }
};

export default B;
Run Code Online (Sandbox Code Playgroud)

如果你想扩展A:

import A from './a';

Class B extends A{
  constructor(argumentA, argumentB) {
    super(argumentA, argumentB);
    this.paramA = argumentA;
  }
};

export default B;
Run Code Online (Sandbox Code Playgroud)

尖端

  • 使用 Webpack 和 NPM 作为构建工具。不要使用 Gulp 或 Grunt
  • 使用 Babel 来转译你的代码(JSX loader 可能还不够)
  • 学会完全不使用 jQuery,而是从 NPM 中为您需要完成的工作选择正确的 Polyfill 和工具
  • github 上有大量编写良好的样板代码库,因此请从最好的代码中借鉴。这是我正在使用的一些 React 。

我的回答本质上是:

您要求的模式/库是 AirBnb JavaScript 样式指南,忘记 jQuery

  • 嗯,克罗克福德只是一个观点,而不是权威:-)无论如何,我认为只有你帖子的“导入”部分回答了OP的问题。你应该放弃其余的。 (3认同)
  • “*var 不是 ES6* 的一部分”-什么? (2认同)
  • 你不应该按字面意思理解克罗克福德所说的一切:-) (2认同)