javascript - WebPack:如何访问单独的类/文件中所需的依赖项

标签 javascript dependency-injection webpack

我的团队正在切换到 webpack,我遇到了需要帮助的问题。

我不知道为什么,但 webpack 似乎没有公开每个文件外部的依赖关系。不幸的是,这打破了我们用于抽象表渲染逻辑的模式。

foo.renderers.DefaultCellRenderer

class DefaultCellRenderer
  renderCell: (data) ->
    ... render logic goes here ...

foo.renderers.ComplexCellRenderer

class ComplexCellRenderer
  renderCell: (data) ->
    ... render logic goes here ...

foo.mixins.SimpleTableMixin

require foo.mixins.BaseTableMixin

class SimpleTableMixin
  constructor: (@data) ->
    foo.mixins.BaseTableMixin.apply @
    @columns = [
      { label: 'Col 1' }
      { label: 'Col 2' }
    ]

foo.mixins.ComplexTableMixin

require foo.mixins.BaseTableMixin
require foo.renderers.ComplexCellRenderer

class ComplexTableMixin
  constructor: (@data) ->
    foo.mixins.BaseTableMixin.apply @
    @columns = [
      { label: 'Col 1' }
      { label: 'Col 2', renderer: 'ComplexCellRenderer' }
    ]

foo.mixins.BaseTableMixin

require foo.renderers.DefaultCellRenderer

class BaseTableMixin
  render: (container) =>
    # render table header...

    # render table body...
    for row in @data
      for metadata, cellIndex in @columns
        name = metadata.renderer or 'DefaultCellRenderer'
        target = foo.renderers[name]
        container.append target.renderCell row[cellIndex]

这是一个极其简化的示例,但本质上,这种方法允许我们构建非常复杂的表,其行为层可在运行时动态配置。

在实现 webpack 之前,这种方法是有效的,因为“foo.renderers”是全局的,任何需要自定义渲染的类都负责声明该依赖关系,保证其在被基本 .render() 函数调用时存在......

但是,自从迁移到 webpack 后,除非我在基表混合中明确要求,否则这些渲染器不再可用。这打破了这种方法的根本好处,即使我们的表可扩展而无需修改底层逻辑。

此外,我无法直接在列数组中传递渲染器引用,因为应用程序状态需要可序列化为 JSON,以便可以随意脱水/再水化。

考虑到所有这些,谁能告诉我是否有一种方法可以确保这些依赖项在基表混合中可用,而不必在该文件中显式声明它们(从而打破打开/关闭原则) ?

谢谢!

更新 因此,根据下面 dtothefp 的答案,我最终创建了一个包装类,它动态地需要同一目录或子目录中的所有渲染器...所以我只需要需要一个引用而不是单个引用(尽管,它们可以单独需要)同样,以避免循环引用)

/foo/common/renderers/Renderers.coffee

goog.provide 'foo.common.renderers'

context = require.context './', true, /^.+\.js$/
context.keys().forEach (key) ->
  renderers = context(key)?.foo?.common?.renderers
  _.extend foo.common.renderers, renderers if renderers?
  return

最佳答案

尝试使用 expose-loader https://github.com/webpack-contrib/expose-loader

module: {
  rules: [{
    test: path.join(yourSrcRoot, 'foo', 'renderers', 'DefaultCellRenderer'),
    use: [{
      loader: 'expose-loader',
      options: 'foo.renderers.DefaultCellRenderer'  // not sure if this works???
    }]
  }]
}

似乎尝试从您之前拥有的任何内容转移到在命名空间上使用全局变量的 Webpack 是一种反模式,但这可能会让您开始。

或者更好的是,为什么不在包的开头引导整个事情呢?

// index.js

const foos = require.context('./foo', true, /(renderers|mixins)\/.+\.js$/);

global.foo = {};
global.foo.mixins = {};
global.foo.renderers = {};

foos.keys().forEach((fp) => {
  const [dir] = fp.split('/');

  global.foo[dir] = foos(fp);
});

不确定您所说的“这破坏了这种方法的根本好处,即使我们的表可扩展而无需修改底层逻辑”是什么意思。如果您想使用模块加载器但不想导入依赖项,那么您似乎错过了重点。

关于javascript - WebPack:如何访问单独的类/文件中所需的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43666686/

相关文章:

javascript - 未捕获的类型错误 : Object has no method 'splice'

javascript - 获取 promise 数组的大小( Protractor )

c# - RegisterWithContext 与生活方式不匹配

node.js - 如何修复 webpack 错误 : Cannot find module - on node. js (webpackEmptyContext)

javascript - 单击时如何从 Controller 获取数据到指令

javascript - 无法读取 $promise 的属性然后未定义?

javascript - Angular 调用随机服务!为什么?

dependency-injection - 在Windsor中注册组件不指定接口(interface)可以吗?

webpack - _webpack_require 返回一个空模块对象

javascript - Kik 卡 - 我可以导入/需要 Kik.js 文件吗?