繁体   English   中英

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

[英]WebPack: how do I access dependencies required in a separate class / file

我的团队正在切换到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,因此我可以随意对其进行脱水/脱水,因此我无法直接在columns数组中传递渲染器引用。

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

谢谢!

更新因此,基于以下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);
});

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM