[英]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.